与 OpenCV Remap 相比,Matlab Interp2 函数的行为有所不同
Matlab Interp2 function behaviour differently compared with OpenCV Remap
我正在尝试为 interp2 寻找等效的 OpenCV 函数,我参考了这张海报以在 OpenCV 中使用重映射函数。
cv::remap (in opencv) and interp2 (matlab)
但是,我意识到这两个函数的输出存在显着差异。这是我的 Matlab 代码
U = [0.1 0.1 0.1; 0.2 0.2 0.2; 0.3 0.3 0.3];
X = [0 0 0; 0.5 0.5 0.5; 1 1 1];
Y = [0 0.5 1;0 0.5 1;0 0.5 1];
V = interp2(U,X,Y,'linear',NaN)
我得到输出 V 矩阵为
NaN NaN NaN
NaN NaN NaN
NaN NaN 0.1000
这是我的 OpenCV 代码
#include "highgui.h"
#include "cv.h"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
//generate flowmap model
CvFileStorage* fx = cvOpenFileStorage("result.txt", 0, CV_STORAGE_WRITE);//ask storage for save file
Mat xmesh = cvCreateMat(3, 3, 5);
Mat ymesh = cvCreateMat(3, 3, 5);
for (int i = 0; i < xmesh.rows; i++)
for (int j = 0; j < xmesh.cols; j++)
{
xmesh.at<float>(i, j) = i*0.5;
ymesh.at<float>(i, j) = j*0.5;
}
//generate optical flow folder
Mat u = cvCreateMat(3, 3, 5);
for (int i = 0; i <u.rows; i++)
for (int j = 0; j < u.cols; j++)
{
u.at<float>(i, j) = (i + 1)*0.1;
}
Mat v = Mat::zeros(u.size(), u.type());
remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(0));
//convert mat to Iplimage
IplImage* xmesh_a = cvCloneImage(&(IplImage)xmesh);
IplImage* ymesh_a = cvCloneImage(&(IplImage)ymesh);
IplImage* u_a = cvCloneImage(&(IplImage)u);
IplImage* v_a = cvCloneImage(&(IplImage)v);
//save end to txt
cvWrite(fx, "xmesh", xmesh_a, cvAttrList());
cvWrite(fx, "ymesh", ymesh_a, cvAttrList());
cvWrite(fx, "u", u_a, cvAttrList());
cvWrite(fx, "v", v_a, cvAttrList());
cvReleaseFileStorage(&fx);
waitKey();
}
我得到的输出V矩阵是
1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001
如有任何帮助,我们将不胜感激。谢谢!
结果的差异与 c++ 和 MATLAB 之间的索引差异有关,分别是基于 0 和基于 1。
interp2(U,X,Y,'linear',NaN)
与 interp2(1:3,1:3,U,X,Y,'linear',NaN)
相同,将其更改为 interp2(0:2,0:2,U,X,Y,'linear',NaN)
您将获得与 OpenCV 相同的结果。
如果您希望 remap
的结果与 interp2
的结果相同,您可以将 xmesh
和 ymesh
后退一步并搜索否定位置产生 nan
个值。
#include <cmath>
//...
//...
for (int i = 0; i < xmesh.rows; i++)
for (int j = 0; j < xmesh.cols; j++)
{
xmesh.at<float>(i, j) = i*0.5-1;
ymesh.at<float>(i, j) = j*0.5-1;
}
//...
//...
remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(NAN));
结果:
nan nan nan
nan nan nan
nan nan 0.1
我正在尝试为 interp2 寻找等效的 OpenCV 函数,我参考了这张海报以在 OpenCV 中使用重映射函数。
cv::remap (in opencv) and interp2 (matlab)
但是,我意识到这两个函数的输出存在显着差异。这是我的 Matlab 代码
U = [0.1 0.1 0.1; 0.2 0.2 0.2; 0.3 0.3 0.3];
X = [0 0 0; 0.5 0.5 0.5; 1 1 1];
Y = [0 0.5 1;0 0.5 1;0 0.5 1];
V = interp2(U,X,Y,'linear',NaN)
我得到输出 V 矩阵为
NaN NaN NaN
NaN NaN NaN
NaN NaN 0.1000
这是我的 OpenCV 代码
#include "highgui.h"
#include "cv.h"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
//generate flowmap model
CvFileStorage* fx = cvOpenFileStorage("result.txt", 0, CV_STORAGE_WRITE);//ask storage for save file
Mat xmesh = cvCreateMat(3, 3, 5);
Mat ymesh = cvCreateMat(3, 3, 5);
for (int i = 0; i < xmesh.rows; i++)
for (int j = 0; j < xmesh.cols; j++)
{
xmesh.at<float>(i, j) = i*0.5;
ymesh.at<float>(i, j) = j*0.5;
}
//generate optical flow folder
Mat u = cvCreateMat(3, 3, 5);
for (int i = 0; i <u.rows; i++)
for (int j = 0; j < u.cols; j++)
{
u.at<float>(i, j) = (i + 1)*0.1;
}
Mat v = Mat::zeros(u.size(), u.type());
remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(0));
//convert mat to Iplimage
IplImage* xmesh_a = cvCloneImage(&(IplImage)xmesh);
IplImage* ymesh_a = cvCloneImage(&(IplImage)ymesh);
IplImage* u_a = cvCloneImage(&(IplImage)u);
IplImage* v_a = cvCloneImage(&(IplImage)v);
//save end to txt
cvWrite(fx, "xmesh", xmesh_a, cvAttrList());
cvWrite(fx, "ymesh", ymesh_a, cvAttrList());
cvWrite(fx, "u", u_a, cvAttrList());
cvWrite(fx, "v", v_a, cvAttrList());
cvReleaseFileStorage(&fx);
waitKey();
}
我得到的输出V矩阵是
1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001
如有任何帮助,我们将不胜感激。谢谢!
结果的差异与 c++ 和 MATLAB 之间的索引差异有关,分别是基于 0 和基于 1。
interp2(U,X,Y,'linear',NaN)
与 interp2(1:3,1:3,U,X,Y,'linear',NaN)
相同,将其更改为 interp2(0:2,0:2,U,X,Y,'linear',NaN)
您将获得与 OpenCV 相同的结果。
如果您希望 remap
的结果与 interp2
的结果相同,您可以将 xmesh
和 ymesh
后退一步并搜索否定位置产生 nan
个值。
#include <cmath>
//...
//...
for (int i = 0; i < xmesh.rows; i++)
for (int j = 0; j < xmesh.cols; j++)
{
xmesh.at<float>(i, j) = i*0.5-1;
ymesh.at<float>(i, j) = j*0.5-1;
}
//...
//...
remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(NAN));
结果:
nan nan nan
nan nan nan
nan nan 0.1