opencv實現(xiàn)輪廓高斯濾波平滑
更新時間:2020年07月21日 14:35:25 作者:BHY_
這篇文章主要為大家詳細介紹了opencv實現(xiàn)輪廓高斯濾波平滑,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了opencv實現(xiàn)輪廓高斯濾波平滑的具體代碼,供大家參考,具體內(nèi)容如下
一個小測試的題目:
在圖像上點選,找到與點選處相鄰的顏色相近的點集合,對該點集合提取輪廓,對該點集合輪廓平滑處理,顯示處理結(jié)果。
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; //************************************ // Method: findRegion 漫水填充 // FullName: findRegion // Access: public // Returns: vector<Point> // Qualifier: // Parameter: Mat img // Parameter: Point pos // Parameter: int LowDifference // Parameter: int UpDifference //************************************ vector<Point> findRegion(Mat img, Point pos, int LowDifference, int UpDifference) { Mat image = img.clone(); Mat imgBack = img.clone(); Rect ccomp; Scalar pixel = image.at<Vec3b>(pos); Scalar pixel2 = Scalar(255 - pixel[0], 255 - pixel[1], 255 - pixel[2], pixel[3]); floodFill(image, pos, pixel2, &ccomp, Scalar(LowDifference, LowDifference, LowDifference), Scalar(UpDifference, UpDifference, UpDifference)); Mat diff; absdiff(image, imgBack, diff); //統(tǒng)計所有非零像素 vector<Point> pt; for (int i = 0; i < diff.rows; i++) { for (int j = 0; j < diff.cols; j++) { Point newPos(j, i); Scalar pixel3 = diff.at<Vec3b>(newPos); if (pixel3[0] != 0 || pixel3[1] != 0 || pixel3[2] != 0) { pt.push_back(newPos); } } } return pt; } //************************************ // Method: findPerimeter 從點集合中尋找輪廓點 // FullName: findPerimeter // Access: public // Returns: vector<Point> // Qualifier: // Parameter: vector<Point> pt // Parameter: Size size //************************************ vector<Point> findPerimeter(vector<Point> pt, Size size) { Mat imgGray(size, CV_8UC1, Scalar(0)); for (int i = 0; i < pt.size(); i++) { imgGray.at<uchar>(pt[i]) = 255; } std::vector<std::vector<cv::Point>> contours; //獲取輪廓不包括輪廓內(nèi)的輪廓 cv::findContours(imgGray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); return contours[0]; } //************************************ // Method: displayImage 顯示圖像 // FullName: displayImage // Access: public // Returns: void // Qualifier: // Parameter: Mat img // Parameter: vector<Point> contours 輪廓點 // Parameter: Point pos //************************************ void displayImage(Mat img, vector<Point> contours, Point pos) { Mat imgShow = img.clone(); for (int i = 0; i < contours.size(); i++) { imgShow.at<Vec3b>(contours[i])[0] = 0; imgShow.at<Vec3b>(contours[i])[1] = 0; imgShow.at<Vec3b>(contours[i])[2] = 0; } circle(imgShow, pos, 3, Scalar(0, 0, 0), 1, 8, 0);//畫用戶選擇的點 imshow("img", imgShow); waitKey(0); } //************************************ // Method: findSmoothPeimeter 高斯濾波輪廓點平滑 // FullName: findSmoothPeimeter // Access: public // Returns: void // Qualifier: // Parameter: Mat img 原圖 // Parameter: vector<Point> pt 輪廓點集合 //************************************ void findSmoothPeimeter(Mat img, vector<Point> pt) { vector<Point> contours = findPerimeter(pt, img.size()); Mat im; cvtColor(img, im, CV_BGR2GRAY); Mat cont = ~im; Mat original = Mat::zeros(im.rows, im.cols, CV_8UC3); Mat smoothed = img.clone(); // contour smoothing parameters for gaussian filter int filterRadius = 10; int filterSize = 2 * filterRadius + 1; double sigma = 10; size_t len = contours.size() + 2 * filterRadius; size_t idx = (contours.size() - filterRadius); vector<float> x, y; for (size_t i = 0; i < len; i++) { x.push_back(contours[(idx + i) % contours.size()].x); y.push_back(contours[(idx + i) % contours.size()].y); } // filter 1-D signals vector<float> xFilt, yFilt; GaussianBlur(x, xFilt, Size(filterSize, filterSize), sigma, sigma); GaussianBlur(y, yFilt, Size(filterSize, filterSize), sigma, sigma); // build smoothed contour vector<Point> smoothContours; for (size_t i = filterRadius; i < contours.size() + filterRadius; i++) { smoothContours.push_back(Point(xFilt[i], yFilt[i])); } Scalar color; for (int i = 0; i < smoothContours.size(); i++) { smoothed.at<Vec3b>(smoothContours[i])[0] = 0; smoothed.at<Vec3b>(smoothContours[i])[1] = 0; smoothed.at<Vec3b>(smoothContours[i])[2] = 0; } imshow("smoothed", smoothed); waitKey(10); } void main() { Mat img = imread("4.jpg", 1); vector<Point> pt, contours; Point pos(1438, 590);//先列后行 int para1 = 2; int para2 = 2; pt = findRegion(img, pos, para1, para2); findSmoothPeimeter(img, pt); contours = findPerimeter(pt, img.size());//輪廓點集合 displayImage(img, contours, pos);//顯示圖像 }
漫水填充找到的輪廓
輪廓濾波平滑
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言內(nèi)存的動態(tài)分配比較malloc和realloc的區(qū)別
這篇文章主要介紹了C語言內(nèi)存的動態(tài)分配比較malloc和realloc的區(qū)別,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是本文的詳細內(nèi)容,需要的朋友可以參考下2021-07-07數(shù)據(jù)結(jié)構(gòu)與算法 排序(冒泡,選擇,插入)
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法 排序(冒泡,選擇,插入)的相關(guān)資料,這里對冒泡,選擇和插入都做有實例,需要的朋友可以參考下2017-07-07