基于OpenCV的火焰检测(二)——RGB颜色判据
上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域。火焰提取要用
到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据——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颜色判据的更多相关文章
- 基于OpenCV的火焰检测(一)——图像预处理
博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测.在做这个项目的时候,博主参考了很多相关的文献,用了很多种 ...
- 基于OpenCV的火焰检测(三)——HSI颜色判据
上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据--HSI判据. 为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型: HSI颜 ...
- 基于Opencv识别,矫正二维码(C++)
参考链接 [ 基于opencv 识别.定位二维码 (c++版) ](https://www.cnblogs.com/yuanchenhui/p/opencv_qr.html) OpenCV4.0.0二 ...
- 基于OpenCv的人脸检测、识别系统学习制作笔记之一
基于OpenCv从视频文件到摄像头的人脸检测 在OpenCv中读取视频文件和读取摄像头的的视频流然后在放在一个窗口中显示结果其实是类似的一个实现过程. 先创建一个指向CvCapture结构的指针 Cv ...
- 基于OpenCv的人脸检测、识别系统学习制作笔记之二
在网上找到了一个博客,里面有大量内容适合初学者接触和了解人脸检测的博文,正好符合我目前的学习方面,故将链接放上来,后续将分类原博客的博文并加上学习笔记. 传送门: http://blog.sina.c ...
- 【AdaBoost算法】基于OpenCV实现人脸检测Demo
一.关于检测算法 分类器训练: 通过正样本与负样本训练可得到分类器,opencv有编译好的训练Demo,按要求训练即可生成,这里我们直接使用其已经训练好的分类器检测: 检测过程: 检测过程很简单,可以 ...
- 基于Opencv的人脸检测及识别
一.实验目的:我这里完成的是,将8张人脸图片(4组,每组两张)存入库中,选取1张图片,程序识别出与其匹配的另一张. 这里介绍分三个步骤完成该工作,①程序读取摄像头.拍照 ②程序从电脑文档中读取图片 ...
- 基于OpenCv的人脸检测、识别系统学习制作笔记之三
1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...
- 基于opencv 识别、定位二维码 (c++版)
前言 因工作需要,需要定位图片中的二维码:我遂查阅了相关资料,也学习了opencv开源库.通过一番努力,终于很好的实现了二维码定位.本文将讲解如何使用opencv定位二维码. 定位二维码不仅仅是为了识 ...
随机推荐
- [转载]Google Android开发精华教程
原文地址:Android开发精华教程">Google Android开发精华教程作者:huiyi8zai Android是Google于2007年11月5日宣布的基于Linux平台的开 ...
- MapReduce-输入分片与记录
一个输入分片(split)就是一个由单个map操作来处理的输入块.每一个map操作只处理一个输入分片.每个分片被划分为若干个记录,每条记录就是一个键值对,map一个接一个地处理记录.输入分片和记录都是 ...
- JConsole操作手册
一篇Sun项目主页上介绍JConsole使用的文章,前段时间性能测试的时候大概翻译了一下以便学习,今天整理一下发上来,有些地方也不知道怎么翻,就保留了原文,可能还好理解点,呵呵,水平有限,翻的不好,大 ...
- VK Cup 2017 - Qualification 1 C 贪心
是一道很有趣的题目 给出地图和起始点 与要求的步数k 要求走k步 正好回到起始点 输出字典序最小的移动路径 DLRU这样 可以想到DU LR都是相同数量的 于是k必须是一个偶数 然后走了弯路QAQ 从 ...
- 执行安装redis报错undefined reference to `__sync_add_and_fetch_4'
执行make命令时报错: zmalloc.o: In function `zmalloc_used_memory': /var/lib/tcommsvr/redis-2.8.0-rc4/src/z ...
- LAMP环境搭建问题
//////////////////////////LAMP环境搭建问题///////////////////////////////////////LAMP常见的问题A.安装相关问题(1)MySQL ...
- Javascript-我对作用链、闭包、原型及原型链的理解
Javascript-基础概念总结(2) 最近学习一些javascript基础知识,也解决了很多之前的疑惑,记得第一次被问及怎样理解闭包时,我的回答是:就是类似于封装吧!现在想想是有多白痴,学习技术是 ...
- 安装Xcode 7 beta后Xcode 6崩溃的问题
最新解决方案:把OSX El Capitan升级到Beta 7 (15A263e),Xcode6可使用! 解决方案:http://stackoverflow.com/questions/318035 ...
- Linux脚本基础
1.文本编辑 命令模式快捷键命令 命令 作用 dd 删除(剪切)光标所在整行. 5dd 删除(剪切)从光标处开始的5行. yy 复制光标所在整行. 5yy 复制从光标处开始的5行. n 显示搜索命令定 ...
- linux 部署nginx----端口转发
一.解压安装 tar zxvf nginx-.tar.gz cd nginx- ./configure --with-http_stub_status_module --with-http_ssl_m ...