opencv4学习笔记(4)-鸡窝鸡蛋计数即相关参数心得

文章目录

  1. 预计效果
  2. 效果演示
  3. 实现过程
  4. 程序
  5. 参数调试笔记

1.预计效果

能够从杂乱背景的鸡窝中找出鸡蛋并且计算鸡蛋的数量。

2.效果演示

3. 实现过程

  1. blur均值滤波,让画面变得平滑一些。

  2. canny边缘检测,将边缘二值化展示出来。
    opencv4学习笔记(4)-鸡窝鸡蛋计数即相关参数心得_第1张图片

  3. morphologyEx形态学闭操作,调整kernel卷积和大小,消除一些比较小的黑块,这样留下来的都是一些较大大的黑块。
    opencv4学习笔记(4)-鸡窝鸡蛋计数即相关参数心得_第2张图片
    4.findContours找出所有的闭合轮廓。
    5.可以看出鸡蛋的伦托和噪点的轮廓大小有明显差别,通过限定轮廓的大小,来判断出那些轮廓属于鸡蛋,从而框选出鸡蛋并进行计数。

4. 程序

void Demo::egg_count()
{
	namedWindow("egg", WINDOW_NORMAL);
	Mat src = imread("D:/DESKTOP/picture/egg.jpg");
	Mat src1;
	blur(src, src1, Size(5, 5),Point(-1,-1),BORDER_DEFAULT);//均值滤波
	cvtColor(src1, src1, COLOR_BGR2GRAY);
	Canny(src1, src1, 25, 35, 3, false);//canny边缘检测
	imshow("边缘", src1);
	Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5), Point(-1, -1));//椭圆形5x5内核
	morphologyEx(src1, src1, MORPH_CLOSE, kernel, Point(-1, -1), 3);//形态学闭操作
	imshow("形态学闭操作", src1);
	vector<vector<Point>> contours;
	vector<Vec4i> hireachy;
	findContours(src1, contours, hireachy, RETR_TREE, CHAIN_APPROX_NONE, Point());//找出所有轮廓
	cvtColor(src1, src1, COLOR_GRAY2BGR);
	int egg = 0;
	for (int i = 0; i < contours.size(); i++)//通过大小限定计算出鸡蛋的轮廓
	{
		Rect rect = boundingRect(contours[i]);
		if (rect.width > src1.cols/15 && rect.width < src1.cols - 20&&rect.height>src1.rows/15) {
			drawContours(src, contours, static_cast<int>(i), Scalar(0, 0, 255), 2, 8, hireachy, 0, Point());
			egg++;
		}
		
	}
	putText(src, "eggs:"+to_string(egg),Point(0,100), FONT_HERSHEY_PLAIN, 5, Scalar(0, 255, 255), 2, 8, false);
	imshow("egg", src);
	waitKey(0);
}

5.参数调试笔记

  1. 第一步blur滤波可以减少canny检测出来的边缘的数量,如图是没有家均值滤波的:
    opencv4学习笔记(4)-鸡窝鸡蛋计数即相关参数心得_第3张图片
    2.canny边缘检测的两个阈值设置,如果过高,可能会导致连鸡蛋都检测不出来,过低会导致边缘过多。
    3.kernel这里选用的是椭圆内核,出来的闭合曲线也有点椭圆的形状了。内核的大小不要选太小了,不然会检测出来过多的闭合曲线(虽然通过最后的大小限定也能过滤掉)。
    4.最后的鸡蛋大小要选着一个合适的范围,能够包括鸡蛋,也能排除噪点。

你可能感兴趣的:(opencv学习笔记,opencv,计算机视觉,边缘检测)