
opencv检测细胞个数
发布日期:2021-05-14 10:21:18
浏览次数:18
分类:精选文章
本文共 5728 字,大约阅读时间需要 19 分钟。
玉米(或大米)颗粒图像计数系统设计与实现
系统概述
本系统旨在通过图像处理技术快速、准确地计数玉米或其他谷物颗粒。该系统基于图像分割和特征检测技术,能够处理真实世界中的复杂场景,提供高精度的计数结果。
原理简述
该系统利用先进的图像处理算法,根据玉米颗粒的形态特征进行识别和计数。主要步骤包括:图像预处理、边缘检测、形态学操作、轮廓提取以及颗粒计数等。这些技术共同作用,实现对玉米颗粒的高效计数。
OpenCV3 代码实现
以下是基于OpenCV3的代码实现,用于玉米颗粒图像的预处理和计数。
#include#include #define PI 3.1415926using namespace std;using namespace cv;void fillHole(const Mat& srcBw, Mat& dstBw) { Size mSize = srcBw.size(); Mat Temp(mSize.height + 2, mSize.width + 2, srcBw.type()); srcBw.copyTo(Temp(Range(1, mSize.height + 1), Range(1, mSize.width + 1))); floodFill(Temp, Point(0, 0), Scalar(255)); Mat cutImg = Temp(Range(1, mSize.height + 1), Range(1, mSize.width + 1)).copyTo(cutImg); dstBw = srcBw | (~cutImg);}int main() { Mat srcImg; srcImg = imread("1.jpg"); clock_t start = clock(); namedWindow("原图", 0); imshow("原图", srcImg); waitKey(1); cvtColor(srcImg, srcImage, COLOR_BGR2GRAY); srcImage = srcImage > 160; Mat vec_rgb; vec_rgb = Mat::zeros(srcImage.size(), CV_8UC1); medianBlur(srcImage, vec_rgb, 3); namedWindow("中值滤波", 0); imshow("中值滤波", vec_rgb); waitKey(1); Canny(vec_rgb, vec_rgb, 3, 9, 3); namedWindow("边缘检测", 0); imshow("边缘检测", vec_rgb); waitKey(1); Mat element = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(1, 1)); erode(vec_rgb, vec_rgb, element); fillHole(vec_rgb, vec_rgb); namedWindow("填充处理", 0); imshow("填充处理", vec_rgb); waitKey(1); vector contours; vector hierarchy; hierarchy.push_back(Vec4i(0, 0, 0, 0)); findContours(vec_rgb, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point(0, 0)); vector > contours_poly; vector boundRect; vector center; vector radius; for(int i = 0; i < contours.size(); i++) { vector approxContour; approxPolyDP(Mat(contours[i]), approxContour, 3, true); contours_poly.push_back(approxContour); boundRect.push_back(boundingRect(Mat(approxContour))); minEnclosingCircle(approxContour, center[i], radius[i]); Point zhongdian = center[i]; cout << "玉米(或大米)颗粒坐标" << zhongdian.x << "," << zhongdian.y << endl; } Mat drawing; drawing = Mat::zeros(vec_rgb.size(), CV_8UC3); for(int i = 0; i < contours.size(); i++) { Scalar color = (0, 0, 255); drawContours(drawing, contours_poly[i], i, color, 1, 8, hierarchy, 0, Point()); rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); circle(drawing, center[i], (int)radius[i], color, 2, 8, 0); } namedWindow("包围矩形和圆形", 0); imshow("包围矩形和圆形", drawing); waitKey(1); cout << "玉米(或大米)颗粒个数" << contours.size() << endl; clock_t end = clock(); cout << "运行时间:" << ((double)(end - start)) / CLOCKS_PER_SEC << endl; waitKey(); return 0;}
OpenCV4 代码实现
以下是基于OpenCV4的相应更新版本。
#include#include #define PI 3.1415926using namespace std;using namespace cv;void fillHole(const Mat& srcBw, Mat& dstBw) { Size mSize = srcBw.size(); Mat Temp(mSize.height + 2, mSize.width + 2, srcBw.type()); srcBw.copyTo(Temp(Range(1, mSize.height + 1), Range(1, mSize.width + 1))); floodFill(Temp, Point(0, 0), Scalar(255)); Mat cutImg = Temp(Range(1, mSize.height + 1), Range(1, mSize.width + 1)).copyTo(cutImg); dstBw = srcBw | (~cutImg);}int main() { Mat srcImg; srcImg = imread("1.jpg"); clock_t start = clock(); namedWindow("原图", 0); imshow("原图", srcImg); waitKey(1); cvtColor(srcImg, srcImage, COLOR_BGR2GRAY); srcImage = srcImage > 160; Mat vec_rgb; vec_rgb = Mat::zeros(srcImage.size(), CV_8UC1); medianBlur(srcImage, vec_rgb, 3); namedWindow("中值滤波", 0); imshow("中值滤波", vec_rgb); waitKey(1); Canny(vec_rgb, vec_rgb, 3, 9, 3); namedWindow("边缘检测", 0); imshow("边缘检测", vec_rgb); waitKey(1); Mat element = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(1, 1)); erode(vec_rgb, vec_rgb, element); fillHole(vec_rgb, vec_rgb); namedWindow("填充处理", 0); imshow("填充处理", vec_rgb); waitKey(1); vector contours; vector hierarchy; hierarchy.push_back(Vec4i(0, 0, 0, 0)); hierarchy.push_back(Vec4i(0, 0, 0, 0)); findContours(vec_rgb, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point(0, 0)); vector > contours_poly; vector boundRect; vector center; vector radius; for(int i = 0; i < contours.size(); i++) { vector approxContour; approxPolyDP(Mat(contours[i]), approxContour, 3, true); contours_poly.push_back(approxContour); boundRect.push_back(boundingRect(Mat(approxContour))); minEnclosingCircle(approxContour, center[i], radius[i]); Point zhongdian = center[i]; cout << "玉米(或大米)颗粒坐标" << zhongdian.x << "," << zhongdian.y << endl; } Mat drawing; drawing = Mat::zeros(vec_rgb.size(), CV_8UC3); for(int i = 0; i < contours.size(); i++) { Scalar color = (0, 0, 255); drawContours(drawing, contours_poly[i], i, color, 1, 8, hierarchy, 0, Point()); rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); circle(drawing, center[i], (int)radius[i], color, 2, 8, 0); } namedWindow("包围矩形和圆形", 0); imshow("包围矩形和圆形", drawing); waitKey(1); cout << "玉米(或大米)颗粒个数" << contours.size() << endl; clock_t end = clock(); cout << "运行时间:" << ((double)(end - start)) / CLOCKS_PER_SEC << endl; waitKey(); return 0;}
效果展示
以下为系统处理后的效果图示,展示了玉米颗粒在不同预处理和处理阶段的变化:
原图:图片显示原始玉米颗粒图像,包含背景干扰和多方面的光照反射。
中值滤波:中值滤波后图像更清晰,突出了玉米颗粒的轮廓和边缘。
边缘检测:Canny边缘检测后,图像呈现出玉米颗粒的清晰边缘,有助于后续处理。
膨胀和腐蚀:通过膨胀和腐蚀操作,进一步优化了图像细节,提升了后续算法的鲁棒性。
填充处理:填充处理消除掉背景空洞,确保后续轮廓提取的准确性。
最终计数:系统输出展示了包围每颗玉米颗粒的最小矩形、圆形以及颗粒坐标,完成了高精度的计数任务。
总结
通过上述技术处理,系统实现了对玉米颗粒的高效、准确计数,具备较强的鲁棒性和适应性。代码基于OpenCV框架,兼容两大版本,适用于不同开发环境。该系统在禾场作业中的应用效果显著,能够快速高效地完成玉米或其他谷物的颗粒计数任务。
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年04月08日 23时36分11秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
反射机制
2019-03-11
反射Field、Method、Constructor
2019-03-11
可变长度参数
2019-03-11
类加载器子系统
2019-03-11
堆空间常用参数总结
2019-03-11
逃逸分析-堆分配对象
2019-03-11
常量池、运行时常量池
2019-03-11
GC算法
2019-03-11
3、条件查询
2019-03-11
5、分组函数 / 聚合函数
2019-03-11
8、子查询
2019-03-11
cordova打包apk更改图标
2019-03-11
开启与配置SMTP服务器
2019-03-11
postman基本使用方法
2019-03-11
域名解析步骤
2019-03-11
APP卡片式设计
2019-03-11
1.普通注册界面(html)(转载于JavaWeb应用开发与实践)
2019-03-11
GitHub上传时,项目在已有文档时直接push出现错误解决方案
2019-03-11
云数据库
2019-03-11
图计算
2019-03-11