关闭

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

671人阅读 评论(0) 收藏 举报
分类:
上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据——HSI判据。
    为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型:

    HSI颜色模型用H、S、I三参数描述颜色特性,其中:
    H表示颜色的色调,它表示人的感官对不同颜色的感受,如红色、绿色、蓝色等,它也可表示一定范围的颜色,如暖色、冷色等。
    H的单位是°,代表与红轴的角度。

这里写图片描述

    S表示颜色的饱和度,纯光谱色是完全饱和的,加入白光会稀释饱和度。饱和度越大,颜色看起来就会越鲜艳。
    I对应成像亮度和图像灰度。

    HSI模型的建立基于两个重要的事实: ① I分量与图像的彩色信息无关;② H和S分量与人感受颜色的方式是紧密相联的。
    这些特点使得HSI模型非常适合彩色特性检测与分析。

    对比一下RGB和HSI模型:

这里写图片描述

    得出由RGB模型转化为HSI模型的公式:

这里写图片描述

    假设R、G、B分量已经归一化到[0,1],那么求出来的S分量和I分量的值也会被归一化到[0,1]。当S分量为0的时候,对应的H分量也应该为0。

    用OpenCV1.0可以根据上面的公式和条件写出模型转化函数的代码:
int cvBGR2HSI(IplImage*img_bgr, IplImage*img_hsi){
    if (img_bgr == NULL || img_hsi == NULL){
        printf("func cvBGR2HSI Error:\n");
        printf("img_bgr == NULL || img_hsi == NULL\n");
        return -1;
    }

    if (img_bgr->nChannels != 3 || img_hsi->nChannels != 3){
        printf("func cvBGR2HSI Error:\n");
        printf("img_bgr->nChannels != 3 || img_hsi->nChannels != 3\n");
        return -1;
    }

    double eps = 1.111e-016;
    double pi = 3.1416;
    double num = 0;
    double den = 0;
    double theta = 0;
    double R, G, B, H, S, I;
    for (int i = 0; i < img_bgr->height; i++){
        uchar*ptr1 = (uchar*)(img_bgr->imageData + i*img_bgr->widthStep);
        uchar*ptr2 = (uchar*)(img_hsi->imageData + i*img_hsi->widthStep);
        for (int j = 0; j < img_bgr->width; j++){
            R = double(ptr1[3 * j + 2]) / 255.0;
            G = double(ptr1[3 * j + 1]) / 255.0;
            B = double(ptr1[3 * j + 0]) / 255.0;
            num = 0.5*((R - G) + (R - B));
            den = sqrt((R - G)*(R - G) + (R - B)*(G - B));
            theta = acos(num / (den + eps));

            H = theta;
            if (B>G){
                H = 2 * pi - H;
            }
            H = H / (2 * pi);
            num = min(min(R, G), B);
            den = R + G + B;
            if (den < eps){
                den = eps;
            }
            S = 1 - 3 * num / den;
            if (S < eps){
                H = 0;
            }
            I = (R + G + B) / 3.0;

            ptr2[3 * j + 0] = H * 360;
            ptr2[3 * j + 1] = S * 255;
            ptr2[3 * j + 2] = I * 255;
        }
    }
    return 0;
}
   在代码中要注意的是在OpenCV中RGB三通道的排列顺序:先存放B分量,再存放G分量,最后才是R分量,这与MATLAB里面的规则是不同的。

    有了模型转化函数之后,我们就可以在HSI色彩模型内使用HSI判据了。HSI判据很简单,也很直观,它的规则是每个分量设定两个阈值,满足
阈值条件的置1,不满足的置0。具体表达式如下:
                        H_min < H < H_max  AND
                        S_min < S < S_max  AND
                        I_min < I < I_max

    在OpenCV1.0中可以轻松写出上面的代码:
int cvHSI_CHK(IplImage*img_hsi, IplImage*hsi_chk, int H_min, int H_max, int S_min, int S_max, int I_min, int I_max)
{
    if (img_hsi == NULL || hsi_chk == NULL){
        printf("func cvHSI_CHK Error:\n");
        printf("img_hsi == NULL || hsi_chk == NULL)\n");
        return -1;
    }

    if (img_hsi->nChannels != 3 || hsi_chk->nChannels != 1){
        printf("func cvHSI_CHK Error:\n");
        printf("img_hsi->nChannels != 3 || hsi_chk->nChannels != 1)\n");
        return -1;
    }

    CvSize size = cvGetSize(img_hsi);

    IplImage*H = cvCreateImage(size, 8, 1);
    IplImage*S = cvCreateImage(size, 8, 1);
    IplImage*I = cvCreateImage(size, 8, 1);
    IplImage*mask = cvCreateImage(size, 8, 1);

    cvSplit(img_hsi, H, S, I, NULL);

    cvCmpS(H, H_min, mask, CV_CMP_GE);

    cvCmpS(H, H_max, H, CV_CMP_LE);
    cvMul(H, mask, H);

    cvCmpS(S, S_min, mask, CV_CMP_GE);
    cvCmpS(S, S_max, S, CV_CMP_LE);
    cvMul(S, mask, S);

    cvCmpS(I, I_min, mask, CV_CMP_GE);
    cvCmpS(I, I_max, I, CV_CMP_LE);
    cvMul(I, mask, I);

    cvMul(H, S, H);
    cvMul(H, I, hsi_chk);
    cvConvertScale(hsi_chk, hsi_chk, 1.0 / 255);    

    cvReleaseImage(&H);
    cvReleaseImage(&S);
    cvReleaseImage(&I);
    cvReleaseImage(&mask);

    return 0;
}
 根据实验经验,博主给出一组参考阈值:
    H_min = 0    H_max = 60          
    S_min = 20   S_max = 100
    I_min = 100  I_max = 255

    参考上面给出的色相环可以轻松设定H分量的两个阈值,如果是想要检测其他颜色的火焰,可以根据需要做修改。
    S分量的阈值较小,这与火焰所处的环境有关,若是在露天较明亮的地方检验,则需要调低一点;若在室内较暗的地方检验,则需要调高一点。
    I分量的阈值较大,依据这么一个先验知识:火焰是会发光的。

    最后,我们代入参考阈值检验一下图片看看效果如何:

