打开简历。如何将点和矩阵相乘 (CvMat)
OpenCV. How do I multiply point and matrix (CvMat)
我有用于旋转的矩阵:
CvMat* rot_mat = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, angle, scale, rot_mat);
...
这个矩阵用于图像运算。
cvWarpAffine(..., ..., rot_mat, ..., ...);
我必须知道,这个矩阵应该如何影响确切的像素 - 它应该被转移的位置。
如何将 2D 点(像素位置)与我的矩阵相乘以找出应将像素转移到何处?
我为此实现了一些愚蠢的代码。我想应该有更复杂的解决方案:
CvMat* rot_mat;
CvPoint* p;
...
float* data = (float*)(rot_mat->data.ptr);
float newX = data[0] * p->x + data[1] * p->y + data[2];
float newY = data[3] * p->x + data[4] * p->y + data[5];
我在这个 forum 中找到了答案。以防万一 link 在这里失败是解决方案:
cv::Point2f operator*(cv::Mat M, const cv::Point2f& p)
{
cv::Mat_<double> src(3/*rows*/,1 /* cols */);
src(0,0)=p.x;
src(1,0)=p.y;
src(2,0)=1.0;
cv::Mat_<double> dst = M*src; //USE MATRIX ALGEBRA
return cv::Point2f(dst(0,0),dst(1,0));
}
如果您已经将信息存储在 cv::Point 个元素中,您可以使用 cv::Mat 构造函数将该信息转换为矩阵而无需内存复制,例如
cv::Mat V = cv::Mat(v, false); // false to avoid memory copy
在使用'V'操作后,你可以回到原来的结构,如
V.copyTo( cv::Mat(p, false) );
您可以使用相同的构造函数解析单个点或它们的列表 (std::vector)。这个示例代码可以更好地展示这个想法:
#include <iostream>
#include <opencv2/core/core.hpp>
int main( )
{
std::vector< cv::Point2f > v(3);
v[0] = cv::Point2f(1, 1);
v[1] = cv::Point2f(2, 2);
v[2] = cv::Point2f(3, 3);
cv::Mat V = cv::Mat(v, false); // false to avoid memory copy
std::vector< cv::Point2f > p(3);
V.copyTo( cv::Mat(p, false) );
for (int i = 0; i < 3; ++i) {
std::cout << p[i] << std::endl;
}
return 0;
}
- 对于 3D 点
std::vector<cv::Point3d> transform_3d_points(std::vector<cv::Point3d> points3d, cv::Mat transformation_matrix){
std::vector<cv::Point3d> transformed_points3d;
cv::perspectiveTransform(points3d, transformed_points3d, transformation_matrix);
return transformed_points3d;
}
- 对于二维点
std::vector<cv::Point2d> transform_2d_points(std::vector<cv::Point2d> points2d, cv::Mat transformation_matrix){
std::vector<cv::Point2d> transformed_points2d;
cv::perspectiveTransform(points2d, transformed_points2d, transformation_matrix);
return transformed_points2d;
}
对于3d点,变换矩阵应该是4*4齐次的。
例如
cv::Mat transformation_matrix = (cv::Mat_<double>(4, 4) << 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
std::vector<cv::Points3d> points3d = { cv::Points3d(0,0,0), cv::Points3d(1,1,1) }
对于2d点,变换矩阵应该是3*3齐次的。
例如
cv::Mat transformation_matrix = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
std::vector<cv::Points2d> points2d = { cv::Points2d(0,0), cv::Points3d(1,1) }
我有用于旋转的矩阵:
CvMat* rot_mat = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, angle, scale, rot_mat);
...
这个矩阵用于图像运算。
cvWarpAffine(..., ..., rot_mat, ..., ...);
我必须知道,这个矩阵应该如何影响确切的像素 - 它应该被转移的位置。
如何将 2D 点(像素位置)与我的矩阵相乘以找出应将像素转移到何处?
我为此实现了一些愚蠢的代码。我想应该有更复杂的解决方案:
CvMat* rot_mat;
CvPoint* p;
...
float* data = (float*)(rot_mat->data.ptr);
float newX = data[0] * p->x + data[1] * p->y + data[2];
float newY = data[3] * p->x + data[4] * p->y + data[5];
我在这个 forum 中找到了答案。以防万一 link 在这里失败是解决方案:
cv::Point2f operator*(cv::Mat M, const cv::Point2f& p)
{
cv::Mat_<double> src(3/*rows*/,1 /* cols */);
src(0,0)=p.x;
src(1,0)=p.y;
src(2,0)=1.0;
cv::Mat_<double> dst = M*src; //USE MATRIX ALGEBRA
return cv::Point2f(dst(0,0),dst(1,0));
}
如果您已经将信息存储在 cv::Point 个元素中,您可以使用 cv::Mat 构造函数将该信息转换为矩阵而无需内存复制,例如
cv::Mat V = cv::Mat(v, false); // false to avoid memory copy
在使用'V'操作后,你可以回到原来的结构,如
V.copyTo( cv::Mat(p, false) );
您可以使用相同的构造函数解析单个点或它们的列表 (std::vector)。这个示例代码可以更好地展示这个想法:
#include <iostream>
#include <opencv2/core/core.hpp>
int main( )
{
std::vector< cv::Point2f > v(3);
v[0] = cv::Point2f(1, 1);
v[1] = cv::Point2f(2, 2);
v[2] = cv::Point2f(3, 3);
cv::Mat V = cv::Mat(v, false); // false to avoid memory copy
std::vector< cv::Point2f > p(3);
V.copyTo( cv::Mat(p, false) );
for (int i = 0; i < 3; ++i) {
std::cout << p[i] << std::endl;
}
return 0;
}
- 对于 3D 点
std::vector<cv::Point3d> transform_3d_points(std::vector<cv::Point3d> points3d, cv::Mat transformation_matrix){
std::vector<cv::Point3d> transformed_points3d;
cv::perspectiveTransform(points3d, transformed_points3d, transformation_matrix);
return transformed_points3d;
}
- 对于二维点
std::vector<cv::Point2d> transform_2d_points(std::vector<cv::Point2d> points2d, cv::Mat transformation_matrix){
std::vector<cv::Point2d> transformed_points2d;
cv::perspectiveTransform(points2d, transformed_points2d, transformation_matrix);
return transformed_points2d;
}
对于3d点,变换矩阵应该是4*4齐次的。 例如
cv::Mat transformation_matrix = (cv::Mat_<double>(4, 4) << 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
std::vector<cv::Points3d> points3d = { cv::Points3d(0,0,0), cv::Points3d(1,1,1) }
对于2d点,变换矩阵应该是3*3齐次的。 例如
cv::Mat transformation_matrix = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
std::vector<cv::Points2d> points2d = { cv::Points2d(0,0), cv::Points3d(1,1) }