OpenCV_火焰检测——完整代码

转:http://blog.csdn.net/xiao_lxl/article/details/43307993

火焰检测小程序

前几天,偶然看到了An Early Fire-Detection Method Based on Image Processing ,The Author is:Thou-Ho (Chao-Ho) Chen, Ping-Hsueh Wu, and Yung-Chuen Chiou

这篇文章,参照他的颜色模型做了一个火焰检测的小程序,以此记录并与大家分享。

针对视频,若是加上火焰背景建模,效果会更好。有兴趣的可以试一下。

检测图片为:

检测效果图为:

程序代码附下:

 

 

  1. int main()  
  2. {  
  3.     string filepath = "F:\\video\\fire\\fire0.jpg";  
  4.     Mat inputImg = imread(filepath,1);  
  5.       
  6.     CheckColor(inputImg);  
  7.     return 0;  
  8. }  
  9. //////////////////////////////////  
  10. //The Color Check is According to "An Early Fire-Detection Method Based on Image Processing"  
  11. //The Author is:Thou-Ho (Chao-Ho) Chen, Ping-Hsueh Wu, and Yung-Chuen Chiou  
  12. //////////////////////////////////////  
  13. Mat CheckColor(Mat &inImg)  
  14. {  
  15.     Mat fireImg;  
  16.     fireImg.create(inImg.size(),CV_8UC1);  
  17.       
  18.     int redThre = 115; // 115~135  
  19.     int saturationTh = 45; //55~65  
  20.     Mat multiRGB[3];  
  21.     int a = inImg.channels();  
  22.     split(inImg,multiRGB); //将图片拆分成R,G,B,三通道的颜色  
  23.   
  24.     for (int i = 0; i < inImg.rows; i ++)  
  25.     {  
  26.         for (int j = 0; j < inImg.cols; j ++)  
  27.         {  
  28.             float B,G,R;  
  29.             B = multiRGB[0].at<uchar>(i,j); //每个像素的R,G,B值  
  30.             G = multiRGB[1].at<uchar>(i,j);  
  31.             R = multiRGB[2].at<uchar>(i,j);     
  32.   
  33.             /*B = inImg.at<uchar>(i,inImg.channels()*j + 0); //另一种调用图片中像素RGB值的方法 
  34.             G = inImg.at<uchar>(i,inImg.channels()*j + 1); 
  35.             R = inImg.at<uchar>(i,inImg.channels()*j + 2);*/  
  36.   
  37.             int maxValue = max(max(B,G),R);  
  38.             int minValue = min(min(B,G),R);  
  39.   
  40.             double S = (1-3.0*minValue/(R+G+B));  
  41.   
  42.             //R > RT  R>=G>=B  S>=((255-R)*ST/RT)  
  43.             if(R > redThre && R >= G && G >= B && S >0.20 && S >((255 - R) * saturationTh/redThre))  
  44.             {  
  45.                 fireImg.at<uchar>(i,j) = 255;  
  46.             }  
  47.             else  
  48.             {  
  49.                 fireImg.at<uchar>(i,j) = 0;  
  50.             }  
  51.         }  
  52.     }  
  53.   
  54.     dilate(fireImg,fireImg,Mat(5,5,CV_8UC1));  
  55.     imshow("fire",fireImg);  
  56.     waitKey(0);  
  57.   
  58.     DrawFire(inImg,fireImg);  
  59.       
  60.     return fireImg;  
  61. }  
  62.   
  63. void DrawFire(Mat &inputImg,Mat foreImg)  
  64. {  
  65.     vector<vector<Point>> contours_set;//保存轮廓提取后的点集及拓扑关系  
  66.   
  67.     findContours(foreImg,contours_set,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);     
  68.   
  69.     Mat result0;  
  70.     Scalar holeColor;  
  71.     Scalar externalColor;  
  72.   
  73.     vector<vector<Point> >::iterator iter = contours_set.begin() ;  
  74.     for(; iter!= contours_set.end(); )  
  75.     {  
  76.         Rect rect = boundingRect(*iter );  
  77.         float radius;    
  78.         Point2f center;    
  79.         minEnclosingCircle(*iter,center,radius);    
  80.           
  81.         if (rect.area()> 0)        
  82.         {  
  83.   
  84.             rectangle(inputImg,rect,Scalar(0,255,0));     
  85.             ++ iter;  
  86.   
  87.         }  
  88.         else  
  89.         {  
  90.             iter = contours_set.erase(iter);  
  91.         }  
  92.     }  
  93.   
  94.     imshow("showFire",inputImg);  
  95.     waitKey(0);  
  96. }  
