• 计算机视觉小项目—基于RGB颜色特征的火焰识别


    提出问题

    随着计算机视觉及图像处理技术的发展 ,基于计算机视觉的火焰检测技术逐渐取代了传统的火灾检测 。

    由于火焰最显著静态特质是其颜色 ,火焰识别算法主要利用视频图像中颜色与亮度的相关信息 ,所以对火焰颜色的特征提取是火焰识别过程的关键 。在有关火焰检测技术中对颜色空间应用研究也日益增多 。

    初步分析

    计算机中的图片一般用数组存储,以像素点为单位。

    在RGB颜色空间下,每个像素点的颜色由R、G、B三通道组成,RGB颜色空间以R(Red红)、G(Green绿)、B(Blue蓝)三种颜色为基础,进行不同程度的叠加,产生丰富而广泛的颜色,所以也叫三基色模式。

    每个通道的取值范围从0到255,每种颜色都有对应的RGB值。

    同样的道理,火焰也是如此,只要找到火焰颜色的RGB值的规律,就可以借此来识别图中的火焰。

    最关键的问题是:如何找到火焰的RGB值的规律呢?

    解决问题

    最简单的方法就是利用统计学中的抽样调查,找几张只有火焰的图,读取它们的RGB值,并从中找出规律。

    当然了,也可以参考他人所写的相关文章,复现别人的方法。

    我们接下来看一下一篇文章中的记载:

    如上图所示, a a a列表示原始图像, b b b列表示R通道, c c c表示G通道, d d d列表示B通道。

    可以很清晰看到火焰区域强度值最高的是R通道,最低的是B通道。

    我们对火焰区域分割并用绿色标记,可以计算出这些样本图像火焰部分像素点 R    ,    G    ,    B R\;,\;G\;,\;B R,G,B的均值 R m e a n    ,    G m e a n    ,    B m e a n R_{mean}\;,\;G_{mean}\;,\;B_{mean} Rmean,Gmean,Bmean



    通过以上的研究发现,火焰区域R通道值最高,颜色饱和度最高。因此,火焰区域像素应符合下列条件:

    式中, R ( x , y )    ,    G ( x , y )    ,    B ( x , y ) R(x,y)\;,\;G(x,y)\;,\;B(x,y) R(x,y),G(x,y),B(x,y)分别表示像素点 ( x , y ) (x,y) (x,y)红绿蓝三个通道的值。 K K K是总像素点。 R m e a n R_{mean} Rmean是总像素中红色分量强度平均值。公式表明,火焰区域各分量强度值中 R m e a n R_{mean} Rmean的值最大。

    当前由于灯光照明的影响,使许多建立在像素点通道值转换技术基础上的火焰识别算法的检测效果大打折扣。但是,标准的RGB颜色模型不易受灯光照明的影响。因此,可以使用RGB颜色空间的转换公式:

    在火焰图片库中随机抽取各种条件不同的图片200张。用手工标注出这些图片的火焰区域,并分别在 r − − g r--g rg r − − b r--b rb g − − b g--b gb三个平面生成一幅3271975像素的质量分布图。下图体现火焰区域像素在 r − − g r--g rg r − − b r--b rb g − − b g--b gb三个平面的分布情况。在下图中黑色三角形部分就是火焰像素识别区域,并以此区域来识别像素点是否是火焰像素。

    注意:计算机中像素点RGB值在数组中存储的顺序是B、G、R

    可以用下列不等式来表示上图中的三角形区域:

    综合使用上面的规则,我们可以有效的从图像中识别出可以火焰像素,划定火焰区域。

    为减少由于手工标注火焰区域边缘导致该处像素点的识别率低,采取三角形区域覆盖。

    代码举例

    导入需要的包:

    import cv2 as cv
    import numpy as np
    import PIL.Image as Image
    
    • 1
    • 2
    • 3

    读取图像:

    image=Image.open('fire.jpeg')
    image.show()
    
    • 1
    • 2


    将图像转为数组形式读取:

    src=cv.imread('fire.jpeg')
    print(src.shape) #(高、宽、通道数)
    print(src.size) # 像素点个数
    
    • 1
    • 2
    • 3

    结果展示为:

    (435, 640, 3)
    835200
    
    • 1
    • 2

    计算三通道的均值:

    # 计算机中像素点RGB值再数组中存储的顺序为B、G、R
    b=0
    g=0
    r=0
    for i in range(len(src)): # 行数
        for j in range(len(src[i])):
            b+=src[i][j][0]
            g+=src[i][j][1]
            r+=src[i][j][2]
    # 三通道均值
    b_=b/src.size
    g_=g/src.size
    r_=r/src.size
    print('b,g,r三通道均值分别为{},{},{}'.format(b_,g_,r_))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果为:

    b,g,r三通道均值分别为20.331627155172413,26.382262931034482,34.51316451149425
    
    • 1

    识别函数为:

    def imag_process(src):
        r_aver=217
        g_aver=109
        b_aver=78
        for i in range(len(src)):
            for j in range(len(src[i])):
                b_p=src[i][j][0]/np.sum(src[i][j]+1e-5)
                g_p=src[i][j][1]/np.sum(src[i][j]+1e-5)
                r_p=src[i][j][2]/np.sum(src[i][j]+1e-5)
                if src[i][j][2]>r_aver and src[i][j][2]>src[i][j][1]>src[i][j][0]:
                    if src[i][j][2] > r_aver and src[i][j][2] > src[i][j][1] > src[i][j][0]:
                        if r_p >= 1.14 * g_p - 0.076 and r_p <= -0.989 * g_p + 0.991 and r_p >= -2.077 * g_p + 1.025:
                            if r_p <= -1.881 * b_p + 0.9582 and r_p <= 95.348 * b_p + 0.171 and r_p >= -0.543 * b_p + 0.506:
                                if g_p >= 0.846 * b_p + 0.048 and g_p <= -0.461 * b_p + 0.495 and g_p <= 191.957 * b_p - 0.621:
                                    src[i][j][0] = 0
                                    src[i][j][1] = 255
                                    src[i][j][2] = 0
        return src
    
    new_image = imag_process(src)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    接下来我们需要可视化得到的新图像:

    def img_show(src):
        ch=np.random.rand()*100
        cv.namedWindow("图片", cv.WINDOW_NORMAL)
        cv.imshow("图片", src)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img_show(new_image)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果为:

    参考文献

    《基于颜色特征的火焰检测新算法》,耿庆田 ,于繁华 ,赵宏伟 ,王 闯;吉林大学计算机科学与技术学院,长春师范大学计算机科学与技术学院

  • 相关阅读:
    算法刷题介绍
    后台管理-----动态路由1(首页页面与路由映射的创建)
    基于PHP的玩偶玩具商城网站设计
    汽车驾驶智能座舱太阳光模拟器老化试验
    聊聊RocketMQ中的broker的TPS和QPS为何相差巨大,是如何统计的
    SIP中继与VoIP:有何不同?
    Python每日一练(牛客新题库)——第24天:内置函数
    抖音矩阵系统,。抖音矩阵系统,。抖音矩阵系统,。抖音矩阵系统,。抖音矩阵系统,。
    HarmonyOS开发案例:【图片编辑】
    HCIA使用DHCP配置eNSP,给路由器加权限并且加密
  • 原文地址:https://blog.csdn.net/wzk4869/article/details/126114191