• Opencv 分水岭分割图片


    #include <iostream>
    #include <opencv2/opencv.hpp>

    using namespace std;
    using namespace cv;

    Mat img1, img2, img3, img4, img5,img6,img_result, img_gray1, img_gray2, img_gray3, img_canny1,img_binary1, img_dist1,kernel_1,kernel_2,img_laplance,img_sharp;

    char win1[] = "window1";
    char win2[] = "window2";
    char win3[] = "window3";
    char win4[] = "window4";
    char win5[] = "window5";
    char win6[] = "window6";
    char win7[] = "window7";

    int thread_value = 100;
    int max_value = 255;
    RNG rng1(12345);
    RNG rng2(1235);

    int Demo_Moments();

    int Demo_Moments()
    {
      namedWindow(win1, CV_WINDOW_AUTOSIZE);
      namedWindow(win2, CV_WINDOW_AUTOSIZE);
      //namedWindow(win3, CV_WINDOW_AUTOSIZE);

      img1 = imread("D://images//24.jpg");
      //img2 = imread("D://images//1//p5_1.jpg");
      if (img1.empty())
      {
        cout << "could not load image..." << endl;
        return 0;
      }

      imshow(win1, img1);
      img1.copyTo(img2);

      //背景色变黑色
      for (size_t row =0;row<img2.rows;row++)
      {
        for (size_t col=0;col<img2.cols;col++)
        {
          //if (img2.at<Vec3b>(row,col)==Vec3b(135,26,95))
          if(img2.at<Vec3b>(row,col)[0]>100 && img2.at<Vec3b>(row,col)[0]<150 && img2.at<Vec3b>(row,col)[1]>18 && img2.at<Vec3b>(row, col)[1] <80 && img2.at<Vec3b>(row,col)[2]>80 && img2.at<Vec3b>(row,col)[2]<170)
          {
            img2.at<Vec3b>(row, col)[0] = 0;
            img2.at<Vec3b>(row, col)[1] = 0;
            img2.at<Vec3b>(row, col)[2] = 0;
          }
        }
      }
      
      imshow(win2, img2);
      img2.copyTo(img_sharp);

      //通过拉普拉斯-锐化边缘
      kernel_1 = (Mat_<float>(3,3)<<1,1,1,1,-8,1,1,1,1);
      filter2D(img2, img_laplance, CV_32F,kernel_1, Point(-1, -1), 0, BORDER_DEFAULT);
      img2.convertTo(img_sharp, CV_32F);
      img3 = img_sharp - img_laplance;

      img3.convertTo(img3, CV_8UC3);
      img_laplance.convertTo(img_laplance, CV_8UC3);

      imshow(win3, img3);

      //转灰度图
      cvtColor(img3, img4, CV_BGR2GRAY);
      //二值化
      threshold(img4, img_binary1, 40, 255, THRESH_BINARY | THRESH_OTSU);

      //距离变换
      distanceTransform(img_binary1, img_dist1, DIST_L1, 3, 5);
      //归一化处理
      normalize(img_dist1, img_dist1, 0, 1, NORM_MINMAX);
      //imshow(win4,img_dist1);
      //距离变换结果二值化
      threshold(img_dist1, img_dist1, 0.4, 1, THRESH_BINARY);
      
      //定义腐蚀核大小
      kernel_2 = Mat::ones(3,3,CV_8UC1);
      //腐蚀二值图
      erode(img_dist1, img_dist1, kernel_2, Point(-1, -1));
      imshow(win4, img_dist1);

      img_dist1.convertTo(img5, CV_8U);

      //查找轮廓,标记,得到标记轮廓的图片
      vector<vector<Point>> vec_points;
      //查找轮廓
      findContours(img5, vec_points, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));

      //
      img6 = Mat::zeros(img1.size(),CV_32SC1);
      for (size_t i=0;i<vec_points.size();i++)
      {
        //drawContours(img6, vec_points, static_cast<int>(i), Scalar(rng1.uniform(0,255), rng1.uniform(0, 255), rng1.uniform(0, 255)),-1);
        drawContours(img6, vec_points, static_cast<int>(i), Scalar::all(static_cast<int>(i) + 1), -1);
        //drawContours(img6, vec_points, static_cast<int>(i), Scalar(theRNG().uniform(0, 255), theRNG().uniform(0, 255), theRNG().uniform(0, 255)), -1);
      }

      //circle(img6,Point(5,5),3,Scalar(rng1.uniform(0, 255), rng1.uniform(0, 255), rng1.uniform(0, 255)),-1);
      //circle(img6, Point(5, 5), 3, Scalar(theRNG().uniform(0, 255), theRNG().uniform(0, 255), theRNG().uniform(0, 255)), -1);
      circle(img6,Point(5,5),3,Scalar(255,255,255),-1);
      imshow(win5,img6*3000);
      
      //在标记图片的基础上进行分水岭变换
      watershed(img1,img6);
      Mat img_mark = Mat::zeros(img6.size(),CV_8UC1);
      img6.convertTo(img_mark,CV_8UC1);
      //取反
      bitwise_not(img_mark,img_mark,Mat());
      imshow(win6,img_mark);

      //着色
      vector<Vec3b> vec_colors;
      for (size_t j=0;j<vec_points.size();j++)
      {
        int color_r = rng2.uniform(0,255);
        int color_g = rng2.uniform(0, 255);
        int color_b = rng2.uniform(0, 255);

        //int color_r = theRNG().uniform(10, 255);
        //int color_g = theRNG().uniform(10, 255);
        //int color_b = theRNG().uniform(10, 255);

        vec_colors.push_back(Vec3b((uchar)color_b,(uchar)color_g,(uchar)color_r));
        //vec_colors.push_back(Vec3b((uchar)rng1.uniform(0,255), (uchar)rng1.uniform(0, 255), (uchar)rng1.uniform(0, 255)));
      }

      img_result = Mat::zeros(img6.size(),CV_8UC3);
      for (size_t row=0;row<img6.rows;row++)
      {
        for (size_t col=0;col<img6.cols;col++)
        {
          int index_1 = img6.at<int>(row,col);
          if (index_1>0 && index_1<=static_cast<int>(vec_points.size()))
          {
            img_result.at<Vec3b>(row, col) = vec_colors[index_1 -1];
          }
          else
          {
            img_result.at<Vec3b>(row, col) = Vec3b(0,0,0);
          }
        }
      }

      imshow(win7, img_result);

      return 0;
    }

    int main()
    {
      Demo_Moments();

      waitKey(0);
      return 0;
    }

     

  • 相关阅读:
    [转]HTTP请求模型和头信息参考
    括号匹配算法
    SQL LEFT JOIN 关键字 (转)
    Vim学习资料汇总
    与图相关的算法
    关于字符串的一些算法
    Huffman编码
    迅雷开放了下载引擎
    ubuntu下《UNIX环境高级编程》(apue.h)编译出错的处理方法
    学习unix信号
  • 原文地址:https://www.cnblogs.com/herd/p/9739619.html
Copyright © 2020-2023  润新知