int main()
{
	string filepath = "F:\\video\\fire\\fire0.jpg";
	Mat inputImg = imread(filepath,1);
	
  	CheckColor(inputImg);
	return 0;
}
//////////////////////////////////
//The Color Check is According to "An Early Fire-Detection Method Based on Image Processing"
//The Author is:Thou-Ho (Chao-Ho) Chen, Ping-Hsueh Wu, and Yung-Chuen Chiou
//////////////////////////////////////
Mat CheckColor(Mat &inImg)
{
	Mat fireImg;
	fireImg.create(inImg.size(),CV_8UC1);
	
	int redThre = 115; // 115~135
	int saturationTh = 45; //55~65
	Mat multiRGB[3];
	int a = inImg.channels();
	split(inImg,multiRGB); //将图片拆分成R,G,B,三通道的颜色

	for (int i = 0; i < inImg.rows; i ++)
	{
		for (int j = 0; j < inImg.cols; j ++)
		{
			float B,G,R;
			B = multiRGB[0].at<uchar>(i,j); //每个像素的R,G,B值
			G = multiRGB[1].at<uchar>(i,j);
			R = multiRGB[2].at<uchar>(i,j);	

			/*B = inImg.at<uchar>(i,inImg.channels()*j + 0); //另一种调用图片中像素RGB值的方法
			G = inImg.at<uchar>(i,inImg.channels()*j + 1);
			R = inImg.at<uchar>(i,inImg.channels()*j + 2);*/

			int maxValue = max(max(B,G),R);
			int minValue = min(min(B,G),R);

			double S = (1-3.0*minValue/(R+G+B));

			//R > RT  R>=G>=B  S>=((255-R)*ST/RT)
			if(R > redThre && R >= G && G >= B && S >0.20 && S >((255 - R) * saturationTh/redThre))
			{
				fireImg.at<uchar>(i,j) = 255;
			}
			else
			{
				fireImg.at<uchar>(i,j) = 0;
			}
		}
	}

	dilate(fireImg,fireImg,Mat(5,5,CV_8UC1));
	imshow("fire",fireImg);
	waitKey(0);

	DrawFire(inImg,fireImg);
	
	return fireImg;
}

void DrawFire(Mat &inputImg,Mat foreImg)
{
	vector<vector<Point>> contours_set;//保存轮廓提取后的点集及拓扑关系

	findContours(foreImg,contours_set,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);	

	Mat result0;
	Scalar holeColor;
	Scalar externalColor;

	vector<vector<Point> >::iterator iter = contours_set.begin() ;
	for(; iter!= contours_set.end(); )
	{
		Rect rect = boundingRect(*iter );
		float radius;  
		Point2f center;  
		minEnclosingCircle(*iter,center,radius);  
		
		if (rect.area()> 0)		
		{

			rectangle(inputImg,rect,Scalar(0,255,0));	
			++ iter;

		}
		else
		{
			iter = contours_set.erase(iter);
		}
	}

	imshow("showFire",inputImg);
	waitKey(0);
}

 

另附几个其他的效果图:

posted @ 2016-08-11 21:47  lhuan  阅读(7803)  评论(1编辑  收藏  举报