您的位置:首页 > 运维架构

关于OpenCv图像变换与基本图形检测

2013-01-11 09:52 1061 查看
图像变换值卷积
cvFilter2D -

在空间域中卷积的运算次数为N^2*M^2(其中N为图像的长宽,M为卷积模板的长宽)。但OpenCV有优化的设置。因为在频率域的卷积计算复杂度正比于N^2*log(N)。因此,OpenCV会根据核的大小自动决定是否做频域内的卷积。并且即使在空间域卷积,OpenCV的代码都有系统的优化过。

cvSobel

书上说 OpenCV 通过在cvSobel函数中一些特殊 aperture_size 值CV_SCHARR的隐性使用(翻译的有点问题,句子不通)。实验了一下,用aperture_size =3 以及用aperture_size = CV_SCHARR 效果一样。但是手动编aperture_size =3的sobel则结果不完全一样,精度较低。

laplacian 滤波对噪声敏感。一般用一阶微分算子来进行边缘检测,二阶微分算子用的不多。不过也可以使用laplacian 进行边缘检测。即laplacian 值为0的地方为图像的边缘(包括实质性的和没有意义的)。不过通过一阶(Sobel)导数值很大来过滤这些无意义的边缘。

cvCanny

aperture_size 对结果影响很大。一般取3. 而且aperture_size只能取3,5,9三个数字。影响canny算子的结果是threshold1和threshold2两个参数。

cvHoughCircles,cvHoughLines2

一些例程如下,其中粗斜体为比较影响输出结果的参数(即输出的直线和圆的个数和质量不同),其他的参数对结果的影响我没有怎么实验。

CvSeq* lines;

lines = cvHoughLines2( dst0, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 40, 30, 10 );    for(int i = 0; i < lines->total; i++ )    {     CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);     cvLine( dst, line[0], line[1], CV_RGB(255,0,0), 2, 8 );    }

注:CV_HOUGH_STANDARD 效果没有  CV_HOUGH_PROBABILISTIC 好用。CV_HOUGH_MULTI_SCALE 速度非常慢,效果一般。综合看,CV_HOUGH_PROBABILISTIC 好用。而且对line来说,CV_HOUGH_MULTI_SCALE 和 CV_HOUGH_STANDARD 中 line[0],line[1]分别表示rho和theta。而 CV_HOUGH_PROBABILISTIC 是线段终点的CvPoint结构。

CvSeq* circles ;

circles = cvHoughCircles( dst0, storage, CV_HOUGH_GRADIENT, 2, dst0->height/4.0, 50, 100 );    int i;    for( i = 0; i < circles->total; i++ )    {     float* p = (float*)cvGetSeqElem( circles, i );     cvCircle( dst, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]),CV_RGB(255,0,0), 3, 8, 0 );    }

在用 cvHoughCircles 前,需要cvSmooth,比如cvSmooth( dst,dst, CV_GAUSSIAN, 9, 9 ); 否则会有很多假圆被提取出来。cvHoughCircles 对正圆有效,对椭圆提取效果一般。

cvRemap

图像放大、旋转等几何变换涉及到图像插值。这些问题一般称为正投影问题。为了解决这些四舍五入和目标差异的问题,实际上我们可以反过来解决:通过目标图像中的每一个像素去问:“哪个源像素需要来填补这个目标像素?”这些源像素的位置几乎都是小数(非整数)。所以必须对这些源像素进行插值以得到目标位置的正确值。

cvWarpAffine 和 cvGetQuadrangleSubPix

两个函数都可以做旋转变换,但是两个函数对变换时需要的输入旋转矩阵不相同。

cvWarpAffine 定义如下:

double scale = 0.6;

center = cvPoint2D32f(src->width/2,src->height/2);

CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);       cv2DRotationMatrix(center,(double)angle,scale,rot_mat);

cvGetQuadrangleSubPix 定义如下:

CvMat rot_mat = cvMat( 2, 3, CV_32F, m );

m[0] = (float)(1./scale *cos(-angle*2*CV_PI/180.));       m[1] = (float)(1./scale *sin(-angle*2*CV_PI/180.));       m[2] = center.x;       m[3] = -m[1];       m[4] = m[0];       m[5] = center.y;

cvGetQuadrangleSubPix(src,showImage,&rot_mat);

这两个旋转矩阵不同的原因是: cvWarpAffine 先平移至旋转中心再旋转,然后再平移回来。cvGetQuadrangleSubPix并没有考虑这些,可能在内部实现了。

cvTransform

src必须为N*1的数组。

cvIntergral

积分图像可作为任意尺寸矩形图像求和的快速运算。设I为image的积分图像。则计算左上角坐标(x1,y1)和右下角(x2,y2)的矩形区域像素和的公式为:sum = I(x2,y2)-I(x1-1,y2)-I(x2,y1-1)+I(x1-1,y1-1);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  检测 图形 OpenCv