本期介绍一下笔者在试验数据处理时写的一个用于火焰识别的小程序,该小程序的功能是对拍摄到的火焰图像进行提取、增强、降噪和识别,并输出相应处理过的火焰图像以及火焰参数,如传播距离、面积等。该程序基于Python 3语言,用到了前面提到的图像和数据文件的批处理,OpenCV库和numpy库的简单应用,以下针对该程序的思路进行介绍,不涉及具体的代码讲解。
1.原始图像准备
本例中的试验数据为高速相机拍摄的纹影火焰图像,下图是燃烧前后的图像对比,除了视野中增加了火焰之外,其余图像几乎没有发生变化。
2. 图像提取和增强
考虑到上面两张图像的差异,这里采用的是利用二者差异提取有用信息的方法,具体就是两幅图的对应像素RGB通道分别做差取绝对值,即|A-B|,A,B分别代表两幅图的像素矩阵。这种有效信息提取的方式可以排除掉由于一些硬件原因造成的画面明暗不均、污点等。在图像提取之后由于提取出来的图像非常暗,辨识度较低,因此需要对图像的画面进行增强,这里由于图像过于暗,直接将每个像素的RGB值进行了平方以增强图像(这种做法比较非主流,若有更好的方法欢迎提出)。下图是图像提取后和提取后增强的图像。
3. 图像降噪
由上图所示,虽然图像增强后画质更加清晰,辨识度明显提高,但相应的噪点也更多。目前降噪的算法较多,有高斯滤波、中值滤波、均值滤波、双边滤波等降噪算法。经过测试,在本算例中中值滤波具有较好的效果,对噪点去除较好,滤波后的图像如下图所示,图中虽然火焰图像的细节被一定程度地模糊了,但其火焰与背景的边界仍然非常清晰。
4. 灰度化和二值化
要想对火焰的轮廓进行识别,就需要首先对图像进行灰度处理,然后将灰度图像进行二值化处理。灰度处理的本质是将原有图像的RGB三个矩阵缩减成一个矩阵。因此,灰度处理的方法可以从两个方面考虑,一是直接用系统提供的灰度转换函数实现,二是可以将RGB三个通道中的一个提取出来作为灰度图。在本例中由于火焰图像的R (红色)通道具有有效信息强、噪点少的特点,因此直接将R通道的像素值提取作为灰度图。
在灰度处理的基础之上,二值化是将图像的像素值处理成只有0 (黑色)和255 (白色)两个值的结果。因此在二值化方法中需要涉及到阈值问题,低于阈值的取0;高于阈值的取255。阈值的选取往往也需要进行多次测试最终确定,本例中阈值取值为30。灰度化和二值化的结果如下图所示。
5. 腐蚀和膨胀
在二值化处理之后,发现图像上仍然存在一些噪点,这些噪点会对我们进行火焰的长度和面积计算造成干扰;此外,在一些情况下火焰内部还会存在空心点的情况,这也是我们想要尽量避免的。因此,需要用腐蚀和膨胀方法(或者开运算和闭运算)对二值化的图像进行处理,去除或减少噪点,同时补全图像的空心部分(具体算法这里不进行详细介绍,感兴趣的读者可查找相关资料深入研究)。经过腐蚀和膨胀处理后的二值化图像如下图所示,相比初始的二值化图像,噪点明显减少,同时图像内部的空心点也被补全。
6. 轮廓识别的挑选
基于腐蚀和膨胀处理之后的图像进行轮廓识别,若果存在离散的噪点那么轮廓识别也会有多个结果,需要制定一定的准则对识别到的轮廓进行筛选。比如轮廓长度低于某个值的认为是无效结果;亦或者在所有识别到的结果中只取最大轮廓等等。轮廓识别的最终效果以及与原始图像的对比如下图所示。基于该识别结果,可有效地对火焰的长度、面积进行计算,进而计算出传播速度、面积增长率等参数。
小结:该程序经过简单的修改可适用于各种物体追踪或者识别的应用中,如车辆运动、喷雾发展等。
附录:
在公众号发送“火焰图像识别”或“火焰识别”可获取完整代码以及测试图像的链接。
留言区