多字符直线倾斜旋转校正

 
对于直线倾斜的成串字符 可以通过 开运算连成一片 在用细化算法 求直线 算出倾斜角度 以此纠正
 
 
 
// ration1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#ifdef DEBUG
#pragma comment(lib," opencv_core231d.lib")
#pragma comment(lib,"opencv_features2d231d.lib")
#pragma comment(lib,"opencv_flann231d.lib")
#pragma comment(lib,"opencv_gpu231d.lib")
#pragma comment(lib,"opencv_highgui231d.lib")
#pragma comment(lib,"opencv_imgproc231d.lib")
#else
#pragma comment(lib,"opencv_core231.lib")
#pragma comment(lib,"opencv_features2d231.lib")
#pragma comment(lib,"opencv_flann231.lib")
#pragma comment(lib,"opencv_gpu231.lib")
#pragma comment(lib,"opencv_highgui231.lib")
#pragma comment(lib,"opencv_imgproc231.lib")
#endif
void cvThin( IplImage* src, IplImage* dst, int iterations)
{
    CvSize size = cvGetSize(src);
    cvCopy(src, dst);
    int n = 0,i = 0,j = 0;
    for(n=0; n<iterations; n++)
    {
        IplImage* t_image = cvCloneImage(dst);
        for(i=0; i<size.height; i++)
        {
            for(j=0; j<size.width; j++)
            {
                if(CV_IMAGE_ELEM(t_image,byte,i,j)==1)
                {
                    int ap=0;
                    int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);
                    int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);
                    if (p2==0 && p3==1)
                    {
                        ap++;
                    }
                    int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);
                    if(p3==0 && p4==1)
                    {
                        ap++;
                    }
                    int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);
                    if(p4==0 && p5==1)
                    {
                        ap++;
                    }
                    int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);
                    if(p5==0 && p6==1)
                    {
                        ap++;
                    }
                    int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);
                    if(p6==0 && p7==1)
                    {
                        ap++;
                    }
                    int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);
                    if(p7==0 && p8==1)
                    {
                        ap++;
                    }
                    int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);
                    if(p8==0 && p9==1)
                    {
                        ap++;
                    }
                    if(p9==0 && p2==1)
                    {
                        ap++;
                    }
                    if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7)
                    {
                        if(ap==1)
                        {
                            if(!(p2 && p4 && p6))
                            {
                                if(!(p4 && p6 && p8)) 
                                {
                                    CV_IMAGE_ELEM(dst,byte,i,j)=0;
                                }
                            }
                        }
                    }
                }
            }
        }
        cvReleaseImage(&t_image);
        t_image = cvCloneImage(dst);
        for(i=0; i<size.height; i++)
        {
            for(int j=0; j<size.width; j++)
            {
                if(CV_IMAGE_ELEM(t_image,byte,i,j)==1)
                {
                    int ap=0;
                    int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);
                    int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);
                    if (p2==0 && p3==1)
                    {
                        ap++;
                    }
                    int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);
                    if(p3==0 && p4==1)
                    {
                        ap++;
                    }
                    int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);
                    if(p4==0 && p5==1)
                    {
                        ap++;
                    }
                    int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);
                    if(p5==0 && p6==1)
                    {
                        ap++;
                    }
                    int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);
                    if(p6==0 && p7==1)
                    {
                        ap++;
                    }
                    int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);
                    if(p7==0 && p8==1)
                    {
                        ap++;
                    }
                    int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);
                    if(p8==0 && p9==1)
                    {
                        ap++;
                    }
                    if(p9==0 && p2==1)
                    {
                        ap++;
                    }
                    if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7)
                    {
                        if(ap==1)
                        {
                            if(p2*p4*p8==0)
                            {
                                if(p2*p6*p8==0)
                                {
                                    CV_IMAGE_ELEM(dst, byte,i,j)=0;
                                }
                            }
                        }
                    } 
                }
            }
        } 
        cvReleaseImage(&t_image);
    }
}
void autoCorrection(IplImage * src , int elementx , int elementy)
{
    IplImage * dst = cvCreateImage(cvGetSize(src),8,1);
    //1. 闭运算连成一片
    //创建自定义核
    IplConvKernel * element = cvCreateStructuringElementEx(elementx ,elementy,elementx/2,elementy/2,CV_SHAPE_RECT);
    cvMorphologyEx(src,dst,NULL,element,CV_MOP_CLOSE);
    cvReleaseStructuringElement(&element);
//    cvShowImage("close",dst);
    //2. 细化
    cvThreshold(dst,dst,100,1,CV_THRESH_BINARY);
    IplImage * thin = cvCreateImage(cvGetSize(src),8,1);
    cvThin(dst,thin,elementy);
    cvThreshold(thin,thin,0.5,255,CV_THRESH_BINARY);
    //cvShowImage("thin",thin);
    
    // 3 . hough 找直线
    CvMemStorage * stroge = cvCreateMemStorage(0);
    CvSeq * lines = NULL;
    float *fline,fTheta;
    int angle;
    lines = cvHoughLines2(thin,stroge,CV_HOUGH_STANDARD,2,CV_PI/180,100,0,0);
    
    if (lines->total ==0)
    {
        return
    }
    fline = (float*)cvGetSeqElem(lines,0);
    fTheta = fline[1]; // 过原点与直线垂直的直线与x轴夹角
    angle = (int)(fTheta *180/ CV_PI + 0.5);
    if (angle >= 90 && angle <= 135)
    {
        angle = angle -90;
    }
    else if (angle >0 && angle <= 45)
    {
        
    }
    else if(angle >135 && angle < 180)
    {
        //Rotation(pImageData,nPixelFormatSize,nwidthstep,nwidth,nheight,90 - angle);
        angle = 90 - angle;
    }else if (angle >45 &&angle <90)
    {
        //Rotation(pImageData,nPixelFormatSize,nwidthstep,nwidth,nheight,angle - 90);
        angle = angle -90;
    }
    cvThreshold(src , src ,100,255 , CV_THRESH_BINARY_INV);
    IplImage * ration = cvCreateImage(cvGetSize(src),8,1);
    float m[6];
    CvMat M = cvMat( 2, 3, CV_32F, m );
    CvPoint2D32f pt = cvPoint2D32f(src->width/2.0, src->height/2.0);
    cv2DRotationMatrix(pt, angle, 1.0, &M);
    cvWarpAffine(src,ration,&M,CV_INTER_AREA |CV_WARP_FILL_OUTLIERS,cvScalarAll(255));
    memcpy(src->imageData,ration->imageData,src->imageSize);
    //cvShowImage("ration",ration);
    cvReleaseImage(&ration);
    cvReleaseMemStorage(&stroge);
    cvReleaseImage(&thin);
    cvReleaseImage(&dst);
}
int _tmain(int argc, _TCHAR* argv[])
{
    
    IplImage * src =cvLoadImage("E7.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    cvShowImage("src",src);
    cvThreshold(src, src, 0,255,CV_THRESH_OTSU);
    // 要求背景为黑色纠正物体为白色
    cvThreshold(src , src , 100,255 , CV_THRESH_BINARY_INV);
    autoCorrection(src,70,70);
    cvShowImage("ration",src);
    cvWaitKey(-1);
    getchar();
    return 0;
}





原文地址:https://www.cnblogs.com/xiaomaLV2/p/2576318.html