1
我想在OpenCV中創建兩個Blob的平均值。爲了實現這一目標,我打算以下列方式預處理的圖像上使用分水嶺算法:流域邊界緊密圍繞一個區域
cv::Mat common, diff, processed, result;
cv::bitwise_and(blob1, blob2, common); //calc common area of the two blobs
cv::absdiff(blob1, blob2, diff); //calc area where they differ
cv::distanceTransform(diff, processed, CV_DIST_L2, 3); //idea here is that the highest intensity
//will be in the middle of the differing area
cv::normalize(processed, processed, 0, 255, cv::NORM_MINMAX, CV_8U); //convert floats to bytes
cv::Mat watershedMarkers, watershedOutline;
common.convertTo(watershedMarkers, CV_32S, 1./255, 1); //change background to label 1, common area to label 2
watershedMarkers.setTo(0, processed); //set 0 (unknown) for area where blobs differ
cv::cvtColor(processed, processed, CV_GRAY2RGB); //watershed wants 3 channels
cv::watershed(processed, watershedMarkers);
cv::rectangle(watershedMarkers, cv::Rect(0, 0, watershedMarkers.cols, watershedMarkers.rows), 1); //remove the outline
//draw the boundary in red (for debugging)
watershedMarkers.convertTo(watershedOutline, CV_16S);
cv::threshold(watershedOutline, watershedOutline, 0, 255, CV_THRESH_BINARY_INV);
watershedOutline.convertTo(watershedOutline, CV_8U);
processed.setTo(cv::Scalar(CV_RGB(255, 0, 0)), watershedOutline);
//convert computed labels back to mask (blob), less relevant but shows my ultimate goal
watershedMarkers.convertTo(watershedMarkers, CV_8U);
cv::threshold(watershedMarkers, watershedMarkers, 1, 0, CV_THRESH_TOZERO_INV);
cv::bitwise_not(watershedMarkers * 255, result);
我的結果問題是,計算出的邊界是(幾乎)總是毗鄰常見的兩種斑點的面積。下面是圖片:
我期望邊界沿着輸入的最大強度區域(即沿着不同區域的中間)。相反(正如你所看到的),它主要圍繞標記爲2的區域,稍稍移動以觸摸背景(標記爲1)。我在這裏做錯了什麼,或者我誤解了分水嶺是如何工作的?
見[此](http://stackoverflow.com/questions/31961240/opencv-watershed-segmentation-miss-some-objects?rq=1) –
@JeruLuke感謝,但不是這樣。我的背景具有標籤1和對象2. – slawekwin
反轉距離變換,使距離較遠的點具有較小的值。在'normalize'行之後加上'processed = 255 - processed'。 – Miki