[OpenCV][纹理特征]如何计算不同方向下的高斯导数直方图
学习SelectiveSearch
算法时候,其纹理特征需要计算类SIFT
特征,实现方式是计算每张图片8
个方向上10 bin
大小的高斯导数直方图
\(S_{texture}(r_{i}, r_{j})\) measures texture similarity. We represent texture using fast SIFT-like measurements as SIFT itself works well for material recognition [20]. We take Gaussian derivatives in eight orientations using \(σ = 1\) for each colour channel. For each orientation for each colour channel we extract a histogram using a bin size of 10. This leads to a texture histogram \(T_{i} = {t_{i}^{1}, ..., t_{i}^{n}}\) for each region \(r_{i}\) with dimensionality \(n = 240\) when three colour channels are used. Texture histograms are normalised using the \(L_{1}\) norm. Similarity is measured using histogram intersection:
OpenCV
实现了SelectiveSearch
算法,其通过图像旋转、Scharr
滤波以及手动计算直方图的方式完成了纹理特征的计算。之前没有思考过如何完成不同方向下导数直方图的计算,学习里面代码实现不同方向下的导数直方图计算
源码地址:opencv_contrib/modules/ximgproc/src/selectivesearchsegmentation.cpp
完整流程
- 计算高斯导数
- 计算直方图
- 直方图连接
计算高斯导数
需要分别计算8
个方向上的高斯导数,分别是
x
轴正/负方向y
轴正/负方向- 图像逆时针
45
度旋转后x
轴正/负方向 - 图像逆时针
45
度旋转后y
轴正/负方向
使用函数Scharr
对图像进行高斯求导,然后通过阈值函数threshold
获取正/负方向的求导结果
完成上述操作后将结果进行标准化([0,255]
),以便后续直方图的计算。实现代码如下:
1 | /** |
- 进行阈值函数操作后直接放入向量中,所以求导图像有正有负
- 标准化公式如下:
\[ y = \frac{255*(x-hmin)}{hmax-hmin} \]
计算直方图
参考:直方图
1 | /** |
调用OpenCV
函数calcHist
得到的是N
列大小的矩阵,为方便后续计算,将其转置成单行矩阵
直方图连接
彩色图像有3
个通道,每个通道有8
个方向求导,共得到3x8=24
个直方图
对每个求导图像计算10 bin
大小的直方图,所以得到的纹理特征维数是24x10=240
维
在连接各个直方图之前,可以先对其进行标准化([0,1]
),以便后续操作
1 | int main() { |