本章内容
* 基于分水岭的图像分割算法
*1.均值漂移滤波,
* 2.二值化
* 3.距离变换
* 4.查找轮廓,获取标记
* 5.分水岭
* 6.标记颜色
输出结果:
源码:
#include<opencv2/opencv.hpp>
#include<iostream>
int main(int argc, char** argv) {
/* 本章内容
* 基于分水岭的图像分割算法
*1.均值漂移滤波,
* 2.二值化
* 3.距离变换
* 4.查找轮廓,获取标记
* 5.分水岭
* 6.标记颜色
*/
cv::String fileName = "/home/wang/dev/Image/coins_001.jpg";
cv::Mat src = cv::imread(fileName);
if(src.data == NULL ){
std::cout << "文件读入失败" << std::endl;
return -1;
}
cv::imshow("src", src);
// 1.均值漂移滤波,
cv::Mat shifted;
cv::pyrMeanShiftFiltering(src,shifted,21,15);
cv::imshow("shifted",shifted);
// 2.二值化
cv::Mat gray;
cv::cvtColor(shifted,gray,cv::COLOR_BGR2GRAY);
cv::Mat binary;
cv::threshold(gray,binary,0,255,cv::THRESH_BINARY|cv::THRESH_OTSU);
cv::imshow("binary",binary);
cv::Mat k = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(-1, -1));
cv::morphologyEx(binary,binary,cv::MORPH_OPEN,k,cv::Point(-1,-1),5);
cv::imshow("binary MORPH_OPEN",binary);//3.距离变换
cv::Mat dist;
cv::distanceTransform(binary,dist,cv::DistanceTypes::DIST_L2,3);
cv::normalize(dist,dist,1,0,cv::NORM_MINMAX);
cv::imshow("dist", dist);
cv::threshold(dist,dist,0.2,1,cv::THRESH_BINARY); //
cv::imshow("dist bynary", dist);// 4.查找轮廓,获取标记
std::vector<std::vector<cv::Point>> contours;
cv::Mat distU8;
dist.convertTo(distU8,CV_8U);
cv::findContours(distU8,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE,cv::Point(0,0));
cv::Mat marker = cv::Mat::zeros(src.size(),CV_32F);
for(int i=0; i < contours.size();i++){
cv::drawContours(marker,contours,i, cv::Scalar(i + 1),-1); // -1表示填充
}
cv::imshow("marker",marker);
// 原图像腐蚀
cv::morphologyEx(src,src,cv::MORPH_ERODE,k);
cv::imshow("src1",src);// 5.分水岭
std::cout << "src.type()" << src.type() << std::endl;
marker.convertTo(marker,CV_32SC1);
cv::watershed(src,marker);
cv::Mat makU8;
marker.convertTo(makU8,CV_8UC1);
cv::imshow("makU8",makU8*20);// 6.标记颜色
std::vector<cv::Vec3b> colors;
for(int i=0; i < contours.size(); i++){
int b = cv::theRNG().uniform(0,255);
int g = cv::theRNG().uniform(0,255);
int r = cv::theRNG().uniform(0,255);
colors.push_back(cv::Vec3b(b,g,r));
}cv::Mat dst = cv::Mat::zeros(marker.size(), CV_8UC3);
int index = 0;
for (int row = 0; row < marker.rows; row++) {
for (int col = 0; col < marker.cols; col++) {
index = marker.at<int>(row, col);
if (index > 0 && index <= contours.size()) {
dst.at<cv::Vec3b>(row, col) = colors[index - 1];
} else {
dst.at<cv::Vec3b>(row, col) = cv::Vec3b(0, 0, 0);
}
}
}
imshow("Final Result", dst);cv::waitKey(0);
return 0;
}