上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域。火焰提取要用
到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据——RGB判据。 在介绍这个判据之前,博主首先给大家简单介绍一下RGB模型。根据三基色原理,用基色光单位来表示光的量,则在RGB颜色空间,任意色光F都可
以用R、G、B三色不同分量的相加混合而成: F=r[R]+g[G]+b[B] 当三基色分量都为0(最弱)时混合为黑色光;当三基色分量都为k(最强)时混合为白。改变了F的坐标值,也即改变了F的色值。

    人眼的视网膜上有两类感光器:锥状体和杆状体。锥状体主要位于视网膜的中间部分,称之为中央凹,且对颜色高度敏感,称为白昼视觉或亮视觉;
杆状体分布面积较大,用来给出视野内的一般的总体图像,没有彩色感觉,而对低照明度敏感,称为微光视觉或暗视觉。由于锥状体对红、绿、蓝三种
颜色的光很敏感,因此一般用于人眼观看的颜色模型是RGB模型。一般来说,无论是在网上下载的图片或视频,还是从摄像机得来的录像,都是RGB
模型。所以,我们从网上下载了一幅火焰图像,不用进行任何的颜色模型转换就可以使用RGB颜色判据来提取区域。 对于普通的火焰来说,它的红色分量和绿色分量会很大,并且绿色分量会大于蓝色分量,所以我们设下的简单判据是:
R > R_avg AND
G > G_avg AND
R > G > B
其中,R_avg为红色分量的均值。
在OpenCV1.0中实现很简单,下面先摆出代码:
int cvBGR_CHK(IplImage*img_bgr, IplImage*bgr_chk){
if (img_bgr == NULL || bgr_chk == NULL){
printf("func cvBGR_CHK Error:\n");
printf("img_bgr == NULL || bgr_chk == NULL\n");
return -1;
}
if (img_bgr->nChannels != 3 || bgr_chk->nChannels != 1){
printf("func cvBGR_CHK Error:\n");
printf("img_bgr->nChannels != 3 || bgr_chk->nChannels != 1\n");
return -1;
}
CvScalar avg;
avg = cvAvg(img_bgr);
CvSize size = cvGetSize(img_bgr);
IplImage*R = cvCreateImage(size, 8, 1);
IplImage*G = cvCreateImage(size, 8, 1);
IplImage*B = cvCreateImage(size, 8, 1);
IplImage*tmp1 = cvCreateImage(size, 8, 1);
IplImage*tmp2 = cvCreateImage(size, 8, 1);
cvSplit(img_bgr, B, G, R, NULL);
cvCmpS(R, avg.val[2], tmp1, CV_CMP_GT);
cvCmpS(G, avg.val[1], tmp2, CV_CMP_GT);
cvMul(tmp1, tmp2, tmp1);
cvCmp(R, G, tmp2, CV_CMP_GT);
cvCmp(G, B, G, CV_CMP_GT);
cvMul(tmp2, G, tmp2);
cvMul(tmp1, tmp2, tmp1);
cvConvertScale(tmp1, bgr_chk, 1.0 / 255);
cvReleaseImage(&R);
cvReleaseImage(&G);
cvReleaseImage(&B);
cvReleaseImage(&tmp1);
cvReleaseImage(&tmp2); return 0;
}
   函数cvBGR_CHK的功能是实现图像的RGB检测,把符合RGB判据的素点置为1,否则置为0,返回的是只有0和1的二值化模板。

对于写代码的习惯,博主在这里说一下闲话。有些人可能觉得上面函数的格式有点奇怪,特别是返回值,有什么卵用?我的C++老师曾经说过,在做
项目的时候,较为复杂的函数一般不要把返回值作为输出结果。什么意思呢?众所周知,函数返回值只有一个,若想返回两个值或者更多个,用这种
方法就行不通了。对于返回两个或更多个值的函数,在C语言中在输入变量后面,这样就可以轻轻松松地输出两个值。那么返回值不就可以写出void
型的吗?我们的确可以使用void,但是你们想一下,在一个大项目中,往往不止一个函数,那如果运行起来报错了,那么应该怎么找错呢?用断点找?
定位到具体函数要花一定的时间;用编译器自带的检错工具?往往输出并没有什么卵用的信息。如果我们在每个函数里面设定一个对输入输出变量的异
常情况进行自动报错的功能,就会大大简化查错的程序。比如说,在上面的函数中,把检错语句屏蔽掉,我分配给输出变量的内存有三个通道,那么函
数执行肯定会报错,那么我们可不可以简简单单地从系统报错的信息中解决问题呢?首先,我们先运行一把,看看报错信息是啥。 Unhandled exception at 0x75D3D3CF in FireDectect.exe: Microsoft C++ exception: cv::Exception at memory location 0x0023F3A8. 有谁可以看出是哪里出了问题吗?反正我不能。再点一下“中断”按钮有木有好的提示?

    ……什么鬼?
所以说,返回简单的错误信息很重要吧。如果取消屏蔽,那么就会输出: func cvBGR_CHK Error:
img_bgr->nChannels != 3 || bgr_chk->nChannels != 1 那我们可以很快解决木有?
所以,博主做项目的时候都会采用这种习惯来写函数,这样会大大节省查找低级错误的时间。
闲话就说到这里,下面我们来检测一下图片看看效果如何:

 

    更多的检测就不在这里重复了,或者有些情况效果不是很好,但要记住,这只是众多判据的其中一个,我们可以两三个判据结合来更精确地提
