zoukankan      html  css  js  c++  java
  • OpenCV——距离变换与分水岭算法的(图像分割)

     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 下由三个数组成(水平/垂直位移量,对角位移和 国际象棋里的马步(马走日))

     

     

      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 }
  • 相关阅读:
    HBase的compact分析
    HBase Rowkey的散列与预分区设计
    Zookeeper 快速理解
    oozie 入门
    Apache Storm内部原理分析
    Java ArrayList源码剖析
    Java HashSet和HashMap源码剖析
    初步掌握Yarn的架构及原理
    UML用例图总结
    UML类图几种关系的总结
  • 原文地址:https://www.cnblogs.com/long5683/p/9692845.html
Copyright © 2011-2022 走看看