在机器视觉中,有时需要对产品进行检测和计数。现在开源的方法有很多种,目的是追求更稳定,更高效的算法。
由于之前网购的维生素片,有时候忘了今天有没有吃过,就想对瓶子里的药片计数...在学习opencv以后,希望实现对于维生素片分割计数算法。本次实战在基于形态学的基础上又衍生出基于距离变换的分水岭算法,使其实现的效果更具普遍性。
基于形态学的维生素片检测和计数
??整体思路:
??细说形态学:
opencv实现:
int main(int argc, char** argv) { Mat src, src_binary,dst,src_distance; src = imread("D:/opencv练习图片/维生素片机器视觉检测和计数.png"); imshow("原图片", src); Mat kernel = getStructuringElement(MORPH_RECT, Size(16, 16), Point(-1, -1)); morphologyEx(src, dst, MORPH_OPEN, kernel); imshow("形态学",dst); cvtColor(dst, dst, COLOR_RGB2GRAY); threshold(dst, src_binary, 100, 255, THRESH_OTSU); imshow("二值化", src_binary); vector<vector<Point>> contours; findContours(src_binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0)); RNG rng(12345); double area; Point2i PL; for (size_t i = 0; i < contours.size(); i++) { area = contourArea(contours[i]); if (area < 500)continue; PL = contours[i].front(); Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(src, contours, i, color, 2, 8); putText(src, to_string(i), PL, FONT_HERSHEY_COMPLEX, 1, color, 2); } imshow("计数结果", src); waitKey(0); return 0; }
效果展示:
由上图可以看的,原图在经过形态学处理后,可以去除很多细节,简化后续的药片分割操作。
但是在计数结果图上发现,索引17号药片并没有完全分割(实际上修改形态学的结构元素尺寸(改为20*20)也可以完全分离这两个药片)。
??这不由得让我们思考,如果简单的形态学处理分割不了药片呢?(比如药片相互重叠)
因此对于复杂的产品图片,我们可以使用基于距离变换的分水岭算法对其分割。
基于距离变换的分水岭算法检测和计数
原文:https://www.cnblogs.com/xyf327/p/14772593.html