取区域,这就是以后要分享的东西了。
今天就分享到这里~欢迎大家多来评论,来找出博主可能存在的错误,希望能和各位图像爱好者共同成长~以后更新会更频繁,大家要继续关注噢~
那么我们下次见~ 下文预告:基于OpenCV的火焰检测(三)——HSI颜色判据

基于OpenCV的火焰检测(二)——RGB颜色判据的更多相关文章

  1. 基于OpenCV的火焰检测(一)——图像预处理

    博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测.在做这个项目的时候,博主参考了很多相关的文献,用了很多种 ...

  2. 基于OpenCV的火焰检测(三)——HSI颜色判据

    上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据--HSI判据. 为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型: HSI颜 ...

  3. 基于Opencv识别,矫正二维码(C++)

    参考链接 [ 基于opencv 识别.定位二维码 (c++版) ](https://www.cnblogs.com/yuanchenhui/p/opencv_qr.html) OpenCV4.0.0二 ...

  4. 基于OpenCv的人脸检测、识别系统学习制作笔记之一

    基于OpenCv从视频文件到摄像头的人脸检测 在OpenCv中读取视频文件和读取摄像头的的视频流然后在放在一个窗口中显示结果其实是类似的一个实现过程. 先创建一个指向CvCapture结构的指针 Cv ...

  5. 基于OpenCv的人脸检测、识别系统学习制作笔记之二

    在网上找到了一个博客,里面有大量内容适合初学者接触和了解人脸检测的博文,正好符合我目前的学习方面,故将链接放上来,后续将分类原博客的博文并加上学习笔记. 传送门: http://blog.sina.c ...

  6. 【AdaBoost算法】基于OpenCV实现人脸检测Demo

    一.关于检测算法 分类器训练: 通过正样本与负样本训练可得到分类器,opencv有编译好的训练Demo,按要求训练即可生成,这里我们直接使用其已经训练好的分类器检测: 检测过程: 检测过程很简单,可以 ...

  7. 基于Opencv的人脸检测及识别

    一.实验目的:我这里完成的是,将8张人脸图片(4组,每组两张)存入库中,选取1张图片,程序识别出与其匹配的另一张. 这里介绍分三个步骤完成该工作,①程序读取摄像头.拍照 ②程序从电脑文档中读取图片   ...

  8. 基于OpenCv的人脸检测、识别系统学习制作笔记之三

    1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...

  9. 基于opencv 识别、定位二维码 (c++版)

    前言 因工作需要,需要定位图片中的二维码:我遂查阅了相关资料,也学习了opencv开源库.通过一番努力,终于很好的实现了二维码定位.本文将讲解如何使用opencv定位二维码. 定位二维码不仅仅是为了识 ...

随机推荐

  1. java创建多线程的三种方式

    /***************************继承Thread类创建多线程************************/ public class FirstThread extends ...

  2. QMouseEvent 的坐标__Win

    1. QMouseEvent.x() 和 QMouseEvent.y() 是窗口里面的坐标,相当于 Windows API 里面的 ClientX和ClientY . 2. QMouseEvent.G ...

  3. Bellman-Ford算法 O(NE)

    Bellman-Ford算法 O(NE) 思路:枚举n-1次所有边,通过枚举所有边,将所有和已知点相连的点都设为已知,初始时起点为已知点. ;i<=n-;i++){ //n-1是次数,枚举n-1 ...

  4. django 添加自定义context

    文档参考;http://python.usyiyi.cn/django_182/ref/templates/api.html 添加自定义上下文文件custom_processors.py # codi ...

  5. GridRegionAdapter(slivelight)

    原地址:http://www.xuebuyuan.com/68722.html Prism学习之SilverlightWindowRegionAdapter[0评] 文章作者: healer 文章分类 ...

  6. 关于JAVA一些知识的了解

    一.枚举类型 示例代码: public class EnumTest { public static void main(String[] args){   Size s=Size.SMALL;   ...

  7. 51 nod 1091 贪心

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1091 1091 线段的重叠 基准时间限制:1 秒 空间限制:131072 ...

  8. Oracle Index Clustering Factor(集群因子)

    一.本文说明: 今天在做测试的时候发现字段上有索引,但是执行计划就是不走索引,经过在网上查找才发现原来是索引的集群因子过高导致的.本文属于转载 二.官网说明 The index clustering ...

  9. ios --- 调用系统"设置"里的功能(转)

    安装后第一次运行软件时,系统会弹出提示用户是否允许软件获取当前位置,如果用户不允许的话,之后运行时系统不会在弹出提示设置,这点很不方便,有个解决办法是给用户一个选项,调出iphone中“设置”定位服务 ...

  10. Redis 高可用及分片集群,说了你也不懂

    Redis 简介 Memcached: 优点:高性能读写.单一数据类型.支持客户端式分布式集群.一致性hash 多核结构.多线程读写性能高. 缺点:无持久化.节点故障可能出现缓存穿透.分布式需要客户端 ...