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 as
print(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
does coords = np.column_stack(np.where(thresh > 0)) give line, column and findNonZero(thresh,coords) gives col,line?
Well, as you know the input image, you should know which one is correct... Then you can find the problem in the other