Open CV 图像变换
一、卷积
卷积定义:如果我们定义图像为 I(x,y), 核为 G(i,j) (其中 0 < i < Mi -1 和 0 < j < Mj - 1), 参考点位于相应核的(ai,aj)坐标上,则卷积H(x,y) 定义如下:
opencv 实现:cvFilter2D()
void cvFilter2D ( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchar = cvPoint(-1,-1) );
卷积边界
void cvCopyMakerBorder( const CvArr* src, CvArr* dst, CvPoint offset, int bordertype, CvScalar value = cvScalarAll(0) );
梯度和Sobel 导数
cvSoble( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size = 3 );
Scharr滤波器
OPENCV 通过在cvSobel() 函数中一些特殊 aperture_size值 CV_SCHARR 的隐性使用,以解决小(但是快)的3x3 Sobel 导数滤波器不准确的问题。
拉普拉斯变换
void cvLaplace( const CvArr* src, CvArr* dst, int apertureSize = 3 );
Canny 算子
边缘检测方法
void cvCanny( const CvArr* img, CvArr* edges, double lowThresh, double highThresh, int apertureSize = 3 );
![]() | ![]() |
上下限分别为150和100时,用Canny算子对两幅不同图像进行边缘检测的结果 | 上下限分别为50和10时,用Canny算子对两幅不同图像进行边缘检测的结果 |
霍夫变换
霍夫变换是一种在图像中寻找直线、圆及其他简单形状的方法。原始的霍夫变化是一种直线变换,即在二值图像中寻找直线的一种相对快速方法。变换可以推广到其他普通的情况,而不仅仅是简单的直线。
霍夫线变换
CvSeq* cvHoughLines2( CvArr* image, void* line_storage, int method, double rho, double theta, int threshold, double param1 = 0, double param2 = 0 );
method 参数:CV_HOUGH_STANDARD(SHT), CV_HOUGH_PROBABILISTIC(PPHT)和CV_HOUGH_MULTI_SCALE(SHT)
lines = cvHoughLines2(); for(i = 0 ;i< linges->total;i++) float* line = (float*)cvGetSqlElem(lines,i);
其中lines是从cvHoughLines2()中得到的返回值,i是做关系的线的索引。在这种情形下,line是指向这条直线数据的指针,对于SHT和MSHT,line[0]和line[1]是浮点类型的 ρ 和 θ ,对于PPHT,是线段终点的CvPoint 结构。
![]() |
首先运行Canny边缘检测(参数1=50,参数2=150),结果以灰度图显示。然后运行累计概率的霍夫变换(参数1=50,参数2=10),结果被白色覆盖,可以看到由霍夫变换产生的粗线 |
霍夫圆变换
CvSeq* cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1 = 100, double param2 = 300, int min_radius = 0, int max_radius = 0 );
通过考虑物体是梯度边缘的集合,可以将霍夫圆变换拓展为任意形状。
重映射
void cvRemap() const CvArr* src, CvArr* dst, const CvArr* mapx, const CvArr* mapy, int flags = CV_INTER_LINEAR|CV_WARP_FILL_OUTLINERS, CvScalar fillval = cvScalarAll(0) );
cvWarpAffine() 附加标志为的值
标志位的值 | 意义 |
CV_INTER_NN | 最近邻 |
CV_INTER_LINEAR | 双线性(默认) |
CV_INTER_AREA | 像素区域重新采样 |
CV_INTER_CUBIC | 双三次插值 |
拉伸、收缩、扭曲和旋转
仿射变换
稠密仿射变换
void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags = CV_INTER_LINEAR|CV_WARP_FILL_OUTLIERS, CvScalar fillval = cvScalarAll(0) );
void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix );
仿射映射矩阵的计算
CvMat* cvGetAffineTransform( const CvPoint2D32f* pts_src, const CvPoint2D32f* pts_dst, CvMat* map_matrix )
CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix );
稀疏仿射变换
cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec = NULL );
透视变换
密集透视变换
void cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flages = CV_INTER_LINEAR + CV_WARP_FILL_OUTLINERS, CvScalar fillval = cvScalarAll(0) );
计算机透视映射矩阵
CvMat* cvGetPerspectiveTransform( const CvPoint2D32f* pts_src, const CvPoint2D32f* pts_dst, CvMat* map_matrix );
稀疏透视变换
void cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat );
CartToPolar 与 PolarToCart
void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude, CvArr* angle = NULL, int angle_in_degrees = 0 ); void cvPolarToCart( const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angle_in_degrees = 0 );
LogPolar
![]() |
旋转和缩放正方形的对数极坐标变换:尺寸转到 log(r) 轴的位移,旋转到 θ 轴的位移 |
void cvLogPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double m, int flags = CV_INTER_LINEAR|CV_WARP__FILL_OUTLIERS );
离散傅立叶变换(DFT)
对任意通过离散(整型)参数索引的数值集合,都可以能用类似连续函数的傅立叶变换的形式定义一个离散傅立叶变换(DFT)。
对于 N 个复数: x0,..., xn, 一维的DFT定义为下式(其中 i = √-1):
对于二维数组(当然高维也类似),也可以定义类似的变换:
void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows = 0 );
频谱乘法
void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int falgs );
卷积和DFT
例:用cvDFT() 加快卷积的计算
// Use DFT to accelerate the convolution of array A by kernel B. // Place the result in array V. void speedy_convolution( const CvMat* A, // Size:M1xN1: const CvMat* B, // Size:M2xN2: CvMat* C // size:(A->rows+b->rows-1)x(A->cols+b->cols-1) ) { int dft_M = cvGetOptimalDFTSize( A->rows + B->rows -1 ); int dft_N = cvGetOptimalDFTSize( A->cols + B->cols -1 ); CvMat* dft_A = cvCreateMat( dft_M, dft_N, A->type); CvMat* dft_B = cvCreateMat( dft_M, dft_N, B->type); CvMat tmp; // copy A to dft_A and pad dft_A with zeros cvGetSubRect( dft_A, &tmp, cvRect(0,0, A->cols, A->rows)); cvCopy( A, &tmp); cvGetSubRect( dft_A, &tmp, cvRect( A->cols, 0, dft_A->cols - A->cols, A->rows) ); cvZero( &tmp); // no need to pad bottom part of dft_A with zeros because of // use nonzero_rows parameter in cvDFT() call below cvDFT( dft_A, dft_A, CV_DXT_FORWORD, A->rows); // repeat the same with the second array cvGetSubRect( dft_B, &tmp, cvRect(0,0, B->cols, B->rows); cvCopy( B, &tmp); cvGetSubRect( dft_B, &tmp, cvRect( B->cols, 0, dft_B->cols - B->cols, B->rows) ); cvZero( &tmp); // no need to pad bottom part of dft_B with zeros because of // use nonzero_rows parameter in cvDFT() call below cvDFT( dft_B, dft_B, CV_DXT_FORWARD, B->rows); // or CV_DXT_MUL_CONJ to get correlation rather than convolution cvMulSpectrums( dft_A, dft_B, dft_A, 0); // calculate only the top part cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, C->rows); cvGetSubRect( dft_A, &tmp, cvRect(0,0, conv->cols, C->rows) ); cvCopy( &tmp, C); cvReleaseMat( dft_A); cvReleaseMat( dft_B); }
离散余弦变换(DCT)
void cvDCT( const CvArr* src, CvArr* dst, int flags );
积分图像
void cvIntegral( const CvArr* image, CvArr* sum, CvArr* sqsum = NULL, CvArr* tilted_sum = NULL );
利用这些积分图,可以计算图像的任意直立或“倾斜”的矩形区域的之和、均值和标准差。
距离变换
void cvDistTransform( const CvArr* src, CvArr* dst, int distance_type = CV_DIST_L2, int mask_size = 3, const float* kernel = NULL, CvArr* labels = NULL );
直方图均衡化
void cvEqualizeHist( const CvArr* src, CvArr* dst );
- 上一篇:OpenCV 直方图与匹配
- 下一篇:Open CV 图像处理