2015-04-29 17 views
1

我想旋轉90度的圖像。我的代碼是像以下:OpenCV Mat旋轉得到錯誤的結果

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; 
} 

但結果是類似以下內容:
循環之前:
enter image description here

旋轉後:
enter image description here

看來,旋轉中心具有某事不對。但我不認爲我設置了錯誤的中心。有沒有人可以告訴我什麼是錯的?

+0

您的預期結果是原始圖像旋轉時沒有黑色邊框,沒有右側的裁剪邊框? – Micka

+0

@Micka是的。我預計它只是在中間沒有黑色區域 –

+0

旋轉中心是正確的,但旋轉是單應性,因此你必須在旋轉後將圖像移動到正確的位置。 – Micka

回答

1

中心在源圖像的尺寸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的回答給出瞭如何做到這一點的一個很好的例子。

+0

是的,你是對的。現在我知道問題了,謝謝。 –

+0

你嘗試過嗎?對我來說,它裁剪圖像會被左側裁剪,並在右側留下黑色邊框,因爲旋轉後,所得圖像的左上角具有負座標。 – Micka

+1

請用最新的答案進行驗證。 @Micka是對的,輪換的中心不是問題。 – gavinb

2

從適應我的回答:

OpenCV 2.4.3 - warpPerspective with reversed homography on a cropped image

您可以使用此代碼:

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 °:

enter image description here

與此輸出33°

enter image description here

順便說一句,如果您只想旋轉90°/ 180°有可能是更有效,更準確的(關於插補)方法比圖像翹曲!