opencv 火灾检测

来源:互联网 发布:见字如面第二季 知乎 编辑:程序博客网 时间:2024/06/11 09:44

采用了一个模型, 这个模型是看别人的代码实现的。


感谢http://tieba.baidu.com/p/3116037207?pid=52443907177&cid=0#52443907177, 我提取了他的代码的核心部分, 并加了一些注释。


以下是代码:h文件:

#include<opencv\highgui.h>#include<opencv\cv.h> using namespace cv;class ProcessImage{public:ProcessImage(void);~ProcessImage(void);static IplImage* Process(IplImage* img);  //图像处理};

cpp文件:

#include "ProcessImage.h"IplImage* imgToShow;CvMemStorage * storage = cvCreateMemStorage(0);  CvSeq * contour = 0; ProcessImage::ProcessImage(void){}ProcessImage::~ProcessImage(void){}//An Early Fire-Detection Method Based on Image Processing// 检测火焰// 要求, (1)R>RT   (2)R>=G>=B   (3)S>=( (255-R) * ST / RT )// RGB为红绿蓝值, S为饱和度// RT为红色阈值, ST为饱和度阈值 IplImage* ProcessColorModel(IplImage *RGBimg){IplImage * pImgFire = cvCreateImage(cvSize(RGBimg->width,RGBimg->height), IPL_DEPTH_8U, 3);IplImage *dst = cvCreateImage( cvGetSize(RGBimg), IPL_DEPTH_8U, 1 );cvSet(pImgFire, cvScalar(0,0,0),0);int RedThreshold=115;  //115~135 int SaturationThreshold=55;  //55~65for(int j = 0;j < RGBimg->height;j++){for (int i = 0;i < RGBimg->widthStep;i+=3){uchar B = (uchar)RGBimg->imageData[j*RGBimg->widthStep+i];uchar G = (uchar)RGBimg->imageData[j*RGBimg->widthStep+i+1];uchar R = (uchar)RGBimg->imageData[j*RGBimg->widthStep+i+2];uchar maxv=max(max(R,G),B); uchar minv=min(min(R,G),B); double S = (1 - 3.0*minv/(R+G+B));//(1)R>RT   (2)R>=G>=B   (3)S>=( (255-R) * ST / RT )if( R>RedThreshold && R>=G && G>=B && S>0.20 && S>(255-R)/20  &&S>=((255-R)*SaturationThreshold/RedThreshold)){pImgFire->imageData[i+RGBimg->widthStep*j] = 255;pImgFire->imageData[i+1+RGBimg->widthStep*j] = 255;pImgFire->imageData[i+2+RGBimg->widthStep*j] = 255;}else{pImgFire->imageData[i+RGBimg->widthStep*j] = 0;pImgFire->imageData[i+1+RGBimg->widthStep*j] = 0;pImgFire->imageData[i+2+RGBimg->widthStep*j] = 0;}}}cvCvtColor(pImgFire,dst,CV_BGR2GRAY);cvReleaseImage(&pImgFire);return dst;}// Find contourvoid FindContours( IplImage* dst ){cvFindContours(dst,storage,&contour,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);//cvRectangle(imgToShow,cvPoint(137,117),cvPoint(200,200),cv::Scalar(255,0,0),2);if(contour)cvDrawContours(dst,contour,cvScalarAll(255),cvScalarAll(255),100);   //画轮廓//cvShowImage("Contours",dst);CvMoments m;CvMat mat;double M00;CvSeq*contour2=contour;IplImage *pTmp=cvCreateImage(cvGetSize(dst),IPL_DEPTH_8U,1);cvSet(pTmp, cvScalar(0,0,0),0);IplImage *pTmp1=cvCreateImage(cvGetSize(dst),IPL_DEPTH_8U,1);cvSet(pTmp1, cvScalar(0,0,0),0);for(;contour2!=0;contour2=contour2->h_next){ CvRect rect=cvBoundingRect(contour2); //得到边界的矩形框cvDrawContours(pTmp,contour2,CV_RGB(255,255,255),CV_RGB(255,255,255),-1, 1, 8);cvRectangle(pTmp,cvPoint(rect.x,rect.y),cvPoint(rect.x+rect.width,rect.y+rect.height),CV_RGB(255,255,255),3,CV_AA,0);int n=contour->total;CvRect r=((CvContour*)contour2)->rect;CvPoint2D32f center;cvMoments(cvGetSubRect(pTmp,&mat,r),&m,0);M00=cvGetSpatialMoment(&m,0,0);center.x=cvGetSpatialMoment(&m,1,0)/M00; //重心为(centerx.+r.x,center.y+r.y)center.y=cvGetSpatialMoment(&m,0,1)/M00;double nHalfW,nHalfH;nHalfW=center.x<(r.width-center.x)?center.x:(r.width-center.x);nHalfH=center.y<(r.height-center.y)?center.y:(r.height-center.y);cvDrawContours(pTmp1,contour2,CV_RGB(255,255,255),CV_RGB(255,255,255),-1, 1, 8);cvRectangle(pTmp1,cvPoint(center.x+r.x-nHalfW,center.y+r.y-nHalfH),cvPoint(center.x+r.x+nHalfW,center.y+r.y+nHalfH),CV_RGB(255,255,255),3,CV_AA,0);cvRectangle(imgToShow,cvPoint(center.x+r.x-nHalfW,center.y+r.y-nHalfH),cvPoint(center.x+r.x+nHalfW,center.y+r.y+nHalfH),CV_RGB(107,180,229),3,CV_AA,0);//cvSaveImage("contoursss.bmp",pTmp);//cvSaveImage("contoursss1.bmp",pTmp1);//MessageBox(FindWindow("CFireDetectionApp","FireDetection"),"find!","1122",MB_OK);}cvReleaseImage(&pTmp);cvReleaseImage(&pTmp1);}IplImage* ProcessImage::Process(IplImage* img){//cvRectangle(img,cvPoint(137,117),cvPoint(200,200),cv::Scalar(255,0,0),2);//dst = process_rgb(img);//cvSaveImage("temp.jpg",temp2);imgToShow = img;IplImage* dst = ProcessColorModel(img);// 具体做检测// 现在的到的是一些列的点// 要把他们变成区域//cvSmooth(dst, dst, CV_GAUSSIAN,15,15,0,0); //滤波cvSmooth(dst, dst, CV_BLUR,15,15,0,0); //滤波cvThreshold( dst, dst, 60, 255, CV_THRESH_BINARY);cvSmooth(dst, dst, CV_MEDIAN, 15, 15 ,0 ,0);cvErode(dst, dst, 0, 1);//cvSaveImage("fushi.jpg",dst);cvDilate(dst, dst, 0, 1);//cvSaveImage("penzhang.jpg",dst);//IplImage* dst = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);//cvSet(dst,cvScalar(0),0);初始化图片函数 // 找到区域// 画一个框FindContours(dst);cvReleaseImage(&dst);return imgToShow;}

main

文件:

#include "ProcessImage.h"int main(){// 读取图片IplImage* img = cvLoadImage("1.jpg");// 检测图片IplImage* fireImage = ProcessImage::Process(cvCloneImage(img));// 显示cvNamedWindow("src", CV_WINDOW_AUTOSIZE);cvNamedWindow("dst", CV_WINDOW_AUTOSIZE);cvShowImage("src", img);cvShowImage("dst", fireImage);cvWaitKey(0);// 释放内存cvReleaseImage(&img);cvReleaseImage(&fireImage);cvDestroyAllWindows();return 0;}

效果:


0 0
原创粉丝点击