zoukankan      html  css  js  c++  java
  • 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);
    }

    另附几个其他的效果图:

  • 相关阅读:
    NOI Online 2020「Prelude」
    CF704E Iron Man
    luogu P4619 [SDOI2018]旧试题
    luogu P4207 [NOI2005]月下柠檬树
    JOI2020
    luogu P3263 [JLOI2015]有意义的字符串
    p1864
    p1824
    p1836
    p1862
  • 原文地址:https://www.cnblogs.com/lhuan/p/5762730.html
Copyright © 2011-2022 走看看