opencv 扬尘识别

去年的时候做了个工地扬尘的项目,起步的时候是先做了识别一张图里的扬尘的工作,用的算法不麻烦,主要是分水岭的算法,两篇博文把分水岭讲的太好了,分享给大家

http://www.cnblogs.com/mikewolf2002/p/3304118.html

http://blog.sciencenet.cn/blog-733228-578509.html

今年找出来了,当时还是用C写的,太跟不上时代了,毕竟opencv已经不提倡那种方式了,改了改换成C++的封装,因为当时要给师弟们看,所以注释写的已经很详细了(我自认为)。给大家提供一种思路,共同进步学习~~~

#include "stdafx.h"
#include 
using namespace cv;
int main()
{
	Mat g_midimage,himg,simg,vimg,tmpimage,binary_image;
	Mat g_srcimage=imread("6.jpg");//读图片
	cvtColor(g_srcimage,g_midimage,COLOR_BGR2HSV);//RGB转HSV
	
	vector hsv;
	//split three channels
	split(g_midimage,hsv);//分离HSV三通道,分成三张图片
	himg=hsv[0];
	simg=hsv[1];
	vimg=hsv[2];




	//二值化H,S,V图像  
	for (int i=0;i(i,j);
			if ((hvalue>0&&hvalue<30)||(hvalue>170&&hvalue<180))//当H图像像素值在0~30和170~180范围内时,得到为白色否则为黑,下面相同。
			   himg.at(i,j)=255;
			else
				himg.at(i,j)=0;

			
		}
	}
	for (int i=0;i(i,j);
			if ((svalue>0&&svalue<20)||(svalue>50&&svalue<100))
				simg.at(i,j)=255;
			else
				simg.at(i,j)=0;


		}
	}
	for (int i=0;i(i,j);
			if (vvalue>170&&vvalue<220)
				vimg.at(i,j)=255;
			else
				vimg.at(i,j)=0;


		}
	}
	//将三通道合并,最终得到二值化图像binary_image
	bitwise_and(himg,simg,tmpimage);
	bitwise_and(tmpimage,vimg,binary_image);
	imshow("binary",binary_image);

	//腐蚀操作得到前景图片,腐蚀6次
	Mat fg;
	erode(binary_image,fg,Mat(),Point(-1,-1),6);

	//显示前景图片
	imshow("foreground",fg);


	//膨胀操作,膨胀6次
	Mat bg;
	dilate(binary_image,bg,Mat(),Point(-1,-1),6);
	//将膨胀的图片阈值化操作,得到背景图片,
	threshold(bg,bg,1,128,THRESH_BINARY_INV);
	//显示背景图片
	imshow("background",bg);
	//将前景和背景图片相加,得到掩膜图片
	Mat markers(binary_image.size(),CV_8U,Scalar(0));
		markers=fg+bg;
	imshow("markers",markers);
	//分水岭函数的掩膜必须是32位的,故将八位图片转化成32位图片,进行分水岭操作,结果存在markers中
	markers.convertTo(markers,CV_32S);
	watershed(g_srcimage,markers);

	//将得到的markers图片转化成八位图片
	Mat tmp;
	markers.convertTo(tmp,CV_8U);
	
	//像素统计,逐行统计,计算白色区域的像素和
	double pixekcount=0.,blackcount=0.;
	for (int i=0;i(i,j);
			if(gvalue==255)
				blackcount++;
		}

	}
	//计算白色区域的比例
	double scale_img;
	scale_img=blackcount/pixekcount;
	//大于0.05则在图上打上有问题的标签
	if(scale_img>0.05)
	{
		putText(tmp,"have question",Point(0,10),3,0.3,Scalar(255,0,0));//打印函数
	    imshow("segment",tmp);//显示有问题的图片,按计划这里应该是传图片或者存图片
		printf( "1!!!");//发送有问题信号,我是打印出来方便观察的
	}
	else
		printf( "0");//没有问题信号


	imshow("segment",tmp);//显示最终的图片

	waitKey(0);
	return 0;

	
}


下图是识别的结果,还比较理想,我们试了很多个图,多数情况能比较好的搞定问题。

opencv 扬尘识别_第1张图片 opencv 扬尘识别_第2张图片

你可能感兴趣的:(opencv)