一、分水嶺算法
分水嶺變換是一個流行的圖像處理算法,用於快速分割圖像為同類區域。它背后的原理是,將圖像視為拓撲結構的地圖,
那么均質區域對應的是被陡峭邊緣包圍的平坦盆地。
實現方法:
分水嶺分割的結果是通過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 }