使用OpenCv通过给定矩阵转换图像

时间:2017-07-08 18:19:51

标签: c++ matlab opencv matrix

我要做的是使用(Matlab)变换矩阵转换图像。它是以下具有3x3维度的2D变换矩阵:

aaa   bbb   0
ccc   ddd   0
eee   fff   1

我在这里找到了一个很好的解释:how to transform an image with a transformation Matrix in OpenCv?但是我无法填充3x3矩阵(并将其应用于图像)。这是我的代码:

cv::Mat t(3,3,CV_64F,cvScalar(0.0));

t.at<double>(0, 0) = aaa;
t.at<double>(1, 0) = bbb;
t.at<double>(2, 0) = 0;

t.at<double>(0, 1) = ccc;
t.at<double>(1, 1) = ddd;
t.at<double>(2, 1) = 0;

t.at<double>(0, 2) = eee;
t.at<double>(1, 2) = fff;
t.at<double>(2, 2) = 1;  

cv::Mat dest;
cv::Size size(imageToTransform.cols,imageToTransform.rows);
warpAffine(imageToTransform, outputImage, t, size, INTER_LINEAR, BORDER_CONSTANT);

imshow("outputImage", outputImage);

导致以下错误:

  

OpenCV错误:断言失败((M0.type()== CV_32F || M0.type()== CV_64F)&amp;&amp; M0.rows == 2&amp;&amp; M0.cols == 3)

这里有什么想法吗?

1 个答案:

答案 0 :(得分:3)

warp仿射中使用的变换矩阵是一个仿射变换矩阵,representation如下:

a11 a12 b1
a21 a22 b2
0   0   1

这意味着它确实是一个3x3矩阵。然而,OpenCV并不关心最后一行,因为它总是相同的(看之前的链接)。然后,您可以删除此行并使用input needed(2x3):

a11 a12 b1
a21 a22 b2

getAffineTransform中你可以看到为什么他们想要那样(将一个同质点映射到新的2d点并将其放在2d并避免额外的乘法)。

你有一个类型的矩阵:

aaa   bbb   0
ccc   ddd   0
eee   fff   1

这似乎是以某种方式转置?因为我不知道你是如何产生矩阵的,所以我无法确定。也许你已将它转置,然后将其分配给opencv(或直接执行)。有趣的部分是(有意或无意地)你在c ++代码中使用了矩阵转置。请记住,在大多数情况下,OpenCV表示法通常是(行,列)。

您的代码应如下所示:

cv::Mat t(2,3,CV_64F,cvScalar(0.0));

t.at<double>(0, 0) = aaa;
t.at<double>(1, 0) = bbb;

t.at<double>(0, 1) = ccc;
t.at<double>(1, 1) = ddd;

t.at<double>(0, 2) = eee;
t.at<double>(1, 2) = fff;

cv::Mat dest;
cv::Size size(imageToTransform.cols,imageToTransform.rows);
warpAffine(imageToTransform, outputImage, t, size, INTER_LINEAR, BORDER_CONSTANT);

imshow("outputImage", outputImage);

我希望这可以帮助您解决问题。