实现思路:
1、首先对图像进行预处理,包括对图像进行高斯滤波、边缘检测和二值化等操作;
2、使用分水岭算法对图像进行分割,它将图片分割成不同的区域;
3、最后,根据分割后的区域,我们可以绘制出属于不同区域的轮廓,并将其作为分割图像的结果。
C/C++代码实现:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
// 预处理:高斯滤波+边缘检测+二值化
Mat preprocess(Mat& img)
{
Mat blur,edge,thresh;
GaussianBlur(img, blur, Size(9, 9), 0);
Canny(blur, edge, 30, 150);
threshold(edge, thresh, 127, 255, 0);
return thresh;
}
// 分水岭算法分割
Mat segmentation(Mat& img)
{
Mat markers = Mat::zeros(img.size(), CV_8U);
markers(Rect(1, 1, img.cols - 2, img.rows - 2)) = 255;
WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
segmenter.process(img);
return segmenter.getSegmentation();
}
// 绘制轮廓
void drawContour(Mat& img, Mat& segImg)
{
Mat img_color;
cvtColor(img, img_color, COLOR_GRAY2BGR);
vector<vector<Point>> contours;
findContours(segImg, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
drawContours(img_color, contours, -1, Scalar(0, 0, 255), 3);
imshow("result", img_color);
}
int main(int argc, char** argv)
{
Mat img = imread("image.jpg", 0);
if (img.empty())
{
cout << "Could not open or find the image!\n" << endl;
return -1;
}
imshow("input", img);
Mat thresh = preprocess(img);
Mat segImg = segmentation(thresh);
drawContour(img, segImg);
imwrite("result.jpg", segImg);
waitKey(0);
return 0;
}