[英]OpenCV Mat rotation gets wrong result
我想將圖像旋轉90度。 我的代碼如下:
int main(int argc, const char * argv[]) {
Mat img = imread("/Users/chuanliu/Desktop/src4/p00.JPG");
resize(img, img, Size(1024, 683));
imwrite("/Users/chuanliu/Desktop/resize.jpg", img);
Mat dst;
Mat rot_mat = getRotationMatrix2D(Point(img.cols / 2.0, img.rows / 2.0), 90, 1);
warpAffine(img, dst, rot_mat, Size(img.rows, img.cols));
imwrite("/Users/chuanliu/Desktop/roatation.jpg", dst);
return 0;
}
但是結果如下:
輪換之前:
旋轉后:
旋轉中心似乎有誤。 但是我不認為我設定了錯誤的中心。 有沒有人可以告訴我什么地方出了問題?
中心是根據源圖像的尺寸Point(img.cols / 2.0, img.rows / 2.0)
但您不僅要旋轉圖像,還要在調用warpAffine
時交換輸出大小的寬度和高度:
Size(img.rows, img.cols)
因此,看起來您可能需要根據輸出圖像坐標指定中心; 例如。 Point(rows/2, cols/2)
。
更新:
不,那不是解決方案。 實際上,有一種非常簡單有效的方法可以將圖像旋轉90度:使用cv::transpose()
函數:
int main()
{
cv::Mat img = cv::imread("5syfi.jpg");
cv::Mat img_rotated;
cv::transpose(img, img_rotated);
cv::imwrite("out.jpg", img_rotated);
return 0;
}
結合使用cv::transpose()
(旋轉)和cv::flip()
(垂直和水平鏡像),您可以非常快速地執行90、180和270度的旋轉。
使用warpAffine()
更加靈活,但計算起來也更加昂貴(即速度較慢)。 因此,如果您只需要旋轉90度,請使用cv::transpose
。 如果需要旋轉任意角度,請使用warpAffine/warpPerspective
函數。 @Micka的答案提供了一個很好的示例。
改編我的答案來自:
OpenCV 2.4.3-在裁切后的圖像上使用反向單應性的warpPerspective
您可以使用以下代碼:
int main(int argc, const char * argv[]) {
cv::Mat img = cv::imread("../inputData/rotationInput.jpg");
cv::imshow("input", img);
cv::Mat dst;
cv::Mat rot_mat = cv::getRotationMatrix2D(cv::Point(img.cols / 2.0, img.rows / 2.0), 90, 1);
//cv::warpAffine(img, dst, rot_mat, cv::Size(img.rows, img.cols));
// since I didnt write the code for affine transformations yet, we have to embed the affine rotation matrix in a perspective transformation
cv::Mat perspRotation = cv::Mat::eye(3,3, CV_64FC1);
for(int j=0; j<rot_mat.rows; ++j)
for(int i=0; i<rot_mat.cols; ++i)
{
perspRotation.at<double>(j,i) = rot_mat.at<double>(j,i);
}
// image boundary corners:
std::vector<cv::Point> imageCorners;
imageCorners.push_back(cv::Point(0,0));
imageCorners.push_back(cv::Point(img.cols,0));
imageCorners.push_back(cv::Point(img.cols,img.rows));
imageCorners.push_back(cv::Point(0,img.rows));
// look at where the image will be placed after transformation:
cv::Rect warpedImageRegion = computeWarpedContourRegion(imageCorners, perspRotation);
// adjust the transformation so that the top-left corner of the transformed image will be placed at (0,0) coordinate
cv::Mat adjustedTransformation = adjustHomography(warpedImageRegion, perspRotation);
// finally warp the image
cv::warpPerspective(img, dst, adjustedTransformation, warpedImageRegion.size());
//mwrite("/Users/chuanliu/Desktop/roatation.jpg", dst);
cv::imwrite("../outputData/rotationOutput.png", dst);
cv::imshow("out", dst);
cv::waitKey(0);
return 0;
}
使用以下輔助功能:
cv::Rect computeWarpedContourRegion(const std::vector<cv::Point> & points, const cv::Mat & homography)
{
std::vector<cv::Point2f> transformed_points(points.size());
for(unsigned int i=0; i<points.size(); ++i)
{
// warp the points
transformed_points[i].x = points[i].x * homography.at<double>(0,0) + points[i].y * homography.at<double>(0,1) + homography.at<double>(0,2) ;
transformed_points[i].y = points[i].x * homography.at<double>(1,0) + points[i].y * homography.at<double>(1,1) + homography.at<double>(1,2) ;
}
// dehomogenization necessary?
if(homography.rows == 3)
{
float homog_comp;
for(unsigned int i=0; i<transformed_points.size(); ++i)
{
homog_comp = points[i].x * homography.at<double>(2,0) + points[i].y * homography.at<double>(2,1) + homography.at<double>(2,2) ;
transformed_points[i].x /= homog_comp;
transformed_points[i].y /= homog_comp;
}
}
// now find the bounding box for these points:
cv::Rect boundingBox = cv::boundingRect(transformed_points);
return boundingBox;
}
cv::Mat adjustHomography(const cv::Rect & transformedRegion, const cv::Mat & homography)
{
if(homography.rows == 2) throw("homography adjustement for affine matrix not implemented yet");
// unit matrix
cv::Mat correctionHomography = cv::Mat::eye(3,3,CV_64F);
// correction translation
correctionHomography.at<double>(0,2) = -transformedRegion.x;
correctionHomography.at<double>(1,2) = -transformedRegion.y;
return correctionHomography * homography;
}
並產生90°的輸出:
這個輸出33°
順便說一句,如果您只想旋轉90°/ 180°,可能會比圖像變形更有效,更准確(關於插值)!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.