我自己写的倾斜校正
下面的大概意思是,首先进行canny变换,以突出轮廓,再进行hough变换查找出直线,但是这样查找出的直线的倾角过小,通过这个倾斜角进行仿射变换,再进行变换。。。。直到大于10次,循环停止。
代码如下:
#include"cvHead.h"
#include"car_type.h"
#include<math.h>
void swapPoint(CvPoint *line);
template <class T>
void smallToBig(T* a, int n)
{
T temp;
//采用冒泡法进行排序
for (int i=0; i<n-1; i++)
{
for (int j=0; j<n-i-1; j++)
{
if (*(a+j)>*(a+j+1))
{
temp = *(a+j);
*(a+j) = *(a+j+1);//a[j] = a[j+1];
*(a+j+1)= temp;
}
}
}
}
/*
交换两个cvpoint类型的值。
*/
void swapPoint(CvPoint *line)
{
CvPoint temp ;
if(line[0].x < line[1].x)//如果line【0】 在line【1】的右侧
{
temp = line[0];
line[0] = line[1];
line[1] = temp;
}
}
int tilt_correct_ext(IplImage *img )//输入图像为灰度图像。
{
IplImage *img_dst = cvCreateImage(cvGetSize(img),8,1);
IplImage *color_dst = cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(img,color_dst,CV_GRAY2BGR );
cvCanny(img,img_dst,50,200,3);
cvShowImage("tilt_canny",img_dst);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
for(int i=0;i<10;i++)
{
cvCanny(img,img_dst,50,200,3);
lines = cvHoughLines2( img_dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 140, 200, 20 );
float tanTheta = 0;
double theta = 0;
float a = 0;
float b = 0;
int count = 0;
int count_temp =0;
int count_ter =0;
double *pTheta0= (double* )malloc(lines->total * sizeof(double) );
double * pTheta = pTheta0;
//pTheta0初始化;
for(int i=0;i<lines->total ;i++)
{
*pTheta = 0;
pTheta++;
}
pTheta = pTheta0;
for(int i = 0; i < lines->total; i++ )
{
count_temp ++;
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 1, 8 );
swapPoint(line);
a = fabs( (float)line[0].y - line[1].y );
b = fabs( (float)line[0].x - line[1].x );
if( b <0.01)//90°
continue;
tanTheta = a/b;
theta = atan(tanTheta);
if(theta >CV_PI/8)
continue;
//判断正负角
if(line[0].y >line[1].y )
theta = 0-theta;
*pTheta = theta;
pTheta++;
count++;
cout<<i<<" "<<theta<<endl;
}//小for
smallToBig(pTheta0,count);
double thetaMedia = *(pTheta0+(int)(count/1.5+0.5) );
free(pTheta0);//释放内存
thetaMedia = 0-(thetaMedia*180/2/CV_PI);
cout<<"thetatAvg_du "<<thetaMedia<<endl;
float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );
CvPoint2D32f center;
center.x=float (img_dst->width/2.0+0.5);
center.y=float (img_dst->height/4.0+0.5);
cv2DRotationMatrix( center, thetaMedia,1, &M);
cvWarpAffine(img_dst,img_dst, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );
cvWarpAffine(img,img, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );
cvShowImage("img_wrap",img);
cvShowImage("color_tielllll",color_dst);
cvWaitKey();
if(fabs(thetaMedia) <0.01)//如果需要旋转的角度小于0.05停止旋转。
break;
}//大for
cvShowImage("img_wrap",img);
//清理内存
cvReleaseMemStorage(&storage);
cvReleaseImage(&img_dst);
cvReleaseImage(&color_dst);
//少清理seq的lines
return 0;
}
小弟初学,还请大牛赐教啊