opencv图像处理梯度边缘和角点
来源:互联网 发布:百度推广做淘宝客 编辑:程序博客网 时间:2024/04/28 17:42
转自:http://blog.sina.com.cn/s/blog_4b9b714a0100c9f7.html
梯度、边缘和角点
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 滤波器系数是:
- 对 x-方向 以及转置矩阵对 y-方向。
函数 cvSobel 通过对图像用相应的内核进行卷积操作来计算图像差分:
由于Sobel 算子结合了 Gaussian 平滑和微分,所以,其结果或多或少对噪声有一定的鲁棒性。通常情况,函数调用采用如下参数 (xorder=1, yorder=0, aperture_size=3) 或 (xorder=0, yorder=1, aperture_size=3) 来计算一阶 x- 或 y- 方向的图像差分。第一种情况对应:
核。
第二种对应:
或者
核的选则依赖于图像原点的定义 (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 则给出最快计算结果,相当于对图像采用如下内核做卷积:
类似于 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只接受单通道图像作为输入。
- 外部链接:经典的canny自调整阈值算法的一个opencv的实现见:http://blog.chinaunix.net/u/30231/showart_233944.htm
PreCornerDetect
计算用于角点检测的特征图,
void cvPreCornerDetect( const CvArr* image, CvArr* corners, int aperture_size=3 );
- image
- 输入图像.
- corners
- 保存候选角点的特征图
- aperture_size
- Sobel 算子的核大小(见cvSobel).
函数 cvPreCornerDetect 计算函数 其中 表示一阶图像差分, 表示二阶图像差分。 角点被认为是函数的局部最大值:
// 假设图像格式为浮点数 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),
然后在邻域上计算图像差分的相关矩阵:
然后它计算矩阵的特征值和特征向量,并且按如下方式(λ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)。
子象素级角点定位的实现是基于对向量正交性的观测而实现的,即从中央点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 )。
- opencv图像处理梯度边缘和角点
- OpenCV-Python—图像梯度和Canny边缘检测
- opencv(十三)--边缘检测和梯度
- opencv对图像进行边缘及角点检测
- 【OpenCV】图像变换(二)边缘检测:梯度算子、Sobel算子和Laplace算子
- 图像梯度(水平和垂直梯度)提取边缘信息
- Python+OpenCV学习(4)---图像梯度及边缘检测
- [图像处理]边缘提取以及Harris角点检测
- 【图像处理】MATLAB:点、线、边缘检测
- 一起学opencv(七) 边缘和角点检测
- OpenCV-边缘检测和图像金字塔
- 边缘检测VS梯度图像
- 图像边缘梯度的定义
- 【OpenCV图像处理】二十二、图像边缘检测(上)
- 【OpenCV图像处理】二十三、图像边缘检测(下)
- openCV学习笔记(二)------图像平滑处理和边缘检测
- OpenCV学习笔记(14):形态学滤波对图像进行边缘及角点检测
- opencv 图像的边缘
- 多线程总结
- ”都会“玩命”
- MSSQL 区分大小写 探究
- Linux 入门
- 全局热块冲突(摘自老白的RAC日记)
- opencv图像处理梯度边缘和角点
- device_driver结构体
- 各种数据库的数据类型对比
- C 语言的谜题 —— 细节问题,收益良多
- BacNet开发入门
- 继续找寻高效xml处理引擎
- 在Linux下,利用gSoap生成的WebService客户端进行开发时遇到的问题
- 踏实系统逐步学习QT4.7(1)
- Linux输入子系统