关于OpenCV3使用距离变换的应用C++实现DEMO-数玉米粒个数

关于OpenCV3使用距离变换的应用C++实现DEMO-数玉米粒个数

过程效果图

在这里插入图片描述在这里插入图片描述

软件环境

VS2015,OpenCV341,C++

代码实现

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

using namespace std;
using namespace cv;

int main(int argc, char** argv) {
	//1.读取图,灰度图
	Mat src = imread("G:\\opencv_trainning\\vs2015\\3\\statistical_count\\1.jpg",IMREAD_GRAYSCALE);
	//判空
	if (src.empty()) {
		cout << "open fault" << endl;
		return -1;
	}
	//显示
	namedWindow("src");
	imshow("src",src);
	//2.二值化分割-获得白底黑字图
	Mat dst;//灰度图
	//参数:(原图,目标图,阈值,最大值,阈值标记)
	threshold(src, dst, 100, 255,THRESH_BINARY|THRESH_TRIANGLE);//使用三角阈值,单峰
	imshow("first",dst);
	//3.形态学处理-膨胀去掉外围干扰
	Mat element = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));//定义结构元素,参数:(形状,核尺寸,锚点)
	dilate(dst,dst,element);//膨胀,参数:(原图,目标图,结构元素变量)
	imshow("second", dst);
	//4.距离变换-获得距离高亮(黑底白字)->归一化
	Mat dist;//
	bitwise_not(dst,dst,Mat());//反色处理,黑底白字,参数:(原图,目标图,掩码)
	distanceTransform(dst,dst,CV_DIST_L2,3);//距离变换,参数:(原图,目标图,距离变换类型,掩码(核)尺寸)
	normalize(dst,dst,0,1.0,NORM_MINMAX);//归一化,参数:(原图,目标图,最小值,最大值,归一化类型)
	imshow("third", dst);
	//5.局部阈值--局部阈值得到分离的每个物体,回到0-255的图片上来
	threshold(dst,dst,0.6,1.0,THRESH_BINARY);//再次二值分割,参数:(原图,目标图,阈值,最大值,阈值类型)
	normalize(dst,dst,0,255,NORM_MINMAX);//归一化到0-255数据区间,参数:(原图,目标图,最小值,最大值,归一化类型)
	Mat dst_8u;//定义8u变量
	dst.convertTo(dst_8u,CV_8U);//转化到新图中
	//参数:(原图,目标图,最大值,自适应方法(Gaussian/Mean),阈值类型,块尺寸,常量值),常量值给0即可,给正相当于反色效果
	adaptiveThreshold(dst_8u,dst_8u,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,85,0.0);//85位置给奇数,取图的1/4或1/6
	//6.形态学操作-膨胀,使局部变大,白色部分单体连接为一个整体
	dilate(dst_8u,dst_8u,element,Point(-1,-1),2);//参数:(原图,目标图,结构元素,锚点,迭代次数)
	imshow("fourth", dst_8u);
	//7.发现轮廓-获取轮廓信息
	vector<vector<Point>> contours;//定义轮廓点向量的向量
	vector<Vec4i> hierarchy;//定义拓扑结构向量
	//参数:(二值化图,轮廓向量的向量,发现方法,检测方法),此处发现方法使用RETR_EXTERNAL,只发现最外层的轮廓
	findContours(dst_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	//画轮廓
	Mat resultImg = Mat::zeros(src.size(),CV_8UC3);//创建结果图
	RNG rng(123456);//定义随机颜色变量
	for (int i = 0; i < contours.size(); i++) {//循环轮廓
		//画轮廓,参数:(图,轮廓点向量的向量,位置id,颜色,线宽),线宽为-1表示整体填充颜色
		drawContours(resultImg, contours, i, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1);
	}
	//8.统计计数
	char str[100] = {0};//定义字符串数组
	sprintf_s(str,"count=%d",contours.size());//打印轮廓个数
	//放文本到图片,参数:(图,字符串,原点,字体,尺度值,颜色),其他参数默认
	putText(resultImg,str,Point(10,30),FONT_HERSHEY_COMPLEX,1.0,Scalar(255,0,0));
	imshow("resultImg", resultImg);
	//显示
	waitKey(0);//按键等待
	return 0;
}

实现思路

1.灰度图:获得灰度图;
2.三角阈值二值化:获得白底黑字图;
3.图形学-膨胀:去掉外围小干扰;
4.反色、距离变换及归一化:获得黑底白字图后,再获得距离图,归一化(0~1)后得到统一数据范围;
5.局部阈值:二值化并更改数据为0~255;
6.形态学操作-膨胀,使局部变大,白色部分单体连接为一个整体;
7.发现轮廓:获得所有独立轮廓向量;
8.统计计数:获得轮廓个数;

我是Simon,在这里期待与您的交流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值