Reputation: 607
I have matrix that is used for rotation:
CvMat* rot_mat = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, angle, scale, rot_mat);
...
This matrix is used for image operations.
cvWarpAffine(..., ..., rot_mat, ..., ...);
I have to know, how this matrix should affect exact pixel - location it should be transfered.
How can I multiply 2D point (pixel location) and my matrix to find out where pixel should be transferred?
Upvotes: 4
Views: 12511
Reputation: 594
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;
}
For 3d points , the transformation matrix should be 4*4 homogeneous. e.g.
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) }
For 2d points , the transformation matrix should be 3*3 homogeneous. e.g.
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) }
Upvotes: 0
Reputation: 2303
If you already have the information stored in cv::Point elements you can transform that info into a matrix without memory copy using the cv::Mat constructor, like
cv::Mat V = cv::Mat(v, false); // false to avoid memory copy
After the operations using 'V' you can back to the original structure like
V.copyTo( cv::Mat(p, false) );
You can parse a single point or a list (std::vector) of them with the same constructor. This sample code can show the idea better:
#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;
}
Upvotes: 2
Reputation: 2575
I found an answer to this in this forum. Just in case the link fails here is the solution:
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));
}
Upvotes: 8
Reputation: 607
I have implemented some silly code for that. I guess there should be more sophisticated solution:
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];
Upvotes: -2