One of the things I left unimplemented in my image tagger input screen was recovering the aspect ratio of the selected rectangle. Before, it just squished everything into a 640x480 image. But now, thanks to
this paper, I can automatically calculate the aspect ratio from a given set of four corners. The OpenCV implementation is below. Note the strange ordering of the rectangle's corners (M_i (i = 1...4), are (0, 0), (w, 0), (0, h), and (w, h) ).
// Get aspect ratio
// Input corners c0,c1,c2,c3 are given as a percent of the original image height/width
// Using equations from: http://research.microsoft.com/en-us/um/people/zhang/Papers/WhiteboardRectification.pdf
cv::Mat A = (cv::Mat_(3,3) << 786.42938232, 0, imageSize.width/2,
0, 786.42938232, imageSize.height/2,
0,0,1);
float k2, k3;
float ratio;
cv::Mat _ratio;
cv::Mat n2, n3;
cv::Mat m1 = (cv::Mat_(3,1) << imageSize.width * (float)c0.x, imageSize.height * (float)c0.y, 1);
cv::Mat m2 = (cv::Mat_(3,1) << imageSize.width * (float)c3.x, imageSize.height * (float)c3.y, 1);
cv::Mat m3 = (cv::Mat_(3,1) << imageSize.width * (float)c1.x, imageSize.height * (float)c1.y, 1);
cv::Mat m4 = (cv::Mat_(3,1) << imageSize.width * (float)c2.x, imageSize.height * (float)c2.y, 1);
k2 = (m1.cross(m4).dot(m3)) / ((m2.cross(m4)).dot(m3));
k3 = (m1.cross(m4).dot(m2)) / ((m3.cross(m4)).dot(m2));
n2 = (k2*m2) - m1;
n3 = (k3*m3) - m1;
_ratio = (n2.t()*(A.inv().t())*(A.inv())*n2) / (n3.t()*(A.inv().t())*(A.inv())*n3);
ratio = sqrt(_ratio.at(0,0));
No comments:
Post a Comment