opencv几个自动检测图片方向的方法

有以下3种方法,minAreaRect就是将图像的有效点用一个矩形逼近,通过矩形的中心角计算偏转。存在目标图像过小就无效了。

2 PCA 计算主成份,算出角度,但是。存在目标图像过小就无效了。

3 DFT 貌似图小了,也可以看到频域的变化,可以进一步研究。

 

 

1 minAreaRect

//自动检测角度,只能针对背景简单的图来检测
//如果一个人手拿的纸文件是倾斜的,但整体是正向的,根本检测不出来
double getRotateDegreeWithSimpleBackGround(Mat img)
{
     

        int w = img.cols;
        int h = img.rows;
        Mat   resultColor, resultGray, whiteImage;
        double whitePoints = filteredRed(img, resultGray, resultColor, whiteImage);

        imshow("resultGray", resultGray);
        vector<Point> points;
        for (int x = 0; x < h; x++)
            for (int y = 0; y < w; y++)
            {

                int P = resultGray.at<uchar>(x, y);
                if (P == 0)
                {
                    Point pt;
                    pt.x = x;
                    pt.y = y;
                    points.push_back(pt);

                }

            }

        RotatedRect box = minAreaRect(Mat(points));

        cout << box.angle << endl;
        Mat NewDegreeImage;
        if (box.angle < -45)box.angle += 90;
        //旋转这块可以围绕那个中心左右转成功率高些 
        rotateImage1(img, NewDegreeImage, box.angle, 0);
        imshow("NewDegreeImage", NewDegreeImage);
        imshow("whiteImage", whiteImage);
        return box.angle;
     

}

 

