Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Difference in output of minAreaRect in python and c++

I am doing text skewness correction and when I wrote the same code in python and c++ the results are different for the box angle Here is the Python version
```

import numpy as np
import cv2 as cv


def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--image", required=True, help="path to input image file")
    args = vars(parser.parse_args())
    image = cv.imread(cv.samples.findFile(args["image"]))
    if image is None:
        print("can't read image " + args["image"])
        sys.exit(-1)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    gray = cv.bitwise_not(gray)

    # threshold the image, setting all foreground pixels to
    # 255 and all background pixels to 0
    thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
    coords = np.column_stack(np.where(thresh > 0))
    angle = cv.minAreaRect(coords)[-1]
    print(cv.minAreaRect(coords))
    #print(coords)
    print(angle)
    # the `cv.minAreaRect` function returns values in the
    # range [-90, 0); as the rectangle rotates clockwise the
    # returned angle trends to 0 -- in this special case we
    # need to add 90 degrees to the angle
    if angle < -45:
        angle = -(90 + angle)

    # otherwise, just take the inverse of the angle to make
    # it positive
    else:
        angle = -angle
    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv.warpAffine(image, M, (w, h), flags=cv.INTER_CUBIC, borderMode=cv.BORDER_REPLICATE)
    cv.putText(rotated, "Angle: {:.2f} degrees".format(angle), (10, 30), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    # show the output image
    print("[INFO] angle: {:.3f}".format(angle))
    cv.imshow("Input", image)
    cv.imshow("Rotated", rotated)
    cv.waitKey(0)

if __name__ == "__main__":
main()

C++ code

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
#include <string>
using namespace cv;
using namespace std;



int main( int argc, char** argv )
{
Mat image=imread(samples::findFile(imageName));
if(image.empty()){
    cout<<"Cannot load the image "+imageName<<endl;
    return -1;
}
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY );
bitwise_not(gray,gray);

Mat thresh;
threshold(gray,thresh,0,255,THRESH_BINARY | THRESH_OTSU);
vector<Point>coords;
findNonZero(thresh,coords);
cout<<coords.size()<<"\n";
RotatedRect box=minAreaRect(coords);
double angle=box.angle;
cout<<box.angle<<"\n";
if(angle<-45)
    angle=-(90+angle);
else
    angle=-angle;

Point2f center((image.cols)/2.0, (image.rows)/2.0);
Mat M=getRotationMatrix2D(center, angle, 1.0);
Mat rotated;
warpAffine(image,rotated,M,image.size(),INTER_CUBIC,BORDER_REPLICATE);
putText(rotated,"Angle "+to_string(angle)+" degrees",Point(10,30),FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 0, 255), 2);
cout<<"The image is rotated by "<<angle<<endl;
imshow("Input",image);
imshow("Rotated",rotated);
waitKey(0);
return 0;

}

Python version gives angle asprint(angle) gives -80.69794464111328```

where as C++ gives angle as cout<<box.angle gives -9.30206 we can see that these are complimentary of each other is their a difference in the angle notations in c++ and python versions
C++ opencv version 4.1.2
Python opencv version 4.2.0

Difference in output of minAreaRect in python and c++

I am doing text skewness correction and when I wrote the same code in python and c++ the results are different for the box angle Here is the Python version
```

import numpy as np
import cv2 as cv


def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--image", required=True, help="path to input image file")
    args = vars(parser.parse_args())
    image = cv.imread(cv.samples.findFile(args["image"]))
    if image is None:
        print("can't read image " + args["image"])
        sys.exit(-1)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    gray = cv.bitwise_not(gray)

    # threshold the image, setting all foreground pixels to
    # 255 and all background pixels to 0
    thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
    coords = np.column_stack(np.where(thresh > 0))
    angle = cv.minAreaRect(coords)[-1]
    print(cv.minAreaRect(coords))
    #print(coords)
    print(angle)
    # the `cv.minAreaRect` function returns values in the
    # range [-90, 0); as the rectangle rotates clockwise the
    # returned angle trends to 0 -- in this special case we
    # need to add 90 degrees to the angle
    if angle < -45:
        angle = -(90 + angle)

    # otherwise, just take the inverse of the angle to make
    # it positive
    else:
        angle = -angle
    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv.warpAffine(image, M, (w, h), flags=cv.INTER_CUBIC, borderMode=cv.BORDER_REPLICATE)
    cv.putText(rotated, "Angle: {:.2f} degrees".format(angle), (10, 30), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    # show the output image
    print("[INFO] angle: {:.3f}".format(angle))
    cv.imshow("Input", image)
    cv.imshow("Rotated", rotated)
    cv.waitKey(0)

if __name__ == "__main__":
main()

C++ code

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
#include <string>
using namespace cv;
using namespace std;



int main( int argc, char** argv )
{
Mat image=imread(samples::findFile(imageName));
if(image.empty()){
    cout<<"Cannot load the image "+imageName<<endl;
    return -1;
}
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY );
bitwise_not(gray,gray);

Mat thresh;
threshold(gray,thresh,0,255,THRESH_BINARY | THRESH_OTSU);
vector<Point>coords;
findNonZero(thresh,coords);
cout<<coords.size()<<"\n";
RotatedRect box=minAreaRect(coords);
double angle=box.angle;
cout<<box.angle<<"\n";
if(angle<-45)
    angle=-(90+angle);
else
    angle=-angle;

Point2f center((image.cols)/2.0, (image.rows)/2.0);
Mat M=getRotationMatrix2D(center, angle, 1.0);
Mat rotated;
warpAffine(image,rotated,M,image.size(),INTER_CUBIC,BORDER_REPLICATE);
putText(rotated,"Angle "+to_string(angle)+" degrees",Point(10,30),FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 0, 255), 2);
cout<<"The image is rotated by "<<angle<<endl;
imshow("Input",image);
imshow("Rotated",rotated);
waitKey(0);
return 0;

}

Python version gives angle asprint(angle) gives -80.69794464111328```

where as C++ gives angle as cout<<box.angle gives -9.30206 we can see that these are complimentary of each other is their a difference in the angle notations in c++ and python versions
C++ opencv version 4.1.2
Python opencv version 4.2.0