图像分水岭法图像分割

 

 

 

 C++: void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize)

 

参数详解:

InputArray src:输入的图像,一般为二值图像

 OutputArray dst:输出的图像

int distanceType:所用的求解距离的类型、

It can be CV_DIST_L1, CV_DIST_L2 , or CV_DIST_C

mask_size  距离变换掩模的大小,可以是 3 或 5. 对 CV_DIST_L1 或 CV_DIST_C 的情况,参数值被强制设定为 3, 因为 3×3 mask 给出 5×5 mask 一样的结果,而且速度还更快。 

 

mask:
用户自定义距离情况下的 mask。 在 3×3 mask 下它由两个数(水平/垂直位量,对角线位移量)组成, 5×5 mask 下由三个数组成(水平/垂直位移量,对角位移和 国际象棋里的马步(马走日))

 

博客转至:https://www.cnblogs.com/long5683/p/9692845.html

  1 #include <opencv2/opencv.hpp>
  2 #include <iostream>
  3 
  4 using namespace cv;
  5 using namespace std;
  6 
  7 Mat src;
  8 
  9 int main(int argc, char** argv)
 10 {
 11     src = imread("分水岭.jpg");
 12     if (src.empty())
 13     {
 14         printf("Can not load Image...");
 15         return -1;
 16     }
 17     imshow("input Image",src);
 18 
 19     //白色背景变成黑色
 20     for (int row=0;row<src.rows;row++)
 21     {
 22         for (int col = 0; col < src.cols; col++) {
 23             if (src.at<Vec3b>(row, col) == Vec3b(255, 255, 255)) {
 24                 src.at<Vec3b>(row, col)[0] = 0;
 25                 src.at<Vec3b>(row, col)[1] = 0;
 26                 src.at<Vec3b>(row, col)[2] = 0;
 27             }
 28         }
 29     }
 30     imshow("black backgroung", src);
 31 
 32     //sharpen(提高对比度)
 33     Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);
 34 
 35     //make it more sharp
 36     Mat imgLaplance;
 37     Mat sharpenImg = src;
 38     //拉普拉斯算子实现边缘提取
 39     filter2D(src, imgLaplance, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);//拉普拉斯有浮点数计算,位数要提高到32
 40     src.convertTo(sharpenImg, CV_32F);
 41 
 42     //原图减边缘(白色)实现边缘增强
 43     Mat resultImg = sharpenImg - imgLaplance;
 44 
 45     resultImg.convertTo(resultImg,CV_8UC3);
 46     imgLaplance.convertTo(imgLaplance, CV_8UC3);
 47     imshow("sharpen Image", resultImg);
 48 
 49     //转换成二值图
 50     Mat binary;
 51     cvtColor(resultImg, resultImg, CV_BGR2GRAY);
 52     threshold(resultImg, binary,40,255,THRESH_BINARY|THRESH_OTSU);
 53     imshow("binary image",binary);
 54 
 55     //距离变换
 56     Mat distImg;
 57     distanceTransform(binary,distImg,DIST_L1,3,5);
 58     normalize(distImg, distImg, 0, 1, NORM_MINMAX);
 59     imshow("dist image",distImg);
 60 
 61     //二值化
 62     threshold(distImg, distImg, 0.4, 1, THRESH_BINARY);
 63     imshow("dist binary image", distImg);
 64 
 65     //腐蚀(使得连在一起的部分分开)
 66     Mat k1 = Mat::ones(3, 3, CV_8UC1);
 67     erode(distImg, distImg, k1);
 68     imshow("分开", distImg);
 69 
 70     //标记
 71     Mat dist_8u;
 72     distImg.convertTo(dist_8u,CV_8U);
 73     vector<vector<Point>> contours;
 74     findContours(dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
 75 
 76     //创建标记
 77     Mat marker = Mat::zeros(src.size(),CV_32SC1);
 78 
 79     //画标记
 80     for (size_t i = 0; i < contours.size(); i++)
 81     {
 82         drawContours(marker,contours,static_cast<int>(i),Scalar(static_cast<int>(i)+1),-1);
 83     }
 84 
 85     circle(marker, Point(5, 5), 3, Scalar(255, 255, 255), -1);
 86     imshow("marker",marker*1000);
 87 
 88     //分水岭变换
 89     watershed(src,marker);//根据距离变换的标记,在原图上分离
 90     Mat water = Mat::zeros(marker.size(),CV_8UC1);
 91     marker.convertTo(water,CV_8UC1);
 92     bitwise_not(water, water,Mat());//取反操作
 93     //imshow("源 image", src);
 94     imshow("watershed Image", water);
 95 
 96     // generate random color
 97     vector<Vec3b> colors;
 98     for (size_t i = 0; i < contours.size(); i++) {
 99         int r = theRNG().uniform(0, 255);
100         int g = theRNG().uniform(0, 255);
101         int b = theRNG().uniform(0, 255);
102         colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
103     }
104 
105     // fill with color and display final result
106     Mat dst = Mat::zeros(marker.size(), CV_8UC3);
107     for (int row = 0; row < marker.rows; row++) {
108         for (int col = 0; col < marker.cols; col++) {
109             int index = marker.at<int>(row, col);
110             if (index > 0 && index <= static_cast<int>(contours.size())) {
111                 dst.at<Vec3b>(row, col) = colors[index - 1];
112             }
113             else {
114                 dst.at<Vec3b>(row, col) = Vec3b(0, 0, 0);
115             }
116         }
117     }
118     imshow("Final Result", dst);
119     waitKey(0);
120     return 0;
121 }
posted @ 2022-04-01 16:54  量子与太极  阅读(57)  评论(0编辑  收藏  举报