这里写图片描述

这里写图片描述

    我们可以看出,火焰的基本轮廓都提取出来了。若大家想要把整个区域都提取出来,可以自行尝试其它阈值。

0
0
查看评论

OpenCV小例程——火焰检测(完整代码)

火焰检测小程序 前几天,偶然看到了An Early Fire-Detection Method Based on Image Processing ,The Author is:Thou-Ho (Chao-Ho) Chen, Ping-Hsueh Wu, and Yung-Chuen Chiou 这...
  • xiao_lxl
  • xiao_lxl
  • 2015-01-30 15:51
  • 5532

基于OpenCV的火焰检测(二)——RGB颜色判据

上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域。火焰提取要用 到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据——RGB判据。 在介绍这个判据之前,博主首先给大家简单介绍一下RGB模型。根据三基色原理,用基色光单...
  • qq_26093511
  • qq_26093511
  • 2016-05-30 12:19
  • 788

烟雾或者火焰检测方法

1 Deep Learning很热,所以大家都用这个做图像处理,可以理解,好发论文嘛。我也用过,发现学习速度太慢,不大实用,如果不是很难(前景和背景对比度低,或者干扰很严重),常用的图像处理方法就可以了。 2 图像分割,可以用阈值法、区域生长、边缘检测、数学形态学的分水岭、小波变换,这些我都用过,...
  • fuping07
  • fuping07
  • 2016-10-17 15:22
  • 920

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

博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测。在做这个项目的时候,博主参考了很多相关的文献,用了很多种不同的火焰判据,并将其进行不同组合,从而达到我们想要的检测效果。接下来的几篇博文将会详细介绍一些效果...
  • qq_27569955
  • qq_27569955
  • 2016-05-14 19:33
  • 3403

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

上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据——HSI判据。 为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型: HSI颜色模型用H、S、I三参数描述颜色特性,其中: H表示颜色的色调,它表示人的感官...
  • qq_27569955
  • qq_27569955
  • 2016-05-29 14:34
  • 1909

基于OpenCV的火焰检测(二)——RGB颜色判据

上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域。火焰提取要用 到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据——RGB判据。 在介绍这个判据之前,博主首先给大家简单介绍一下RGB模型。根据三基色原理,用基色光单位...
  • qq_27569955
  • qq_27569955
  • 2016-05-25 22:54
  • 3392

基于OpenCV的火焰检测(四)——RGB与HSI的结合判据

上两篇博文给大家分别介绍了在火焰检测中常用的两种颜色判据——RGB判据和HSI判据,这一篇博文给大家展示一下它们两个单纯结合的效 果,然后介绍一个更强大的结合算法,能够很好地分割出火焰区域。在下篇博文将会在RGB判据以及HSI判据的基础上分别添加更加严格的约束条件, 使得不合理的区域进一步缩小。 ...
  • qq_27569955
  • qq_27569955
  • 2016-06-02 11:50
  • 1392

OpenCV学习记录之视频中的火焰检测识别

主要完成两个视频中火焰的检测,主要结合RGB判据和HIS判据,设定合适的阈值条件,检测出火焰对应像素的区域,将原图二值化,经过中值滤波以及数学形态学的膨胀运算等图像处理,消除一些噪声及离散点,连通一些遗漏的区域。基于OpenCV的开源库,在VS2013平台上,实现了两个视频中火焰的检测。 利用Ope...
  • coldplayplay
  • coldplayplay
  • 2017-04-17 15:53
  • 2551

opencv 火焰识别

转载: http://blog.163.com/wufei_8888@126/blog/static/4869046620115127552220/ void CPatternrecognitionDlg::SharpAngle(IplImage *pImage)//, CvPo...
  • zpx3243
  • zpx3243
  • 2013-09-20 21:30
  • 1288

基于OpenCV的火焰检测(五)——两个颜色模型的主分量判据

这篇将会是最后一篇讨论从RGB空间和HSI空间中提取火焰区域的博文,其中用到技术称为基于颜色模型的主分量判据。听起来好像很高大上, 其实也是一种很简单的判据,下面就带大家了解一下这个判据。 所谓的主分量,就是在颜色模型里面的三个分量中对于研究的问题较为重要的其中一个分量。如何选取主分量有一定的...
  • qq_27569955
  • qq_27569955
  • 2016-06-05 18:29
  • 1349
    个人资料
    • 访问:286105次
    • 积分:5105
    • 等级:
    • 排名:第6494名
    • 原创:168篇
    • 转载:325篇
    • 译文:2篇
    • 评论:17条
    博客专栏
    最新评论