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

【OpencCV】基于傅立叶变换和霍夫变化的文本倾斜校正

2015-10-28 23:34 211 查看
//此函数应用傅立叶变换进行原始图像倾斜校正
IplImage* mycvRotateImage(const IplImage* src)
{
int op_width = cvGetOptimalDFTSize(src->width);  //获取傅立叶变换的最佳尺寸
int op_height = cvGetOptimalDFTSize(src->height);

IplImage* borderImg = cvCreateImage(cvSize(op_width, op_height), IPL_DEPTH_8U, 1);
cvCopyMakeBorder(src, borderImg, cvPoint(0,0), IPL_BORDER_CONSTANT, cvScalarAll(0));

IplImage* image_real = cvCreateImage(cvGetSize(borderImg), IPL_DEPTH_32F, 1);
IplImage* image_imaginary = cvCreateImage(cvGetSize(borderImg), IPL_DEPTH_32F, 1);
IplImage* fourier = cvCreateImage(cvGetSize(borderImg), IPL_DEPTH_32F, 2);

cvConvertScale(borderImg, image_real, 1, 0);
cvZero(image_imaginary);

cvMerge(image_real, image_imaginary, 0, 0, fourier);
cvDFT(fourier, fourier, CV_DXT_FORWARD);
cvSplit(fourier, image_real, image_imaginary, 0, 0);

cvPow(image_real, image_real, 2.0);
cvPow(image_imaginary, image_imaginary, 2.0);
cvAdd(image_real, image_imaginary, image_real);
cvPow(image_real, image_real, 0.5);

cvAddS(image_real, cvScalar(1.0), image_real);
cvLog(image_real, image_real);

Mat mat = image_real;
mat = mat(Rect(0, 0, mat.cols & -2, mat.rows & -2));

//把低频移动到中心
int cx = mat.cols/2;
int cy = mat.rows/2;

Mat q0(mat, Rect(0, 0, cx, cy));
Mat q1(mat, Rect(0, cy, cx, cy));
Mat q2(mat, Rect(cx, cy, cx, cy));
Mat q3(mat, Rect(cx, 0, cx, cy));

Mat tmp;
q0.copyTo(tmp);
q2.copyTo(q0);
tmp.copyTo(q2);

q1.copyTo(tmp);
q3.copyTo(q1);
tmp.copyTo(q3);

normalize(mat, mat, 0, 1, CV_MINMAX);
Mat magImg(mat.size(), CV_8UC1);
mat.convertTo(magImg,CV_8UC1,255,0);

IplImage* new_real;  //矩阵头换成图像头
new_real = &IplImage(magImg);

cvThreshold(new_real, new_real, 150, 255, CV_THRESH_BINARY);

IplImage* grayImg = cvCreateImage(cvGetSize(new_real), IPL_DEPTH_8U, 1); //转换成cvHoughLines2函数参数形式
cvConvertScale(new_real, grayImg);

CvMemStorage *storage = cvCreateMemStorage();
CvSeq *lines = 0;
lines = cvHoughLines2(grayImg, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100);

//找到符合条件的那条斜线
float angel = 0;
float piThresh = (float)CV_PI/90;
float pi2 = (float)CV_PI / 2;
for (int i = 0; i<lines->total; i++)
{
float *line = (float*)cvGetSeqElem(lines,i);
float rho = line[0];
float theta = line[1];

if (abs(theta) >= piThresh && abs(theta-pi2) >= piThresh)
{
angel = theta;
break;
}
}
angel = angel<pi2 ? angel : (angel-CV_PI);

if (angel != pi2)
{
float angelT = (src->height) * tan(angel) / (src->width);
angel = atan(angelT);
}
float angelD = angel*180/(float)CV_PI;
cout << "The rotation angel to be applied is : " << angelD << endl;

CvMat* rot_mat = cvCreateMat(2, 3, CV_32FC1);
CvPoint2D32f center = cvPoint2D32f((src->width)/2, (src->height)/2);
cv2DRotationMatrix(center, angelD, 1.0, rot_mat);
IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvWarpAffine(src, dst, rot_mat, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(255));

cvNamedWindow("rotateImage", CV_WINDOW_AUTOSIZE);
cvShowImage("rotateImage", dst);

cvReleaseMemStorage(&storage);

cvReleaseImage(&image_real);
cvReleaseImage(&image_imaginary);
cvReleaseImage(&fourier);
cvReleaseImage(&borderImg);

return dst;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: