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

Transform image via a given matrix using OpenCv

本文关键字:转换 图像 OpenCv 使用      更新时间:2023-10-16

我正在尝试做的是使用(Matlab(转换矩阵转换图像。它是以下具有 3x3 维度的 2D 转换矩阵:

aaa   bbb   0
ccc   ddd   0
eee   fff   1

我在这里找到了一个很好的解释:如何在 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( && M0.rows == 2 && M0.cols == 3(

知道这里出了什么问题吗?

曲速仿射中使用的变换矩阵是仿射变换矩阵,表示如下:

a11 a12 b1
a21 a22 b2
0   0   1

这意味着它确实是一个 3x3 矩阵。然而,OpenCV并不关心最后一行,因为它总是相同的(看看前面的链接(。然后,您可以消除此行并具有所需的输入 (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);

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