人工智能学习笔记之计算机视觉(二)——米粒分割算法



前言

C++


提示:以下是本篇文章正文内容,下面案例可供参考

一、基于大津算法

//米粒分割算法
void ImageSmoothHandle::riceDetection()
{
	Mat oImg, imageOutput, imageOtsu;
	string fp = "../resource/米粒图片.png";//相对路径,相对.cpp 文件的路径
	oImg = readImageV2(fp);
	//imshow("rice Img",oImg);

	Mat gray, dist, element, dist2;
	//图像预处理
	cvtColor(oImg, gray, CV_RGB2GRAY);//预处理错误将导致内存错误
    //imshow("gray", gray);
	//waitKey();
    //使用局部阈值得大津算法进行图像的二值化
    //参数1:InputArray类型的src,输入图像,填单通道,单8位浮点类型Mat即可
    //参数2:函数运算后的结果存放在这。即为输出图像(与输入图像同样的尺寸和类型)。
	//参数3:预设满足条件的最大值。
    //参数4:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。(具体见下面的解释)。
	//参数5:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
	//参数6:表示邻域块大小,用来计算区域阈值,一般选择为3、5、7......等。
	//参数7:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。(具体见下面的解释)。
	adaptiveThreshold(gray, dist, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 17, 0);
	imshow("threshold", dist);
	//waitKey();

	//函数会返回指定形状和尺寸的结构元素
	//第一个参数表示内核的形状,有三种形状可以选择
	//矩形:MORPH_RECT;
	//交叉形:MORPH_CORSS;
	//椭圆形:MORPH_ELLIPSE;
	//第二和第三个参数分别是内核的尺寸以及锚点的位置。
	element = getStructuringElement(MORPH_RECT, Size(3, 3));
	//imshow("shap", element);
	//waitKey();

	//开运算:
	//先腐蚀,再膨胀,可清除一些小东西(亮的),放大局部低亮度的区域 
	//闭运算:
		//先膨胀,再腐蚀,可清除小黑点
	//形态学梯度:
		//膨胀图与腐蚀图之差,提取物体边缘
	//顶帽:
		//原图像 - 开运算图,突出原图像中比周围亮的区域
	//黑帽:
		//闭运算图 - 原图像,突出原图像中比周围暗的区域
	//imshow("ddd", dist);
	//waitKey();
	morphologyEx(dist, dist2, MORPH_OPEN, element);
	//imshow("sss", dist2);
	//waitKey();


	//Mat temp;

	//IplConvKernel * myModel;
	//函数中参数cols,rows确定了构造的矩形大小。
	//anchor_x, anchor_y确定了封闭矩形内参考点的横纵坐标。
    //shape是自定义核的形状,具体为
    //1.CV_SHAPE_RECT  核是矩形
    //2.CV_SHAPE_CROSS 核是勺子交叉形
    //3.CV_SHAPE_ELLIPSE 核是椭圆形
    //4.CV_SHAPE_CUSTOM 核是用户自定义类型	
	//myModel = cvCreateStructuringElementEx(3, 3, 2, 2, CV_SHAPE_RECT);
	//参数分别为原图像,输出图像,temp临时图像,自定义核,形态学操作方法(CV_MOP_OPEN CV_MOP_CLOSE CV_MOP_GRADIENT CV_MOP_TOPHAT CV_MOP_BLACKHAT)
	//cvMorphologyEx(&dist, &dist2, temp,myModel, CV_MOP_OPEN, 1);
	//imshow("dj",temp);
	//cvShowImage("xxx", temp);
	//waitKey();


	Mat contours, hierarchy, seg;
	vector<vector<Point>>  cnts;

	//第一个参数:image,单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
	//第二个参数:contours,定义为“vector<vector<Point>> contours”,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。有多少轮廓,向量contours就有多少元素。
	//第三个参数:hierarchy,定义为“vector<Vec4i> hierarchy”;Vec4i是Vec<int,4>的别名,定义了一个“向量内每一个元素包含了4个int型变量”的向量
	//向量hiararchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。
	//hierarchy向量内每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果没有对应项,则相应的hierarchy[i]设置为负数。 
	//第四个参数:int型的mode,定义轮廓的检索模式:
	//取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略

	//取值二:CV_RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关
   //系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,
	//RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界 	
	//第五个参数:int型的method,定义轮廓的近似方法:
	//CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
    //CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息

	seg = dist2.clone();
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);//轮廓检测函数
	//drawContours(dist2, contours, -1, (120, 0, 0), 2);//绘制轮廓
	
	int count = 0;//米粒总数
	Rect rect;
	string strCount;

	double length;
	vector<vector<Point>> er;
	RotatedRect  minArea;
	Point p[100];
	for (int i = cnts.size() - 1; i >= 0; i--)
	{
		vector<Point> c = cnts[i];
		//计算整个轮廓或部分轮廓的面积
		double area = contourArea(c);
		 
		if (area < 10)//滤除面积小于10的分割结果,可能是噪声
			continue;
		count++;
		//cout << "blob" << i << ":" << area << endl;
		//rect = boundingRect(c);//计算轮廓包围矩形(水平的)
		minArea = minAreaRect(c);

		//boxPoints(minArea, er);
		//length = arcLength(er,true);
		rectangle(oImg, rect, Scalar(0, 0, 0xff), 1);//在原始图像上画出包围矩形,并给每个矩形标号
		
		stringstream ss;
		ss << count;
		ss >> strCount;
		putText(oImg, strCount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 0xff, 0));
		//waitKey();
		
	}
	cout << "米粒数量" << count << endl;
	imshow("原图", oImg);
	imshow("形态学去噪",dist2);
	waitKey();
}

原图: 

阈值: 

 

形态学去噪 (开运算)

 

 形态学去噪(闭运算)

待续。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值