梯度、边缘和角点

Sobel

使用扩展 Sobel 算子计算一阶、二阶、三阶或混合图像差分

void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 );

src

输入图像.

dst

输出图像.

xorder

x 方向上的差分阶数

yorder

y 方向上的差分阶数

aperture_size

扩展 Sobel 核的大小,必须是 1, 3, 5 或 7。 除了尺寸为 1, 其它情况下, aperture_size ×aperture_size 可分离内核将用来计算差分。对 aperture_size=1的情况, 使用 3x1 或 1x3 内核(不进行高斯平滑操作)。这里有一个特殊变量 CV_SCHARR (=-1),对应 3x3 Scharr 滤波器,可以给出比 3x3 Sobel 滤波更精确的结果。Scharr 滤波器系数是:

0818b9ca8b590ca3270a3433284dd417.png

对 x-方向 以及转置矩阵对 y-方向。

函数 cvSobel 通过对图像用相应的内核进行卷积操作来计算图像差分:

0818b9ca8b590ca3270a3433284dd417.png

由于Sobel 算子结合了 Gaussian 平滑和微分,所以,其结果或多或少对噪声有一定的鲁棒性。通常情况,函数调用采用如下参数 (xorder=1, yorder=0, aperture_size=3) 或 (xorder=0, yorder=1, aperture_size=3) 来计算一阶 x- 或 y- 方向的图像差分。第一种情况对应:

0818b9ca8b590ca3270a3433284dd417.png 核。

第二种对应:

0818b9ca8b590ca3270a3433284dd417.png

或者

0818b9ca8b590ca3270a3433284dd417.png

核的选则依赖于图像原点的定义 (origin 来自 IplImage 结构的定义)。由于该函数不进行图像尺度变换,所以和输入图像(数组)相比,输出图像(数组)的元素通常具有更大的绝对数值(译者注:即象素的深度)。为防止溢出,当输入图像是 8 位的,要求输出图像是 16 位的。当然可以用函数 cvConvertScale 或 cvConvertScaleAbs 转换为 8 位的。除了 8-比特 图像,函数也接受 32-位浮点数图像。所有输入和输出图像都必须是单通道的,并且具有相同的图像尺寸或者ROI尺寸。

Laplace

计算图像的 Laplacian 变换

void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 );

src

输入图像.

dst

输出图像.

aperture_size

核大小 (与 cvSobel 中定义一样).

函数 cvLaplace 计算输入图像的 Laplacian变换,方法是先用 sobel 算子计算二阶 x- 和 y- 差分,再求和:

dst(x,y) = d2src/dx2 + d2src/dy2

对 aperture_size=1 则给出最快计算结果,相当于对图像采用如下内核做卷积:

0818b9ca8b590ca3270a3433284dd417.png

类似于 cvSobel 函数,该函数也不作图像的尺度变换,所支持的输入、输出图像类型的组合和cvSobel一致。

Canny

采用Canny算法做边缘检测

void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 );

image

输入图像.

edges

输出的边缘图像

threshold1

第一个阈值

threshold2

第二个阈值

aperture_size

Sobel 算子内核大小 (见 cvSobel).

函数 cvCanny 采用 CANNY 算法发现输入图像的边缘而且在输出图像中标识这些边缘。threshold1和threshold2 当中的

小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。

注意事项:cvCanny只接受单通道图像作为输入。

PreCornerDetect

计算用于角点检测的特征图,

void cvPreCornerDetect( const CvArr* image, CvArr* corners, int aperture_size=3 );

image

输入图像.

corners

保存候选角点的特征图

aperture_size

Sobel 算子的核大小(见cvSobel).

函数 cvPreCornerDetect 计算函数

0818b9ca8b590ca3270a3433284dd417.png 其中

0818b9ca8b590ca3270a3433284dd417.png 表示一阶图像差分,

0818b9ca8b590ca3270a3433284dd417.png 表示二阶图像差分。 角点被认为是函数的局部最大值:

// 假设图像格式为浮点数 IplImage* corners = cvCloneImage(image); IplImage* dilated_corners = cvCloneImage(image);

IplImage* corner_mask = cvCreateImage( cvGetSize(image), 8, 1 ); cvPreCornerDetect( image, corners, 3 );

cvDilate( corners, dilated_corners, 0, 1 ); cvSubS( corners, dilated_corners, corners );

cvCmpS( corners, 0, corner_mask, CV_CMP_GE );

cvReleaseImage( &corners ); cvReleaseImage( &dilated_corners );

CornerEigenValsAndVecs

计算图像块的特征值和特征向量,用于角点检测

void cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv, int block_size, int aperture_size=3 );

image

输入图像.

eigenvv

保存结果的数组。必须比输入图像宽 6 倍。

block_size

邻域大小 (见讨论).

aperture_size

Sobel 算子的核尺寸(见 cvSobel).

对每个象素,函数 cvCornerEigenValsAndVecs 考虑 block_size × block_size 大小的邻域 S(p),

然后在邻域上计算图像差分的相关矩阵:

0818b9ca8b590ca3270a3433284dd417.png

然后它计算矩阵的特征值和特征向量,并且按如下方式(λ1, λ2, x1, y1, x2, y2)存储这些值到输出图像中,其中

λ1, λ2 - M 的特征值,没有排序

(x1, y1) - 特征向量,对 λ1

(x2, y2) - 特征向量,对 λ2

CornerMinEigenVal

计算梯度矩阵的最小特征值,用于角点检测

void cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, int block_size, int aperture_size=3 );

image

输入图像.

eigenval

保存最小特征值的图像. 与输入图像大小一致

block_size

邻域大小 (见讨论 cvCornerEigenValsAndVecs).

aperture_size

Sobel 算子的核尺寸(见 cvSobel). 当输入图像是浮点数格式时,该参数表示用来计算差分固定的浮点滤波器的个数.

函数 cvCornerMinEigenVal 与 cvCornerEigenValsAndVecs 类似,但是它仅仅计算和存储每个象素点差分相关矩阵的最小特征值,

即前一个函数的 min(λ1, λ2)

CornerHarris

哈里斯(Harris)角点检测

void cvCornerHarris( const CvArr* image, CvArr* harris_responce, int block_size, int aperture_size=3, double k=0.04 );

image

输入图像。

harris_responce

存储哈里斯(Harris)检测responces的图像。与输入图像等大。

block_size

邻域大小(见关于cvCornerEigenValsAndVecs的讨论)。

aperture_size

扩展 Sobel 核的大小(见 cvSobel)。格式. 当输入图像是浮点数格式时,该参数表示用来计算差分固定的浮点滤波器的个数。

k

Harris detector free parameter. See the formula below.

harris 检测器的自由参数。请看如下公式。

The function cvCornerHarris runs the Harris edge detector on image. Similarly to cvCornerMinEigenVal and

cvCornerEigenValsAndVecs, for each pixel it calculates 2x2 gradient covariation matrix M

over block_size×block_size neighborhood. Then, it stores

det(M) - k*trace(M)2 to the destination image. Corners in the image can be found as local maxima of the

destination image.

函数 cvCornerHarris 对输入图像进行 Harris 边界检测。类似于 cvCornerMinEigenVal 和 cvCornerEigenValsAndVecs。

对每个像素,在 block_size*block_size 大小的邻域上,计算其2*2梯度共变矩阵(或相关异变矩阵)M。

然后,将 det(M) - k*trace(M)2 (此公式有待考证,最后的“2”是否应为平方符号?这里2应该是平方)保存到输出图像中。

输入图像中的角点在输出图像中由局部最大值表示。

FindCornerSubPix

精确角点位置void cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, int count, CvSize win,

CvSize zero_zone, CvTermCriteria criteria );image

输入图像.

corners

输入角点的初始坐标,也存储精确的输出坐标

count

角点数目

win

搜索窗口的一半尺寸。如果 win=(5,5) 那么使用 5*2+1 × 5*2+1 = 11 × 11 大小的搜索窗口

zero_zone

死区的一半尺寸,死区为不对搜索区的中央位置做求和运算的区域。它是用来避免自相关矩阵出现的某些可能的奇异性。

当值为 (-1,-1) 表示没有死区。

criteria

求角点的迭代过程的终止条件。即角点位置的确定,要么迭代数大于某个设定值,或者是精确度达到某个设定值。

criteria 可以是最大迭代数目,或者是设定的精确度,也可以是它们的组合。

函数 cvFindCornerSubPix 通过迭代来发现具有子象素精度的角点位置,或如图所示的放射鞍点(radial saddle points)。

0818b9ca8b590ca3270a3433284dd417.png

子象素级角点定位的实现是基于对向量正交性的观测而实现的,即从中央点q到其邻域点p 的向量和p点处的

图像梯度正交(服从图像和测量噪声)。考虑以下的表达式:

εi=DIpiT•(q-pi)

其中,DIpi表示在q的一个邻域点pi处的图像梯度,q的值通过最小化εi得到。通过将εi设为0,可以建立系统方程如下:

sumi(DIpi•DIpiT)•q - sumi(DIpi•DIpiT•pi) = 0

其中q的邻域(搜索窗)中的梯度被累加。调用第一个梯度参数G和第二个梯度参数b,得到:

q=G-1•b

该算法将搜索窗的中心设为新的中心q,然后迭代,直到找到低于某个阈值点的中心位置。

GoodFeaturesToTrack

确定图像的强角点

void cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, CvArr* temp_image,

CvPoint2D32f* corners, int* corner_count, double quality_level, double min_distance, const CvArr* mask=NULL );

image

输入图像,8-位或浮点32-比特,单通道

eig_image

临时浮点32-位图像,尺寸与输入图像一致

temp_image

另外一个临时图像,格式与尺寸与 eig_image 一致

corners

输出参数,检测到的角点

corner_count

输出参数,检测到的角点数目

quality_level

最大最小特征值的乘法因子。定义可接受图像角点的最小质量因子。

min_distance

限制因子。得到的角点的最小距离。使用 Euclidian 距离

mask

ROI:感兴趣区域。函数在ROI中计算角点,如果 mask 为 NULL,则选择整个图像。必须为单通道的灰度图,大小与输入图像相同。

mask对应的点不为0,表示计算该点。

函数 cvGoodFeaturesToTrack 在图像中寻找具有大特征值的角点。该函数,首先用cvCornerMinEigenVal

计算输入图像的每一个象素点的最小特征值,

并将结果存储到变量 eig_image 中。然后进行非最大值抑制(仅保留3x3邻域中的局部最大值)。

下一步将最小特征值小于 quality_level•max(eig_image(x,y)) 排除掉。最后,函数确保所有发现的角点之间具有足够的距离,

(最强的角点第一个保留,然后检查新的角点与已有角点之间的距离大于 min_distance )。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