#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;
}

Opencv 分水岭分割图片的更多相关文章

  1. 基于标记的分水岭分割算法/OpenCV中距离变换

    Opencv分水岭算法——watershed自动图像分割用法 OpenCV距离变换distanceTransform应用 图像分割作为图像识别的基础,在图像处理中占有重要地位,通常需要在进行图像分割算 ...

  2. 分水岭分割算法(watershed segmentation)的C++实现(法2)

    运行环境:ubuntu16.04+Qt+opencv2.4.13.3 watershed.cpp #include "opencv2/imgproc/imgproc.hpp" #i ...

  3. Opencv分水岭算法——watershed自动图像分割用法

    分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特 ...

  4. opencv::分水岭图像分割

    分水岭分割方法原理 (3种) - 基于浸泡理论的分水岭分割方法 (距离) - 基于连通图的方法 - 基于距离变换的方法 图像形态学操作: - 腐蚀与膨胀 - 开闭操作 分水岭算法运用 - 分割粘连对象 ...

  5. Matlab的标记分水岭分割算法

    1 综述 Separating touching objects in an image is one of the more difficult image processing operation ...

  6. 用CorelDRAW等分分割图片的方法

    在CorelDRAW中,想要将图片等分分割可以通过放置容器来实现,根本不需要裁剪工具和辅助线.例如两等分:首先要建立确定等分的份数,建立长方形或正方形.然后把图片放置容器,调整位置,做无缝拼接就可以了 ...

  7. 怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图?

      分类: OpenCV [Q1]怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图? 进行灰度化,IplImage* pImg = cvLoadImage( "C:\\1.b ...

  8. csharp通过dll调用opencv函数,图片作为参数

    [blog 项目实战派]csharp通过dll调用opencv函数,图片作为参数          ​一直想做着方面的研究,但是因为这个方面的知识过于小众,也是由于自己找资料的能力比较弱,知道今天才找 ...

  9. TensorFlow与OpenCV,读取图片,进行简单操作并显示

    TensorFlow与OpenCV,读取图片,进行简单操作并显示 1 OpenCV读入图片,使用tf.Variable初始化为tensor,加载到tensorflow对图片进行转置操作,然后openc ...

随机推荐

  1. oracle 内存分配和调优 总结

    一直都想总结一下oracle内存调整方面的知识,最近正好优化一个数据库内存参数,查找一些资料并且google很多下.现在记录下来,做下备份.           一.概述:              ...

  2. YARN的Fair Scheduler和Capacity Scheduler

    关于Scheduler YARN有四种调度机制:Fair Schedule,Capacity Schedule,FIFO以及Priority: 其中Fair Scheduler是资源池机制,进入到里面 ...

  3. boost 编译 安装

    首先到 boost.org 下载 boost_1_54_0.tar.gz 上传到 linux 环境下 解压缩 给解压缩出来的文件斌权限 chmod 777 ./* 执行己写好的 shell脚本 boo ...

  4. (转)jdbc 调用 sql server 的存储过程时“该语句没有返回结果集”的解决方法

    本文转载自:http://hedyn.iteye.com/blog/856040 在JDBC中调用SQL Server中的存储过程时出现如下异常: com.microsoft.sqlserver.jd ...

  5. rtmp直播推流(一)--flv格式解析与封装

    flv文件格式分析,可参看RTMP中FLV流到标准h264.aac的转换,该文章写的很清晰. flv封装格式解析,可参看视音频数据处理入门:FLV封装格式解析,文章图文并貌,很直观. flv文件封装, ...

  6. 数据运算+-*/,比较运算符==!=,赋值运算,逻辑运算and,or,not,成员运算in,not in,身份运算is is not,位运算&|,运算符的优先级

    取模就是返回余数. 取模的作用主要是来取奇偶数来用的,奇数干嘛,偶数干嘛. 比较运算符: 赋值运算: 逻辑运算: 赋值的时候可以多个变量同时赋值 成员运算: in就是在不在的意思. 身份运算: 位运算 ...

  7. js手机号正则表达式验证

    var phone = $("#phone").val(); //陈旧版 var parphone = /^(((13[0-9]{1})|(17[0-9]{1})|(15[0-9] ...

  8. JPype:实现在python中调用JAVA

    一.JPype简述 1.JPype是什么? JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python 在某些领域(如服务器端编程)中的不足. 2.JPype ...

  9. VS2015 异常 :遇到异常。这可能是由某个扩展导致的

    原因是安装程序时将注册表修改了,解决方案: 修改注册表: 64位机器: [HKEY_CLASSES_ROOT\CLSID\{73B7DC00-F498-4ABD-AB79-D07AFD52F395}\ ...

  10. Entity Framework使用汇总

    EF的发展历程 还是先来说一下EF从诞生到现在这几年的发展历程吧.在EF最初的版本中,作为一个ORM组件其通过EDM文件(里面是一些xml)来配置数据库与实体类之间的映射,实现数据进出数据库的控制.最 ...