一、分水岭算法
分水岭变换是一个流行的图像处理算法,用于快速分割图像为同类区域。它背后的原理是,将图像视为拓扑结构的地图,
那么均质区域对应的是被陡峭边缘包围的平坦盆地。
实现方法:
分水岭分割的结果是通过watershed()函数获取。
我们将图片中已知属于某个区域的像素进行标记,基于这个标记,分水岭算法开始确定其他像素的归属区域。
1 #include<opencv2/opencv.hpp> 2 #include<iostream> 3 4 using namespace std; 5 using namespace cv; 6 7 /* 8 我们将创建灰度格式的标记图,然后将它转化成一张整图 9 把这些步骤封装在WatershedSegmenter类中 10 */ 11 class WatershedSegmenter { 12 private: 13 Mat markers; 14 public: 15 void setMarkers(const Mat &markerImage) { 16 //转换位整数图像 17 markerImage.convertTo(markers, CV_32S); 18 } 19 20 Mat process(const Mat &image) { 21 //使用算法 22 watershed(image, markers); 23 return markers; 24 } 25 }; 26 27 int main() 28 { 29 //载入原图 30 Mat image = imread("C:\Users\Nelsoner\Desktop\Camera Roll\008.jpg"); 31 32 //移除噪点与微小物体 33 Mat fg; 34 erode(image, fg, Mat(), Point(-1, -1), 6); 35 36 37 //识别不包含物体的像素 38 Mat bg; 39 dilate(image, bg, Mat(), Point(-1, -1), 6); 40 threshold(bg, bg, 1, 128, THRESH_BINARY_INV); 41 42 43 44 45 //创建标记图像 46 Mat markers(image.size(), CV_8U, Scalar(0)); 47 markers = fg + bg; 48 49 50 //创建分水岭分割对象 51 WatershedSegmenter segmenter; 52 //设置标记,并进行处理 53 segmenter.setMarkers(markers); 54 55 markers = segmenter.process(image); 56 57 58 namedWindow("hah"); 59 imshow("hah", markers); 60 61 62 waitKey(); 63 64 return 0; 65 }