C++ 使用OpenCv通过给定矩阵变换图像

C++ 使用OpenCv通过给定矩阵变换图像,c++,matlab,opencv,matrix,C++,Matlab,Opencv,Matrix,我要做的是使用(Matlab)变换矩阵变换图像。它是以下三维2D变换矩阵: 我在这里找到了一个很好的解释:但我无法填充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.

我要做的是使用(Matlab)变换矩阵变换图像。它是以下三维2D变换矩阵:

我在这里找到了一个很好的解释:但我无法填充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);
cv::matt(3,3,cv_64F,cvScalar(0.0));
t、 在(0,0)=aaa;
t、 at(1,0)=bbb;
t、 at(2,0)=0;
t、 at(0,1)=ccc;
t、 at(1,1)=ddd;
t、 at(2,1)=0;
t、 at(0,2)=eee;
t、 at(1,2)=fff;
t、 at(2,2)=1;
cv::Mat dest;
cv::大小(imageToTransform.cols、imageToTransform.rows);
翘曲仿射(图像变换、输出图像、t、大小、内部线性、边界常数);
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):

在中,您可以看到他们为什么希望这样(将一个homgeneous点映射到新的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);
cv::matt(2,3,cv_64F,cvScalar(0.0));
t、 在(0,0)=aaa;
t、 at(1,0)=bbb;
t、 at(0,1)=ccc;
t、 at(1,1)=ddd;
t、 at(0,2)=eee;
t、 at(1,2)=fff;
cv::Mat dest;
cv::大小(imageToTransform.cols、imageToTransform.rows);
翘曲仿射(图像变换、输出图像、t、大小、内部线性、边界常数);
imshow(“outputImage”,outputImage);

我希望这能帮助您解决这个问题。

这里不是opencv的行家,但是看到断言,您的矩阵需要有2个rows@Lovy但导致
cv::Mat t(3,3,cv_64F,cvScalar(0.0))不是3行?
warpAffine
函数要求变换矩阵是2x3矩阵,但在您的例子中是3x3矩阵。在转置中写入投影变换确实很常见。区别在于变换是与坐标相乘之前还是之后。例如,在。
aaa   bbb   0
ccc   ddd   0
eee   fff   1
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);