提出问题
随着计算机视觉及图像处理技术的发展 ,基于计算机视觉的火焰检测技术逐渐取代了传统的火灾检测 。
由于火焰最显著静态特质是其颜色 ,火焰识别算法主要利用视频图像中颜色与亮度的相关信息 ,所以对火焰颜色的特征提取是火焰识别过程的关键 。在有关火焰检测技术中对颜色空间应用研究也日益增多 。
初步分析
计算机中的图片一般用数组存储,以像素点为单位。
在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
r??g,
r
?
?
b
r--b
r??b,
g
?
?
b
g--b
g??b三个平面生成一幅3271975像素的质量分布图。下图体现火焰区域像素在
r
?
?
g
r--g
r??g,
r
?
?
b
r--b
r??b,
g
?
?
b
g--b
g??b三个平面的分布情况。在下图中黑色三角形部分就是火焰像素识别区域,并以此区域来识别像素点是否是火焰像素。
注意:计算机中像素点RGB值在数组中存储的顺序是B、G、R
可以用下列不等式来表示上图中的三角形区域:
综合使用上面的规则,我们可以有效的从图像中识别出可以火焰像素,划定火焰区域。
为减少由于手工标注火焰区域边缘导致该处像素点的识别率低,采取三角形区域覆盖。
代码举例
导入需要的包:
import cv2 as cv
import numpy as np
import PIL.Image as Image
读取图像:
image=Image.open('fire.jpeg')
image.show()
将图像转为数组形式读取:
src=cv.imread('fire.jpeg')
print(src.shape)
print(src.size)
结果展示为:
(435, 640, 3)
835200
计算三通道的均值:
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_))
结果为:
b,g,r三通道均值分别为20.331627155172413,26.382262931034482,34.51316451149425
识别函数为:
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)
接下来我们需要可视化得到的新图像:
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)
结果为:
参考文献
《基于颜色特征的火焰检测新算法》,耿庆田 ,于繁华 ,赵宏伟 ,王 闯;吉林大学计算机科学与技术学院,长春师范大学计算机科学与技术学院
|