selective search算法学习记录
本文是利用skimage库中实现的selective search算法进行解释的。
利用felzenszwalb算法对图片进行分割。
skimage库中felzenszwalb()函数实现了这个算法。
skimage.segmentation.felzenszwalb(skimage.util.img_as_float(im_orig),
scale=scale, sigma=sigma,
min_size=min_size)
其中,im_orig是读取后的图片(3通道),scale参数越大,分割聚类越大。sigma是高斯核的宽度。min_size是得到的最小尺寸。
这个函数返回的是一个和输入图片大小相同尺寸的矩阵。矩阵里面相同的数字表示原图中对应的像素点处属于同一个分割区域。
产生region proposal
将读取到的图片和上一个步骤中得到的分割区域,cat到一起。得到的是一个(width,height,channel),其中channel有三个维度,前三个就是图片三个通道的像素值,最后一个维度是0 1 2…这样的标号。标号相同的表明这两个像素点是同一个区域。
之后按照y,x轴的方向遍历整个图片,根据上步骤中的分割区域生成region proposal,具体原理就是计算一个方框,这个方框将该分割区域所有的像素都包含进去。(方框是矩形的,所有一定存在一个方框中包含一整个分割区域,然后还有一些其他的分割区域)方框的坐标用xyxy的格式进行保存。
用一个字典R进行存放,其中键值是0,1,2,3,4…有多少个region proposal就有多少个键值对。值就是对应区域的坐标等信息。
计算整个图片的纹理梯度
用skimage库中带的方法skimage.feature.local_binary_pattern()分别计算图片三个通道上的梯度,并放到一个ndarry中。用RGB格式的图片进行梯度的计算。
计算每个区域的颜色和纹理直方图
颜色直方图选择的是25bins,也就是有25个条形。
纹理直方图(梯度)是10bins。
这里的每个区域使用像素来表示的,并不是用得到的region proposal来计算。源代码中hsv中前两个通道都是从0-1的数值,第三个通道是<255。因此计算出前两个直方图,都是横坐标为0的地方是1,其他地方是0。计算三个直方图,然后将其concat到一起一共的到一个75维的向量。
并且计算颜色直方图的时候,用的是hsv格式进行计算的。
纹理直方图其实就是用上一步中的到梯度图进行直方图的计算。
计算每个region proposal的邻居
这里计算邻居的时候,是只要两个框有交集,就说明他俩是邻居。采用两个for循环嵌套,将所有的邻居的找出来。
之后将每两个邻居,进行相似度的求解,就是根据直方图进行一定的运算。
将相似度比较大进行合并
上一步中的到的是类似{(r1,r2):相似度的数值}的字典S。接着取出相似度最大的那一组,将里面的两个region proposal进行融合,之后删掉S中包含已经融合好的那两个region proposal的键值对。将融合得到的新的region proposal,放到R中。一直这样循环,直到S为0。此时就得到了最终的selective search后的结果,存放在字典R中。
最终R中包含的是每个区域的label,和xyxy四个坐标,以及size(是精确的size数,而不是通过方框坐标选出来的)
总结
selective search算法,其实就是首先通过felzenszwalb算法,对原始图片进行分割,之后得到一堆初始的region proposal,接着通过计算直方图,然后求解原始region proposal之间的相似度,将相似度大的region proposal合并到一起,得到一个新的region proposal。最后得到的region proposal包括初始的和后面相似度较大的合成的新的region proposal。