opencv倾斜校正(C++版)

校正图片样例:

image
image
image

上图1\2\3分别为常见的几种需要倾斜校正处理的样例。

对于不同样式的图片倾斜校正的思路是不同的:

图1中边界信息明显,可以通过findcontours函数检测轮廓矩阵获得角度从而进行旋转校正。

图2中没有明显边界,但是每行文字信息比较明显,因此可以通过canny函数进行边缘检测,根据一行一行的文字信息确定角度从而进行校正。

图3是真实场景中随意的一张表单照片(重要信息打码啦~~),图片中的表单没有明显的轮廓信息(人类随手拍的),图像文字多为短小、不连续噪音较多,但是笔直的表格线是可以看到的,因此采用检测表格线的方式进行校正。

总体思路:

1、图像预处理

2、用霍夫线变换检测直线

3、对直线做筛选并对角度做统计

4、角度频率最高的直线的角度做为旋转角度返回。(之后就可以根据这个角度进行旋转啦)

代码实现过程中需要注意的点:

1)图像的预处理(根据样本及需求选择预处理方案)

2)霍夫线变换进行检测,调参,了解每个参数的含义

3)直线的角度、弧度的转换

4)选角度均值或是频率最高的值作为最佳旋转角度(选择最优算法策略)

实现代码如下:


//小角度旋转函数
float get_one_small_angle(cv::Mat &img, int max_angle)//传入图像img,倾斜校正允许的最大旋转角度max_angle
{
    cv::Mat m, gray, bi;

    float scale_v = resize_img(img, m);
    m = img.clone();
    //图像预处理(根据需要选择预处理方式)
    cv::cvtColor(m, gray, CV_BGR2GRAY);
    trans_bright(gray);//转换明亮度
    //enhance
    imgEnhanceBrightness(gray);//亮度增强

    int T_length = gray.cols > gray.rows ? gray.rows : gray.cols;
    adaptiveThreshold(gray, bi, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, 21, 10);
    medianBlur(bi,bi,3);
    scale_v = resize_img(bi, bi);//二值化

    vector<Vec2f> lines;
    //霍夫线变换检测直线,第五个参数直线的长度阈值,是大于该阈值则认为是一条直线
    HoughLines(bi, lines, 1, CV_PI / 180, 90, 80, 8);

    Mat imtest(bi.rows, bi.cols, CV_8UC3, Scalar(255, 255, 255));//构造一个测试图片
    std::map<int,int> angle_map;
    int cnt = 0;
    int max_cnt = 0;

    float best_angle=0.0;

    int max_iter=300;//检到几十万条线,只取300个,否则循环太慢
    if(lines.size()<300)
        max_iter = lines.size();

    for (size_t i = 0; i < max_iter; i++)
    {
        float rho = lines[i][0];
        float theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000 * (-b));
        pt1.y = cvRound(y0 + 1000 * (a));
        pt2.x = cvRound(x0 - 1000 * (-b));
        pt2.y = cvRound(y0 - 1000 * (a));
        int length_pt = disPt2Pt(pt1,pt2);
        if(length_pt < (T_length * 0.05)) continue;
        Point pt_mid((pt1.x+pt2.x)/2,(pt1.y+pt2.y)/2);

        //弧度角度注意转换
        float ang_ = atan2((pt2.y-pt1.y)*1.0, (pt2.x-pt1.x)*1.0);
        float theta1 = CV_PI/2 + ang_;
        float fangle = theta1 / CV_PI * 360;
        fangle = round(180 - fangle);//角度四舍五入

        if(abs(fangle)<max_angle && pt_mid.y>bi.rows*0.15 && pt_mid.y < bi.rows*(1-0.15))
        {//直线的角度小于最大倾斜角,且直线既不偏上又不偏下
            cnt++;

            cv::line(imtest, pt1, pt2, Scalar(0,0,0),2);//在imtest上画线

            if(angle_map.end() == angle_map.find(fangle))
            {
                angle_map[fangle] = 1;//map中没有这个角度,则记为1
            }
            else//若角度存在,则+1,并且将频率最高的角度记为最佳角度
            {
                angle_map[fangle]++;
                if(angle_map[fangle]>max_cnt){
                    max_cnt = angle_map[fangle];
                    best_angle = fangle;
                }
            }
        }

//        imshow("linesImg", imtest);
    }

    return best_angle;
}

参考:

OpenCV探索之路(十六):图像矫正技术深入探讨 - Madcola - 博客园

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281

推荐阅读更多精彩内容