Before passing the image to the function, you have to roughly outline the desired regions in the image markers with positive (>0) indices. So, every region is represented as one or more connected components with the pixel values 1, 2, 3, and so on. Such markers can be retrieved from a binary mask using findContours() and drawContours() (see the watershed.cpp demo). The markers are “seeds” of the future image regions. All the other pixels in markers , whose relation to the outlined regions is not known and should be defined by the algorithm, should be set to 0’s. In the function output, each pixel in markers is set to a value of the “seed” components or to -1 at boundaries between the regions.
翻译如下:
markers中存储了图像的大致轮廓,并且以1,2,3...分别表示各个components.markers通常由函数findContours() 和 drawContours()结合使用来获得。markers相当于watershed()运行时的参数。markers中,不属于轮廓(outlined regions)的点的应置为0.函数运行后,图像中的像素如果是在由某个轮廓生成的区域中,那么其就置为这个的编号,如果像素不在轮廓生成的区域中,则置为-1。分割图像算法代码
PS:上面这段话我想尽可能为大家描述清楚,但实在是文字水平有限,感觉还是说得不清楚,大家见谅。不过不要紧,如果看不懂,下面给出的代码看了之后你就全懂了。
代码如下(代码中用到的图像的下载链接:https://pan.baidu.com/s/1dEEP10t):

#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <cstdio>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
cv::Mat srcImage =cv::imread("sea.jpg");
if (!srcImage.data)
return -1;
Mat src_gray;
int thresh = 100; //canny边缘检测的阈值
int max_thresh = 255;
RNG rng(12345);
// 转成灰度并平滑
cvtColor(srcImage, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
// 创建窗体
imshow("srcImage", srcImage);
//用Canny算子检测边缘
Mat canny_output;
Canny(src_gray, canny_output, thresh, thresh * 2, 3);
// 寻找轮廓
vector<vector<Point> > contours;
vector<Vei> hierarchy;
findContours(canny_output, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
if( contours.empty() )
{
cout<<"没有检测到图像的轮廓"<<endl;
return 0;
}
//绘制轮廓到markers,以供watershed函数调用
int i, j, compCount = 0;
Mat markers(canny_output.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ )
drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
vector<Vec3b> colorTab;
for( i = 0; i < compCount; 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));
}
watershed(srcImage, markers );//分水岭算法实现函数
Mat wshed(markers.size(), CV_8UC3);
Mat imgGray;
cvtColor(src_gray, imgGray, COLOR_GRAY2BGR);
// paint the watershed image
for( i = 0; i < markers.rows; i++ )
for( j = 0; j < markers.cols; j++ )
{
int index = markers.at<int>(i,j);
if( index == -1 )
wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);
else if( index <= 0 || index > compCount )
wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);
else
wshed.at<Vec3b>(i,j) = colorTab[index - 1];
}
//wshed = wshed*0.5 + imgGray*0.5;
imshow("imgGray",imgGray);
imshow( "watershed transform", wshed );
cv::waitKey(0);
return(0);
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-94197-2.html
也是醉
对于没有加入公约的美国