opencv图片倾斜矫正


#include
#include
#include

using namespace cv;
using namespace std;
#define ERROR 0.0

/倾斜矫正(霍夫变换)
//显示图片
void show_img(Mat &img) {

    imshow("Test", img);
    waitKey(0);
}
double degreeTrans(double theta) {
    double rst = theta / CV_PI * 180;
    return rst;
}

double calcDegree(Mat &src, int flag = 0) {
    Mat midImg, dstImg;
    vector lines;

    cvtColor(src, midImg, CV_BGR2GRAY);

    Canny(midImg, midImg, 50, 200, 3);

    cvtColor(midImg, dstImg, CV_GRAY2BGR);

    //霍夫直线检测部分可以修改
    int thre = 300; //阈值设定过高导致无法检测直线,阈值过低直线太多,速度很慢
    //int thre = 50;
    HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);

    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        cout << "没有检测到直线:HoughLines " << endl;
        return ERROR;
    }
    //cout << "HoughLines threshold: " << thre << endl;

    float sum = 0;

    for (int i = 0; i < lines.size(); 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));

        sum += theta;

        line(dstImg, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA);
    }

    if (flag) {
        show_img(dstImg);
    }

    float avg = sum / lines.size();

    double angle = degreeTrans(avg) - 90;

    return angle;
}

void rotateImage(Mat &src, Mat &dst, double °ree) {
    Point2f center;
    center.x = float(src.cols / 2.0);
    center.y = float(src.rows / 2.0);
    int length = 0;
    length = sqrt(src.cols*src.cols + src.rows*src.rows);
    //计算二维旋转的仿射变换矩阵
    Mat affineMrt = getRotationMatrix2D(center, degree, 1);
    //仿射变换,背景色填充为白色
    warpAffine(src, dst, affineMrt, Size(length, length), 1, 0, Scalar(255, 255, 255));
}
/倾斜矫正(霍夫变换)

int main()
{
    Mat src = imread("18.jpg",1);//加载没有倾斜的原图像
    Mat dst;
    double degree = 25;//图像设置倾斜角度值
    rotateImage(src,dst,degree);//图像倾斜
    show_img(dst);//显示倾斜后的图像
    //double degrees=calcDegree(dst,1);
    //printf("degree=%f\n",degrees);
    /*
    Mat midImg, dstImg;
    vector lines;

    cvtColor(dst, midImg, CV_BGR2GRAY);

    Canny(midImg, midImg, 50, 200, 3);

    cvtColor(midImg, dstImg, CV_GRAY2BGR);

    //霍夫直线检测部分可以修改
    int thre = 300; //阈值设定过高导致无法检测直线,阈值过低直线太多,速度很慢
    //int thre = 50;
    HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);

    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        thre -= 50;
        HoughLines(midImg, lines, 1, CV_PI / 180, thre, 0, 0);
    }
    if (!lines.size()) {
        cout << "没有检测到直线:HoughLines " << endl;
        return ERROR;
    }
    //cout << "HoughLines threshold: " << thre << endl;

    float sum = 0;

    for (int i = 0; i < lines.size(); 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));

        sum += theta;

        line(dstImg, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA);
    }
        show_img(dstImg);
    float avg = sum / lines.size();

    double angle = degreeTrans(avg) - 90;
    printf("%f\n",angle);
    */
    //获得矫正角度
    Mat dstt;
    double angle = calcDegree(dst,1);
    //图像矫正
    rotateImage(dst,dstt, angle);
    show_img(dstt);//显示矫正后图像
    cvWaitKey(0);
    return 0;
}

opencv图片倾斜矫正_第1张图片

 

opencv图片倾斜矫正_第2张图片

opencv图片倾斜矫正_第3张图片

 

你可能感兴趣的:(opencv图像处理)