Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Deskew Image using FitElipse angle

I am preparing an image containing a character (the digit '4') for subsequent OCR.

I start by fit an ellipse to a thresholded image, then deskew it using the angle of the elipse as the input to a rotation matix followed by an affine transform.C:\fakepath\4.png

Despite my best attempts and the various workarounds suggested for the angle returned from fitelipse, i cannot get the letter vertically aligned.

code is as follows and the results attached

C:\fakepath\elipse.png C:\fakepath\threshold.png C:\fakepath\Rotated.png

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    int affineFlags = WARP_INVERSE_MAP|INTER_LINEAR;
    Mat input = Imgcodecs.imread("4.png");
    Mat grayImage = new Mat(input.size(), CV_8UC1 );

    // convert the frame in gray scale
    Imgproc.cvtColor(input, grayImage, Imgproc.COLOR_BGR2GRAY);

    Core.bitwise_not(grayImage, grayImage);
    Mat threshold = new Mat(grayImage.rows(), grayImage.cols(),grayImage.type());
    Imgproc.threshold(grayImage, threshold, 0, 255, THRESH_OTSU);

    Imgcodecs.imwrite("threshold.png", threshold);
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();

    Imgproc.findContours(threshold, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    double angle=0;

    for(MatOfPoint mp : contours)
    {
        //RotatedRect rr = Imgproc.minAreaRect(new MatOfPoint2f(mp.toArray()));

        if(mp.total() > 35) // Cheat to find the biggest contour.
        {
            RotatedRect elipse = Imgproc.fitEllipse(new MatOfPoint2f(mp.toArray()));
            Imgproc.ellipse(input, elipse, new Scalar(0,255,0));
            angle = elipse.angle;               
        }

    }

    Imgcodecs.imwrite("elipse.png", input);


    Point center = new Point(threshold.cols() /2 ,threshold.rows()/2);

    Mat rotMat = Imgproc.getRotationMatrix2D(center,angle , 1.0 );
    Mat imgOut = Mat.zeros(input.rows(), input.cols(), input.type());
    Imgproc.warpAffine(threshold, imgOut, rotMat, imgOut.size(), affineFlags);
    Imgcodecs.imwrite("Rotated.png", imgOut);

Deskew Image using FitElipse angle

I am preparing an image containing a character (the digit '4') for subsequent OCR.

I start by fit an ellipse to a thresholded image, then deskew it using the angle of the elipse as the input to a rotation matix followed by an affine transform.C:\fakepath\4.png

Despite my best attempts and the various workarounds suggested for the angle returned from fitelipse, i cannot get the letter vertically aligned.

code is as follows and the results attached

C:\fakepath\elipse.png C:\fakepath\threshold.png C:\fakepath\Rotated.png

Latest Rotated

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    int affineFlags = WARP_INVERSE_MAP|INTER_LINEAR;
    Mat input = Imgcodecs.imread("4.png");
    Mat grayImage = new Mat(input.size(), CV_8UC1 );

    // convert the frame in gray scale
    Imgproc.cvtColor(input, grayImage, Imgproc.COLOR_BGR2GRAY);

    Core.bitwise_not(grayImage, grayImage);
    Mat threshold = new Mat(grayImage.rows(), grayImage.cols(),grayImage.type());
    Imgproc.threshold(grayImage, threshold, 0, 255, THRESH_OTSU);

    Imgcodecs.imwrite("threshold.png", threshold);
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();

    Imgproc.findContours(threshold, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    double angle=0;

    for(MatOfPoint mp : contours)
    {
        //RotatedRect rr = Imgproc.minAreaRect(new MatOfPoint2f(mp.toArray()));

        if(mp.total() > 35) // Cheat to find the biggest contour.
        {
            RotatedRect elipse = Imgproc.fitEllipse(new MatOfPoint2f(mp.toArray()));
            Imgproc.ellipse(input, elipse, new Scalar(0,255,0));
            angle = elipse.angle;               
        }

    }

    Imgcodecs.imwrite("elipse.png", input);


    Point center = new Point(threshold.cols() /2 ,threshold.rows()/2);

    Mat rotMat = Imgproc.getRotationMatrix2D(center,angle , 1.0 );
    Mat imgOut = Mat.zeros(input.rows(), input.cols(), input.type());
    Imgproc.warpAffine(threshold, imgOut, rotMat, imgOut.size(), affineFlags);
    Imgcodecs.imwrite("Rotated.png", imgOut);