2 PCA方法
int getRotateDegreeUsingPCA(Mat src, Mat ibw)
{
    // Load image
 // Mat src = imread("pca_test1.jpg");
//      Mat src = imread(argv[1]);
    // Check if image is loaded successfully
    if (!src.data || src.empty())
    {
        cout << "Problem loading image!!!" << endl;
        return EXIT_FAILURE;
    }
    imshow("src", src);
    // Convert image to grayscale
     Mat gray;
     cvtColor(src, gray, COLOR_BGR2GRAY);
    // Convert image to binary
     Mat bw;
     threshold(gray, bw, 50, 255,  THRESH_BINARY | THRESH_OTSU);
    // Find all the contours in the thresholded image
    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    //findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    findContours(bw, contours, hierarchy,  RETR_LIST,  CHAIN_APPROX_NONE);
    for (size_t i = 0; i < contours.size(); ++i)
    {
        // Calculate the area of each contour
        double area = contourArea(contours[i]);
        // Ignore contours that are too small or too large
        if (area < 1e2 || 1e5 < area) continue;
        // Draw each contour only for visualisation purposes
        drawContours(src, contours, static_cast<int>(i), Scalar(0, 0, 255), 2, 8, hierarchy, 0);
        // Find the orientation of each shape
        getOrientation(contours[i], src);
    }
    imshow("output", src);
//    waitKey(0);
    return 0;

3 DFT

//传入参数为灰度图
//图像必须足够大才会影响整体的DTE变换
double getRotateDegreeUsingDFT(Mat srcImg,Mat resultlImg)
{
#define GRAY_THRESH 100
#define HOUGH_VOTE 50
//    const char* filename = "imageText.jpg";
    //Mat srcImg = imread(filename,cv::IMREAD_GRAYSCALE);
    if (srcImg.empty())
        return -1;
    imshow("source", srcImg);

    Point center(srcImg.cols / 2, srcImg.rows / 2);

#ifdef DEGREE
    //Rotate source image
    Mat rotMatS = getRotationMatrix2D(center, DEGREE, 1.0);
    warpAffine(srcImg, srcImg, rotMatS, srcImg.size(), 1, 0, Scalar(255, 255, 255));
    imshow("RotatedSrc", srcImg);
    //imwrite("imageText_R.jpg",srcImg);
#endif

    //Expand image to an optimal size, for faster processing speed
    //Set widths of borders in four directions
    //If borderType==BORDER_CONSTANT, fill the borders with (0,0,0)
    Mat padded;
    int opWidth = getOptimalDFTSize(srcImg.rows);
    int opHeight = getOptimalDFTSize(srcImg.cols);
 
    copyMakeBorder(srcImg, padded, 0, opWidth - srcImg.rows, 0, opHeight - srcImg.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
    Mat comImg;
    //Merge into a double-channel image
    merge(planes, 2, comImg);

    //Use the same image as input and output,
    //so that the results can fit in Mat well
    dft(comImg, comImg);

    //Compute the magnitude
    //planes[0]=Re(DFT(I)), planes[1]=Im(DFT(I))
    //magnitude=sqrt(Re^2+Im^2)
    split(comImg, planes);
    magnitude(planes[0], planes[1], planes[0]);

    //Switch to logarithmic scale, for better visual results
    //M2=log(1+M1)
    Mat magMat = planes[0];
    magMat += Scalar::all(1);
    log(magMat, magMat);

    //Crop the spectrum
    //Width and height of magMat should be even, so that they can be divided by 2
    //-2 is 11111110 in binary system, operator & make sure width and height are always even
    magMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));

    //Rearrange the quadrants of Fourier image,
    //so that the origin is at the center of image,
    //and move the high frequency to the corners
    int cx = magMat.cols / 2;
    int cy = magMat.rows / 2;

    Mat q0(magMat, Rect(0, 0, cx, cy));
    Mat q1(magMat, Rect(0, cy, cx, cy));
    Mat q2(magMat, Rect(cx, cy, cx, cy));
    Mat q3(magMat, 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 the magnitude to [0,1], then to[0,255]
    normalize(magMat, magMat, 0, 1,  cv::NORM_MINMAX);
    Mat magImg(magMat.size(), CV_8UC1);
    magMat.convertTo(magImg, CV_8UC1, 255, 0);
    imshow("magnitude", magImg);
    //imwrite("imageText_mag.jpg",magImg);

    //Turn into binary image
     
    threshold(magImg, magImg, GRAY_THRESH, 255,  THRESH_BINARY);
    imshow("mag_binary", magImg);
    //imwrite("imageText_bin.jpg",magImg);

    //Find lines with Hough Transformation
    vector<Vec2f> lines;
    float pi180 = (float)CV_PI / 720;
    Mat linImg(magImg.size(), CV_8UC3);
    HoughLines(magImg, lines, 1, pi180, HOUGH_VOTE, 0,5);
    //HoughLinesP(dst, lines, 1, CV_PI / 720, 30, roiImage.rows / 3, 3);
    int numLines = lines.size();
    for (int l = 0; l < numLines; l++)
    {
        float rho = lines[l][0], theta = lines[l][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));
        line(linImg, pt1, pt2, Scalar(255, 0, 0), 3, 8, 0);
    }
    imshow("lines", linImg);
    //imwrite("imageText_line.jpg",linImg);
    if (lines.size() == 3) {
        cout << "found three angels:" << endl;
        cout << lines[0][1] * 180 / CV_PI << endl << lines[1][1] * 180 / CV_PI << endl << lines[2][1] * 180 / CV_PI << endl << endl;
    }

    //Find the proper angel from the three found angels
    float angel = 0;
    float piThresh = (float)CV_PI / 90;
    float pi2 = CV_PI / 2;
    for (int l = 0; l < numLines; l++)
    {
        float theta = lines[l][1];
        if (abs(theta) < piThresh || abs(theta - pi2) < piThresh)
            continue;
        else {
            angel = theta;
            break;
        }
    }

    //Calculate the rotation angel
    //The image has to be square,
    //so that the rotation angel can be calculate right
    angel = angel < pi2 ? angel : angel - CV_PI;
    if (angel != pi2) {
        float angelT = srcImg.rows*tan(angel) / srcImg.cols;
        angel = atan(angelT);
    }
    float angelD = angel * 180 / (float)CV_PI;
    cout << "the rotation angel to be applied:" << endl << angelD << endl << endl;

    //Rotate the image to recover
    Mat rotMat = getRotationMatrix2D(center, angelD, 1.0);
    Mat dstImg = Mat::ones(srcImg.size(), CV_8UC3);
    warpAffine(srcImg, dstImg, rotMat, srcImg.size(), 1, 0, Scalar(255, 255, 255));
    imshow("DFT旋转结果", dstImg);
    //imwrite("imageText_D.jpg",dstImg);
    resultlImg=dstImg;
    //waitKey(0);
}

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenCV遮挡检测是指检测图像中物体与其他物体之间的遮挡情况,确定一个物体是否被完全或部分遮挡。这在许多计算机视觉应用程序中都是非常重要的问题,例如物体跟踪、运动分析和自动驾驶等领域。 OpenCV提供了多种方法来实现遮挡检测。例如,可以使用两个目标的轮廓检测来确定它们之间是否有重叠区域,或者可以比较两个物体之间的颜色差异。另外,还可以使用形状匹配算法、卷积神经网络(CNN)等方法,来实现遮挡检测。 在实际应用中,由于物体的遮挡情况多种多样,因此需要采用不同的方法和算法来检测和处理。此外,由于OpenCV是一个基于开源的计算机视觉库,因此有许多社区提供的工具和应用程序可以帮助开发人员更好地实现并调整遮挡检测算法,从而适应各种实际场景的需求。 ### 回答2: OpenCV是一种开源计算机视觉库,提供了很多图像处理函数。OpenCV的遮挡检测可以用于识别图像中的遮挡物,以及确定图像中遮挡物的边界。 opencv的遮挡检测算法主要通过检测图像中不同区域的纹理、颜色、亮度等特征来判断是否存在遮挡。通常,遮挡物会导致图像中出现不连续的区域和缺失的信息。因此,利用这些特征可以有效地检测出遮挡物。 可以采用OpenCV中的函数实现遮挡检测。首先,需要提取图像的特征,例如颜色、纹理和边缘等。然后,可以利用这些特征来获取图像中的不同区域。接下来,可以使用像素值、纹理方向和颜色分布等信息来比较不同区域之间的相似性,并确定是否存在遮挡。如果相邻区域之间的相似度较低,则可以确定存在遮挡。 具体实现中,可以使用不同的算法和技术来提高遮挡检测的精度,例如直方图均衡、形态学操作、背景差分等。同时,还需要考虑到图像中不同物体的大小、形状和位置等因素,以及图像中存在的噪声和光照变化等问题。 总之,OpenCV的遮挡检测可以用于识别图像中的遮挡物,可以应用于多个领域,例如机器人视觉、自动驾驶、视频监控等。 ### 回答3: OpenCV遮挡检测是一个计算机视觉领域的研究方向,旨在解决目标被遮挡时的检测问题。目前,遮挡检测在自动驾驶、视频监控、人脸识别等领域应用广泛。 遮挡检测可以分为基于传统算法和深度学习算法两个方向。传统算法主要是通过目标的外观和运动信息建立模型,检测目标运动的异常,从而判断是否被遮挡。深度学习算法则是利用深度卷积神经网络对目标的特征表达进行学习,并在训练的过程中对被遮挡物体进行显式建模,从而提高遮挡检测的准确率。 在实现遮挡检测功能时,需要实现以下几个步骤。首先,需要对图像或视频进行处理,提取目标的特征信息。然后,根据目标的外观和运动信息建立模型,对目标进行跟踪和预测,判断其是否遮挡。最后,根据检测结果进行后续处理,例如遮挡区域的标记或对目标进行重新定位等。 与传统的目标检测不同,遮挡检测需要考虑目标被遮挡的情况,因此需要更加复杂的算法和流程。但在实际应用中,遮挡检测可以提高系统的可靠性和安全性,降低误判率和漏检率,为人类生活和工作带来更多便利和安全保障。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值