参考https://blog.csdn.net/qq_34914551/article/details/78916084
其中连通域的轮廓选取用到了OTSU算法
#include "stdafx.h"
#include
#include
using namespace cv;
using namespace std;
//otsu算法实现函数
int Otsu(Mat &image)
{
int width = image.cols;
int height = image.rows;
int x = 0, y = 0;
int pixelCount[256];
float pixelPro[256];
int i, j, pixelSum = width * height, threshold = 0;
uchar* data = (uchar*)image.data;
//初始化
for (i = 0; i < 256; i++)
{
pixelCount[i] = 0;
pixelPro[i] = 0;
}
//统计灰度级中每个像素在整幅图像中的个数
for (i = y; i < height; i++)
{
for (j = x; j deltaMax)
{
deltaMax = deltaTmp;
threshold = i;
}
}
//返回最佳阈值;
return threshold;
}
int main()
{
Mat matSrc = imread("1.png", 0);
GaussianBlur(matSrc, matSrc, Size(5, 5), 0);
vector > contours;//contours的类型,双重的vector
vector hierarchy;//Vec4i是指每一个vector元素中有四个int型数据。
//阈值
threshold(matSrc, matSrc, 100, 255, THRESH_BINARY);
imshow("threshold", matSrc);
//寻找轮廓,这里注意,findContours的输入参数要求是二值图像,二值图像的来源大致有两种,第一种用threshold,第二种用canny
findContours(matSrc.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
/// 计算矩
vector mu(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mu[i] = moments(contours[i], false);
}
/// 计算中心矩:
vector mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
}
/// 绘制轮廓
Mat drawing = Mat::zeros(matSrc.size(), CV_8UC1);
for (int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(255);
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
circle(drawing, mc[i], 4, Scalar(128), -1, 8, 0); //中心用灰点表示
}
imshow("outImage",drawing);
waitKey();
return 0;
}
#include "stdafx.h"
#include
#include
using namespace cv;
using namespace std;
//otsu算法实现函数
int Otsu(Mat &image)
{
int width = image.cols;
int height = image.rows;
int x = 0, y = 0;
int pixelCount[256];
float pixelPro[256];
int i, j, pixelSum = width * height, threshold = 0;
uchar* data = (uchar*)image.data;
//初始化
for (i = 0; i < 256; i++)
{
pixelCount[i] = 0;
pixelPro[i] = 0;
}
//统计灰度级中每个像素在整幅图像中的个数
for (i = y; i < height; i++)
{
for (j = x; j deltaMax)
{
deltaMax = deltaTmp;
threshold = i;
}
}
//返回最佳阈值;
return threshold;
}
int main()
{
Mat matSrc = imread("1.png", 0);
GaussianBlur(matSrc, matSrc, Size(5, 5), 0);
vector > contours;//contours的类型,双重的vector
vector hierarchy;//Vec4i是指每一个vector元素中有四个int型数据。
//阈值
threshold(matSrc, matSrc, 100, 255, THRESH_BINARY);
imshow("threshold", matSrc);
//寻找轮廓,这里注意,findContours的输入参数要求是二值图像,二值图像的来源大致有两种,第一种用threshold,第二种用canny
findContours(matSrc.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
//计算最大连通域中心点
int index;
double area, maxArea(0);
for (int i = 0; i < contours.size(); i++)
{
area = contourArea(Mat(contours[i]));
if (area > maxArea)
{
maxArea = area;
index = i;
}
}
// 计算矩
vector mu(contours.size());
mu[index] = moments(contours[index], false);
// 计算中心矩:
vector mc(contours.size());
mc[index] = Point2f(mu[index].m10 / mu[index].m00, mu[index].m01 / mu[index].m00);
// 绘制轮廓
Mat drawing = Mat::zeros(matSrc.size(), CV_8UC1);
Scalar color = Scalar(255);
drawContours(drawing, contours, index, color, 2, 8, hierarchy, 0, Point());
circle(drawing, mc[index], 4, Scalar(128), -1, 8, 0); //中心用灰点表示
imshow("outImage",drawing);
waitKey();
return 0;
}