Open CV 图像变换

一、卷积

卷积定义:如果我们定义图像为 I(x,y), 核为 G(i,j) (其中 0 < i < Mi -1 和 0 < j < Mj - 1), 参考点位于相应核的(ai,aj)坐标上,则卷积H(x,y) 定义如下:

image.png

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 导数滤波器不准确的问题。


拉普拉斯变换

image.png

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
);
1569118542703166.png1569118345917462.png
上下限分别为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 结构。


1569120006444687.png
首先运行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

1569137422486288.png
旋转和缩放正方形的对数极坐标变换:尺寸转到 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):

image.png

对于二维数组(当然高维也类似),也可以定义类似的变换:

image.png

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)

image.png

void cvDCT(
    const CvArr* src,
    CvArr* dst,
    int flags
);


积分图像

void cvIntegral(
    const CvArr* image,
    CvArr* sum,
    CvArr* sqsum = NULL,
    CvArr* tilted_sum = NULL
);

1569142448948414.png

利用这些积分图,可以计算图像的任意直立或“倾斜”的矩形区域的之和、均值和标准差。


距离变换

1569149530419085.png

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 C/C++
相关文章
评论留言
发布留言