分水嶺演算法學習(opencv)__演算法

來源:互聯網
上載者:User

分水嶺演算法可以將映像中的邊緣轉化成“山脈”,將均勻地區轉化為“山穀”。首先,計算灰階映像的梯度,然後開始從使用者指定點(或演算法得到的點) 開始持續“灌注”盆地直到這些地區連在一起。基於這樣產生的標記就可以吧地區合并在一起,合并後的地區又通過聚集的方式進行分割,好像映像被“填充”起來一樣。通過這種方式,與指示點相連的盆地就為指示點“所擁有”。最終我們把映像分割成相應的標記地區。

例1:

 #include"cv.h"#include"highgui.h"using namespace cv;Mat markerMask, img;Point prePt(-1,-1);void onMouse(int event ,int x,int y,int flags,void* param){if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON)) prePt = Point(-1,-1);if (event == CV_EVENT_LBUTTONDOWN)prePt = Point(x,y);if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON)){Point pt(x,y);if (prePt.x < 0) prePt = pt;line(markerMask,prePt,pt,Scalar(255,255,255),5);line(img, prePt, pt, Scalar(255, 255, 255), 5);prePt = pt;imshow("原圖", img);}}int main(){Mat img0 = imread("D:\\tongliya.jpg",1);img0.copyTo(img);namedWindow("原圖",1);imshow("原圖",img);Mat imgGray;//最後顯示watershed效果圖用cvtColor(img0,markerMask,CV_BGR2GRAY);cvtColor(markerMask,imgGray,CV_GRAY2BGR);markerMask = Scalar::all(0);setMouseCallback("原圖",onMouse,NULL);while (1){int c = waitKey(10);if ((char)c == 'q' || (char)c == 27) return 0;if ((char)c == 'r'){img0.copyTo(img);markerMask = Scalar::all(0);imshow("原圖",img);}if (char(c) == 'p'){vector<vector<Point>> contours;vector<Vec4i> hierarchy;int count=0;findContours(markerMask,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);<span style="color:#33CC00;">//輸入映像image必須為一個2值單通道映像</span>if (contours.empty()) continue;Mat markers(markerMask.size(),CV_32S);markers = Scalar::all(0);for (int idx = 0; idx >= 0; idx = hierarchy[idx][0], count++)<span style="color:#33CC00;">//hierarchy[idx][0]表示後一個輪廓</span>drawContours(markers,contours,idx,Scalar::all(count+1),-1,8,hierarchy,INT_MAX);if (count == 0) continue;watershed(img0,markers);vector<Vec3b> colorTab;<span style="color:#33CC00;">//隨機設定顏色</span>                        for (int i = 0; i < count; i++){int b = theRNG().uniform(0, 255);int g = theRNG().uniform(0, 255);int r = theRNG().uniform(0, 255);colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));}Mat wshed(markers.size(),CV_8UC3);for (int i = 0; i < markers.rows;i++)for (int j = 0; j < markers.cols; j++){int tmp = markers.at<int>(i,j);if (tmp == -1) wshed.at<Vec3b>(i, j) = Vec3b(255,255,255);//邊界值為-1else if (tmp <= 0 || tmp>count) wshed.at<Vec3b>(i, j) = Vec3b(0,0,0);else wshed.at<Vec3b>(i, j) = colorTab[tmp-1];}imshow("分水嶺變換1", wshed);wshed = 0.5*wshed + 0.5*imgGray;imshow("分水嶺變換",wshed);}}return 0;}



個人理解:

          1.watershed()函數接受兩個參數,void watershed(InputArray image, InputOutputArraymarkers)

輸入映像image為 8位3通道,markers為帶有標記映像(or map),結果儲存在markers中。

          2.markers根據標記把像素 設定為1,2,3.。。。。

          3.findContours contours參數為檢測的輪廓數組,count記錄輪廓組數,markers的結果也為1,2,....count,所以顏色也隨機設為count種。

          4.根據markers值,不同地區繪製不同顏色,邊界值為-1,繪製為白色。

           5.結果截圖

例2:

#include "cv.h"#include "highgui.h"using namespace cv;int main(){    Mat img = imread("D:\\tongliya.jpg");    imshow("original image",img);    Mat imgGray;    cvtColor(img,imgGray,CV_BGR2GRAY);    imshow("gray image", imgGray);    Mat binary;    //adaptiveThreshold(imgGray,binary,255,ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY,5,0);    threshold(imgGray,binary,100,255,CV_THRESH_BINARY_INV);    imshow("binary image", binary);    Mat fg;    erode(binary,fg,Mat(),Point(-1,-1),1);//255標註前景,腐蝕使高亮地區隔離且縮小,可以擷取僅僅屬於重要物體的像素    imshow("foreground image",fg);    Mat bg;    dilate(binary,bg,Mat(),Point(-1,-1),1);//背景用128標註,膨脹使高亮地區得到擴充和聯通    threshold(bg,bg,1,128,THRESH_BINARY_INV);    imshow("background image", bg);    Mat markers(binary.size(),CV_8U,Scalar::all(0));    markers = fg + bg;//分水嶺演算法輸入參數    imshow("markers image", markers);    markers.convertTo(markers,CV_32S);    watershed(img,markers);//更新標記映像    Mat tmp = markers.clone();    markers.convertTo(tmp,CV_8U);//返回標記映像,分水嶺位於值0    imshow("Segmentation",tmp);    markers.convertTo(tmp,CV_8U,255,255);    imshow("Watersheds邊界", tmp);    waitKey();    return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.