2016-04-28 64 views
0

我对旋转和平移图像的一段代码:联合旋转和平移OpenCV中,在一通

Point2f pt(0, in.rows); 
double angle = atan(trans.c/trans.b) * 180/M_PI; 
Mat r = getRotationMatrix2D(pt, -angle, 1.0); 
warpAffine(in, out, r, in.size(), interpolation); /* rotation */ 

Mat t = (Mat_<double>(2, 3) << 1, 0, trans.a, 0, 1, -trans.d); 
warpAffine(out, out, t, in.size(), interpolation); /* translation */ 

的问题是,我在两次这样做。因此,例如,如果我的角度为90度,则第一个“out”变量将为空,因为所有数据都超出范围。有一种方法可以一次完成吗?为了避免丢失我的数据和黑色图像。

我认为最好的办法是将r和t结合在一个矩阵中,但我有点失落。

此致

+0

你可以简单地多重播放单应性。仿射变换必须扩展到3x3,通过添加第3行来实现:0 0 1,那么您可以简单地乘以Hcombined = H1 * H2;但要小心,你以正确的顺序繁殖。 – Micka

+0

好的,谢谢。我如何简单地使用opencv添加第三行到r?然后我不确定明白H1是什么,H2是什么。 H1是第三行添加的旋转矩阵? H2是翻译矩阵? – lock

+0

我会发布代码示例 – Micka

回答

0

下面是对如何通过简单的乘法和如何从中提取一个3x3单应的仿射变换的单应性2结合的例子。

int main(int argc, char* argv[]) 
{ 
    cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png"); 

    // create to 3x3 identity homography matrices 
    cv::Mat homography1 = cv::Mat::eye(3, 3, CV_64FC1); 
    cv::Mat homography2 = cv::Mat::eye(3, 3, CV_64FC1); 

    double alpha1 = -13; // degrees 
    double t1_x = -86; // pixel 
    double t1_y = -86; // pixel 

    double alpha2 = 21; // degrees 
    double t2_x = 86; // pixel 
    double t2_y = 86; // pixel 

    // hope there is no error in the signs: 
    // combine homography1 
    homography1.at<double>(0, 0) = cos(CV_PI*alpha1/180); 
    homography1.at<double>(0, 1) = -sin(CV_PI*alpha1/180); 
    homography1.at<double>(1, 0) = sin(CV_PI*alpha1/180); 
    homography1.at<double>(1, 1) = cos(CV_PI*alpha1/180); 
    homography1.at<double>(0, 2) = t1_x; 
    homography1.at<double>(1, 2) = t1_y; 

    // compose homography2 
    homography2.at<double>(0, 0) = cos(CV_PI*alpha2/180); 
    homography2.at<double>(0, 1) = -sin(CV_PI*alpha2/180); 
    homography2.at<double>(1, 0) = sin(CV_PI*alpha2/180); 
    homography2.at<double>(1, 1) = cos(CV_PI*alpha2/180); 
    homography2.at<double>(0, 2) = t2_x; 
    homography2.at<double>(1, 2) = t2_y; 

    cv::Mat affine1 = homography1(cv::Rect(0, 0, 3, 2)); 
    cv::Mat affine2 = homography2(cv::Rect(0, 0, 3, 2)); 

    cv::Mat dst1; 
    cv::Mat dst2; 

    cv::warpAffine(input, dst1, affine1, input.size()); 
    cv::warpAffine(input, dst2, affine2, input.size()); 


    cv::Mat combined_homog = homography1*homography2; 
    cv::Mat combined_affine = combined_homog(cv::Rect(0, 0, 3, 2)); 

    cv::Mat dst_combined; 

    cv::warpAffine(input, dst_combined, combined_affine, input.size()); 

    cv::imshow("input", input); 
    cv::imshow("dst1", dst1); 
    cv::imshow("dst2", dst2); 

    cv::imshow("combined", dst_combined); 

    cv::waitKey(0); 
    return 0; 
} 

在此示例中,首先将图像旋转并翻译到左侧,稍后再翻译到右侧。如果两个转换依次进行,重要的图像区域将会丢失。相反,如果他们通过同形乘法相结合,就好像完整的操作在一个步骤中完成,而不会在中间步骤中丢失图像部分。

输入:如果图像是第一变换

enter image description here

与H1,后用H 2:

enter image description here

如果图像被变换直接与H1 * H2的组合:

enter image description here

此单应性组合的一个典型应用是首先将图像中心转换为原点,然后旋转,然后再转换回原始位置。这具有如同图像围绕其重心旋转的效果。

+0

噢谢谢,这应该对我有很大的帮助,我必须尽快测试它。我还有两个问题。 alpha的单位是什么?对于90度的-13,我很抱歉它一定是呃。我不知道你是否看到过,但我的翻译数据是以(0,in.rows)(即左下角)作为旋转中心。它应该改变我想的矩阵。 – lock

+0

或者我可以先从(0,in.rows) – lock

+0

开始移位,对不起,单位是度。它是-13度,而不是90度。首先我尝试了90度,但我想稍微改变一下,并没有改变评论。抱歉。 – Micka