《超像素》
超像素是一种以聚类思想为初衷的方法,目的是为了对较大像素的图像进行区域划分,来帮助理解,本文介绍了一个开源项目在火灾检测场景使用超像素,比较巧妙,虽然效果不是很理想,但是提供了一个很好的思路。
Key Words:超像素、火灾检测、OpenCV实现
Beijing, 2020
作者:RaySue
Code:https://github.com/tobybreckon/fire-detection-cnn
Agile Pioneer
概念
超像素概念是2003年Xiaofeng Ren提出和发展起来的图像分割技术,指具有相似纹理、颜色、亮度等特征的相邻像素构成的有一定视觉意义的不规则像素块。
超像素就是把一幅像素级(pixel-level)的图,划分成区域级(district-level)的图,是对基本信息元素进行的抽象。超像素最直观的解释,便是把一些具有相似特性的像素“聚合”起来,形成一个更具有代表性的大“元素”。
-
它利用像素之间特征的相似性将像素分组,用少量的超像素代替大量的像素来表达图片特征,很大程度上降低了图像后处理的复杂度,所以通常作为分割算法的预处理步骤。
-
这些小区域大多保留了进一步进行图像分割的有效信息,且一般不会破坏图像中物体的边界信息。
-
应用超像素的意义在于:超像素可以把图像分割的足够细碎,从而可以保障每个分割后的图像块都是一块具有独立语义的图像块。
-
大大降低了数据维度,而且可以剔除一些异常像素点。
-
理论上,任何图像分割算法的过度分割(over-segmentation),即可生成超像素。
超像素常用算法
SEEDS
- cv2.ximgproc.createSuperpixelSEEDS
"""
参数解读:
image_width :输入图像宽度
image_height: 输入图像高度
image_channels :输入图像通道数
num_superpixels :期望超像素数目
num_levels :块级别数,值越高,分段越准确,形状越平滑,但需要更多的内存和CPU时间。
histogram_bins: 直方图bins数,默认5
double_step: 如果为true,则每个块级别重复两次以提高准确性默认false。
"""
retval = cv2.ximgproc.createSuperpixelSEEDS(image_width, image_height, image_channels, num_superpixels, num_levels[, prior[, histogram_bins[, double_step]]])slic = cv2.ximgproc.createSuperpixelSEEDS(test_img.shape[1], test_img.shape[0],test_img.shape[2], 1000, 10, 3, 5, True)slic.iterate(test_img, 10)
LSC (Linear Spectral Clustering) 线性谱聚类
- cv2.ximgproc.createSuperpixelLSC
region_size = 30 # 超像素块的大小
slic = cv2.ximgproc.createSuperpixelLSC(test_img, region_size=region_size)
slic.iterate(10)
mask_slic = slic.getLabelContourMask() # 获取Mask,超像素边缘Mask==1
label_slic = slic.getLabels() # 获取超像素标签
number_slic = slic.getNumberOfSuperpixels() # 获取超像素数目
print(mask_slic.shape)
print(label_slic.shape)
mask_inv_slic = cv2.bitwise_not(mask_slic)
test_mask = np.ones_like(test_img) * 255
# 在原图上绘制超像素边界
small_frame = cv2.bitwise_and(test_img, test_img, mask=mask_inv_slic)
SLIC (Simple linear iterative clustering) 线性迭代聚类
- cv2.ximgproc.createSuperpixelSLIC
# 参数解读
# image :输入图像
# algorithm:选择要使用的算法变体:SLIC、SLICO(默认)和MSLIC三种可选
# region_size:平均超像素大小,默认10
# ruler:超像素平滑度,默认10
slic = cv2.ximgproc.createSuperpixelSLIC(test_img, region_size=22, ruler=30.0)
slic.iterate(10)
mask_slic = slic.getLabelContourMask() # 获取Mask,超像素边缘Mask==1
label_slic = slic.getLabels() # 获取超像素标签
number_slic = slic.getNumberOfSuperpixels() # 获取超像素数目
print(mask_slic.shape)
print(label_slic.shape)
mask_inv_slic = cv2.bitwise_not(mask_slic)
test_mask = np.ones_like(test_img) * 255small_frame = cv2.bitwise_and(test_img, test_img, mask=mask_inv_slic) # 在原图上绘制超像素边界
评估标准
-
Under segmentation Error
- 用于描述超像素块既包含很多物体边缘及物体,又包含很多的背景,这种像素团越多说明效果越不好
-
Boundary Recall
- 和物体边界的重合度,越高代表超像素的边缘越贴近物体边缘
-
Compactness score
- 可以理解为越向棋盘格子越紧实,也就是在超像素簇内部有着更低的空间方
应用场景
该技术已经被广泛的应用到图像分割、姿势估计、目标跟踪、目标识别等多个计算机视觉任务等。
利用超像素来理解 CNN 到底学到了什么,安利论文:“Why Should I Trust You?” Explaining the Predictions of Any Classifier
配合分类模型做 目标定位 比如:一个火灾检测的项目就用到了超像素“Experimentally Defined Convolutional Neural Network Architecture Variants for Non-temporal Real-time Fire Detection”
配合粒子滤波做 目标跟踪 比如:“Superpixel Tracking”
超像素在火灾检测中的应用
对所有的有火灾和没有火灾的图片进行二分类,然后利用超像素算法,对每个超像素块移动到中心,保持模型训练尺度的大小进行分类,所有有多少超像素块就分多少类,效果如下:
Q&A
Q: AttributeError: module ‘cv2.cv2’ has no attribute ‘ximgproc’
A: 如果没有按照opencv-contrib就会报错,pip install opencv-contrib-python解决
参考
[1] https://www.zhihu.com/question/27623988
[2] https://www.cnblogs.com/blog4ljy/p/9449915.html
[3] https://blog.csdn.net/WZZ18191171661/article/details/91039457
[4] https://blog.csdn.net/zhangyonggang886/article/details/51494122?locationNum=2&fps=1
[5] https://blog.csdn.net/qq_26129959/article/details/90760028
[6] https://blog.csdn.net/qq_40268412/article/details/103915197
[7] https://blog.csdn.net/chengyq116/article/details/98470820