1

Here in this code i am detecting a sheet of paper Steps that i used 1.Apply houghLine transform 2.Detect corner 3.Applied perspective transform.

Please can anybody tell me why the codes is not working on all the images, it only works for one or two images.

it works on this image

sheet2

sheet

but when i used some other image instead of this then i am getting error

sheet2

#include <cv.h>
#include <highgui.h>


using namespace std;
using namespace cv;


Point2f center(0,0);

Point2f computeIntersect(Vec4i a, Vec4i b)
{
    int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
    float denom;

    if (float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
    {
        Point2f pt;
        pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
        pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
        return pt;
    }
    else
        return Point2f(-1, -1);
}

void sortCorners(vector<Point2f>& corners, Point2f center)
{
    vector<Point2f> top, bot;

    for (int i = 0; i < corners.size(); i++)
    {
        if (corners[i].y < center.y)
            top.push_back(corners[i]);
        else
            bot.push_back(corners[i]);
    }
    corners.clear();

    if (top.size() == 2 && bot.size() == 2){
        Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
        Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
        Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];
        Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];


        corners.push_back(tl);
        corners.push_back(tr);
        corners.push_back(br);
        corners.push_back(bl);
    }
}

int main()
{
    Mat src,cann,hsv;
    src = imread("C:\\im.jpg",WINDOW_AUTOSIZE);

    if (src.empty())
        return -1;

    imshow("original",src);

    blur(src, src, Size(3, 3));
    Canny(src, cann, 50, 200, 3);
    cvtColor(cann, hsv, CV_GRAY2BGR);

    vector<Vec4i> lines;
    HoughLinesP(cann, lines, 1, CV_PI/180, 70, 30, 10);
    for( size_t i = 0; i < lines.size(); i++ )
    {
        Vec4i l = lines[i];
        line( hsv, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 2, CV_AA);
    } 

    // Expand the lines
    for (int i = 0; i < lines.size(); i++)
    {
        Vec4i v = lines[i];
        lines[i][0] = 0;
        lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2]) * -v[0] + v[1]; 
        lines[i][2] = src.cols; 
        lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2]) * (src.cols - v[2]) + v[3];
    }

    vector<Point2f> corners;
    for (int i = 0; i < lines.size(); i++)
    {
        for (int j = i+1; j < lines.size(); j++)
        {
            Point2f pt = computeIntersect(lines[i], lines[j]);
            if (pt.x >= 0 && pt.y >= 0)
                corners.push_back(pt);
        }
    }

    vector<Point2f> approx;
    approxPolyDP(Mat(corners), approx, arcLength(Mat(corners), true) * 0.02, true);

    //if (approx.size() != 4)
//  {
    //  cout << "The object is not quadrilateral!" << endl;
        //return -1;
    //}



    // Get mass center
    for (int i = 0; i < corners.size(); i++)
        center += corners[i];

    center *= (1. / corners.size());

    sortCorners(corners, center);
    if (corners.size() == 0)
    {
        cout << "The corners were not sorted correctly!" << endl;
        return -1;
    }

    Mat dst = src.clone();

    // Draw lines
    for (int i = 0; i < lines.size(); i++)
    {
        Vec4i v = lines[i];
        line(dst, Point(v[0], v[1]), Point(v[2], v[3]), CV_RGB(0,255,0));
    }

    // Draw corner points
    circle(dst, corners[0], 3, CV_RGB(255,0,0), 2);
    circle(dst, corners[1], 3, CV_RGB(0,255,0), 2);
    circle(dst, corners[2], 3, CV_RGB(0,0,255), 2);
    circle(dst, corners[3], 3, CV_RGB(255,255,255), 2);
    // Draw mass center
    circle(dst, center, 3, CV_RGB(255,255,0), 2);

    Mat quad = Mat::zeros(300, 220, CV_8UC3);

    vector<Point2f> quad_pts;
    quad_pts.push_back(Point2f(0, 0));
    quad_pts.push_back(Point2f(quad.cols, 0));
    quad_pts.push_back(Point2f(quad.cols, quad.rows));
    quad_pts.push_back(Point2f(0, quad.rows));

    Mat transmtx = getPerspectiveTransform(corners, quad_pts);
    warpPerspective(src, quad, transmtx, quad.size());

    imshow("blurr",src);
    imshow("canney",cann);
    imshow("hough",hsv);
    imshow("image", dst);
    imshow("quadrilateral", quad);

    waitKey(0);
    return 0;
}
Spektre
  • 49,595
  • 11
  • 110
  • 380
Chandan
  • 61
  • 1
  • 7
  • what's the error you have? – hiroki Feb 12 '17 at 03:45
  • 'sheet1-10.exe' (Win32): Loaded 'C:\Windows\syswow64\dwmapi.dll'. Cannot find or open the PDB file. The thread 0x34b4 has exited with code -1 (0xffffffff). The thread 0x2aa0 has exited with code -1 (0xffffffff). The thread 0x3768 has exited with code -1 (0xffffffff). The program '[13148] sheet1-10.exe' has exited with code -1 (0xffffffff). – Chandan Feb 12 '17 at 04:28
  • i am not understanding why the code is not working for all the images – Chandan Feb 12 '17 at 04:29
  • That error has nothing to do with the image content. Please actually step through your code with a debugger and tell us where the actual error is occurring and what it is. – rayryeng Feb 12 '17 at 07:10
  • vector approx; approxPolyDP(Mat(corners), approx, arcLength(Mat(corners), true) * 0.02, true); if (approx.size() != 4) { cout << "The object is not quadrilateral!" << endl; return -1; }-------------after this code the their might be some problem as quadrilateral is not able to get from it – Chandan Feb 12 '17 at 09:09
  • see [OpenCV Birdseye view without loss of data](http://stackoverflow.com/a/39316776/2521214) and [How can picture of page be straightened out to look as if it was scanned?](http://stackoverflow.com/a/42173573/2521214). What kind of debuging you did ? I would start with gfx overlay of detected corners.... if they are wrong for some images then the rest can not work properly ... – Spektre Feb 13 '17 at 08:04

0 Answers0