opencv —— 重叠对象计数案例实践

opencv —— 重叠对象计数案例实践

4 人赞同了该文章

在图像中特征物体计数的需求中,可先对图像进行阈值分割 ,根据图像效果,可适当使用形态学操作来优化图像效果。如果在某一个光照环境下,物体表面的反光度不一样,导致图像中特征物体间的轮廓边界不明显,则可以通过距离变换函数distanceTransform(),勾勒出大致的骨架,注意需要规范(归一)化操作。提取出对应物体的大致连通区域 ,最后可通过形态学操作来分离特征,达到能计数的图像效果,通过查找轮廓就可以得到所需数据。

示例: 计算玉米的个数

源码:

#include "stdafx.h"
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/opencv.hpp> 
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
//#include <algorithm>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{

Mat img;
img = imread("E:\\homework\\4\\test_opencv2\\yumi.png");

if (img.empty())
{
	cout &lt;&lt; "null" &lt;&lt; endl;
	return 0;
}

Mat imgGray;
cvtColor(img, imgGray, COLOR_RGB2GRAY);

imshow("img", img);


// 阈值分割
Mat imgTraiangle;
threshold(imgGray, imgTraiangle, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
imshow("imgTraiangle", imgTraiangle);

图像膨胀
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
Mat imgDilate;
dilate(imgTraiangle, imgDilate, kernel, Point(-1, -1),2);
//imshow("imgDilate", imgDilate);

// 距离变换,把这个大概的骨架给它整出来
Mat imgDist;
bitwise_not(imgTraiangle, imgDilate);
distanceTransform(imgDilate, imgDist, CV_DIST_L2, 3);
normalize(imgDist, imgDist, 0, 255, NORM_MINMAX);
Mat imgdst_8u;
imgDist.convertTo(imgdst_8u, CV_8U);

imshow("imgdst_8u", imgdst_8u);

// 通过阈值分割,生成区域
Mat imgThreld;
adaptiveThreshold(imgdst_8u, imgThreld, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 105, 0);
imshow("imgthreld", imgThreld);

// 生成的区域,用腐蚀操作,分离连通区域
Mat imgErode;
Mat kernelErode = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
erode(imgThreld, imgErode, kernelErode, Point(-1, -1), 5);
imshow("imgErode", imgErode);

// 计数
vector&lt;vector&lt;Point&gt;&gt; contours;
vector&lt;Vec4i&gt; hieray;
findContours(imgErode, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(-1, -1));

Mat draw = Mat::zeros(img.size(), CV_8UC3);
RNG rgb(12345);

for (int i = 0; i &lt; contours.size(); i++)
{
	drawContours(draw, contours, static_cast&lt;int&gt;(i), Scalar(rgb.uniform(0, 255), rgb.uniform(0, 255), rgb.uniform(0, 255)), 1, 8, hieray);
}

cout &lt;&lt; "玉米数目 = " &lt;&lt; contours.size() &lt;&lt; endl;

imshow("draw", draw);

waitKey(0);
return 1;

}


输出结果:

imgTraiangle


imgdst_8u
imgThreld
imgErode
draw
计数结果

编辑于 2022-11-12 23:33 ・IP 属地江苏
OpenCV3编程入门(书籍)
OpenCV
数字图像处理
赞同 4​ 添加评论
分享
喜欢 ​ 收藏 ​ 申请转载
赞同 4
分享
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值