opencv分水岭算法区域的分割和合并

更新时间:2023-05-06 02:08:54 阅读: 评论:0

opencv分⽔岭算法区域的分割和合并
使⽤直⽅图相似性合并相似区域
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
using namespace cv;
Mat display(Mat& markers, int noOfSegment)
{
vector<Vec3b> colorTab;
for (int i = 0; i < noOfSegment; i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);
colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
Mat watershedImage(markers.size(), CV_8UC3);
for (int i = 0; i < ws; i++)
{
for (int j = 0; j < ls; j++)
{
int index = markers.at<int>(i, j);
if (index == -1)
watershedImage.at<Vec3b>(i, j) = Vec3b((uchar)255, (uchar)255, (uchar)255);
el if (index <= 0 || index > noOfSegment)
watershedImage.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
el
watershedImage.at<Vec3b>(i, j) = colorTab[index - 1];
}
}
return watershedImage;
}
//分⽔岭图像分割
Mat watershedSrgment(Mat src, int& noOfSegment)//noOfSegment表⽰分割的类别数
{
Mat grayMat;
Mat otsuMat;
cvtColor(src, grayMat, CV_BGR2GRAY);
threshold(grayMat, otsuMat, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
imshow("src", src);
imshow("otsuMat", otsuMat);
//形态学
morphologyEx(otsuMat, otsuMat, MORPH_OPEN, Mat::ones(9, 9, CV_8SC1), Point(4, 4), 2);//2表⽰迭代的次数,Point(4,4)表⽰结构元素的原点 imshow("Mor-open", otsuMat);
//距离变换
Mat ws, ls, CV_32FC1);
distanceTransform(otsuMat, disTranMat, CV_DIST_L2, 3);
//归⼀化
normalize(disTranMat, disTranMat, 0.0, 1, NORM_MINMAX);
imshow("DisTranMat", disTranMat);
//阈值分割
threshold(disTranMat, disTranMat, 0.1, 1, CV_THRESH_BINARY);
normalize(disTranMat, disTranMat, 0, 255, NORM_MINMAX);
imshow("TDisTranMat", disTranMat);
//计算标记的分割块
int i, j, compCount = 0;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(disTranMat, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); Mat markers(disTranMat.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
//绘制区域块
for (; idx >= 0; idx = hierarchy[idx][0], compCount++)
{
drawContours(markers, contours, idx, Scalar::all(compCount + 1), -1, 8, hierarchy, INT_MAX); }
imshow("markers", markers * 255);
double t = (double)getTickCount();
watershed(src, markers);
t = (double)getTickCount() - t;
cout << "time: " << t * 1000 / getTickFrequency() << endl;
Mat wash = display(markers, compCount);
imshow("watershedSrgment", wash);
noOfSegment = compCount;
waitKey(0);
return markers;
}
//分⽔岭图像合并
void gMerge(Mat src, Mat& gments, int& numSeg)
{
vector<Mat> samples;//每个分割区域
//统计区域更新
int newNumSeg = numSeg;
//初始化samples
for (int i = 0; i <= numSeg; i++)
{
Mat sampleImage;
samples.push_back(sampleImage);
}
//计算每个像素的归属
for (int i = 0; i < ws; i++)
{
for (int j = 0; j < ls; j++)
{
int index = gments.at<int>(i,j);
if (index >= 0 && index < numSeg)
samples[index].push_back(src(Rect(j,i,1,1)));
}
}
//创建直⽅图
vector<MatND> hist_bas;
Mat hsv_ba;
int h_bins = 35;
int s_bins = 30;
int hist_size[] = {h_bins,s_bins};
float h_ranges[] = {0,256};
float s_ranges[] = {0,180};
const float* ranges[] = { h_ranges,s_ranges };
int channels[] = {0,1};
MatND hist_ba;
for (int i = 0; i <= numSeg; i++)
{
if (samples[i].dims > 0)
{
cvtColor(samples[i], hsv_ba, CV_BGR2HSV);
calcHist(&hsv_ba, 1, channels, Mat(), hist_ba, 2, hist_size, ranges);
normalize(hist_ba, hist_ba, 0, 1, NORM_MINMAX, -1, Mat());
hist_bas.push_back(hist_ba);
}
el
hist_bas.push_back(Mat());
lea();
}
//计算各直⽅图之间的相似性
double similarity = 0;
vector<bool> merged;
for (int k = 0; k < hist_bas.size(); k++)
{
merged.push_back(fal);
}
for (int c = 0; c < hist_bas.size(); c++)
{
for (int q = c + 1; q < hist_bas.size(); q++)
{
if (!merged[q])
{
if (hist_bas[c].dims > 0 && hist_bas[q].dims>0)
{
similarity = compareHist(hist_bas[c],hist_bas[q],CV_COMP_BHATTACHARYYA);
if (similarity > 0.8)
{
merged[q] = true;
if (q != c)
{
newNumSeg--;
for (int i = 0; i < ws; i++)
{
for (int j = 0; j < ls; j++)
{
int index = gments.at<int>(i, j);
if (index == q)
gments.at<int>(i, j) = c;
}
}
}
}
}
}
}
}
numSeg = newNumSeg;
Mat wash=display(gments, numSeg);
imshow("gMerge", wash);
waitKey(0);
}
int main()
{
//imread中0表⽰灰度返回,1表⽰原图返回
Mat srcImage = imread("E:\\研究⽣\\学习材料\\学习书籍\\OpenCV图像处理编程实例-源码-20160801\\《OpenCV图像处理编程实例-源码-20160801\\images\\flower  if (!srcImage.data)
return -1;
int noOfSegment = 0;
Mat gments=watershedSrgment(srcImage, noOfSegment);
gMerge(srcImage, gments, noOfSegment); return 0;
}

本文发布于:2023-05-06 02:08:54,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/536495.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图