Quantcast
Channel: OpenCV Q&A Forum - Latest question feed
Viewing all articles
Browse latest Browse all 19555

Direct formula for 3D rotation done by warpPerspective or remap

$
0
0
I'm rotating an image at 45 degrees along the y axis. ![image description](/upfiles/14717349398941121.png) Based on this [link](http://stackoverflow.com/questions/19093728/rotate-image-around-x-y-z-axis-in-opencv), I do: Mat rotate3D(Mat in, Mat *out, float rotx, float roty, float rotz) { int f = 2; int h = in.rows; int w = in.cols; float cx = cosf(rotx / R2D), sx = sinf(rotx / R2D); float cy = cosf(roty / R2D), sy = sinf(roty / R2D); float cz = cosf(rotz / R2D), sz = sinf(rotz / R2D); float roto[3][2] = { { cz * cy, cz * sy * sx - sz * cx }, { sz * cy, sz * sy * sx + cz * cx }, { -sy, cy * sx } }; float pt[4][2] = {{ -w / 2, -h / 2 }, { w / 2, -h / 2 }, { w / 2, h / 2 }, { -w / 2, h / 2 }}; float ptt[4][2]; for (int i = 0; i < 4; i++) { float pz = pt[i][0] * roto[2][0] + pt[i][1] * roto[2][1]; ptt[i][0] = w / 2 + (pt[i][0] * roto[0][0] + pt[i][1] * roto[0][1]) * f * h / (f * h + pz); ptt[i][1] = h / 2 + (pt[i][0] * roto[1][0] + pt[i][1] * roto[1][1]) * f * h / (f * h + pz); } Mat in_pt = (Mat_(4, 2) << 0, 0, w, 0, w, h, 0, h); Mat out_pt = (Mat_(4, 2) << ptt[0][0], ptt[0][1], ptt[1][0], ptt[1][1], ptt[2][0], ptt[2][1], ptt[3][0], ptt[3][1]); Mat transform = getPerspectiveTransform(in_pt, out_pt); warpPerspective(in, *out, transform, in.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0)); return transform; } I prefer to remap instead of warpPerspective. So I used this [link](http://www.smallbulb.net/2013/351-opencv-convert-projection-matrix-to-maps) to convert the getPerspectiveTransform into a remap. Basically, it's replacing a warpPerspective by a remap. void perspective2Maps(Mat perspective_mat, Size img_size, Mat* remaps) { Mat inv_perspective(perspective_mat.inv()); inv_perspective.convertTo(inv_perspective, CV_32FC1); Mat xy(img_size, CV_32FC2); float *pxy = (float*)xy.data; for (int y = 0; y < img_size.height; y++) for (int x = 0; x < img_size.width; x++) { *pxy++ = x; *pxy++ = y; } Mat xy_transformed; perspectiveTransform(xy, xy_transformed, inv_perspective); split(xy_transformed, remaps); } Then, I can do: remap(in, out, remaps[0], remaps[1], INTER_LINEAR, BORDER_CONSTANT); It's working well, both with warpPerspective or remap. ![image description](/upfiles/14717351043811807.png) Now, I wish to have the direct formula of the remap matrices. I thought it would be: void rotate3DPoint(Point2f in, Point2f *out, int w, int h, float rotx, float roty, float rotz) { int f = 2; float cx = cosf(rotx / R2D), sx = sinf(rotx / R2D); float cy = cosf(roty / R2D), sy = sinf(roty / R2D); float cz = cosf(rotz / R2D), sz = sinf(rotz / R2D); float roto[3][2] = { { cz * cy, cz * sy * sx - sz * cx }, { sz * cy, sz * sy * sx + cz * cx }, { -sy, cy * sx } }; float pz = in.x * roto[2][0] + in.y * roto[2][1]; out->x = w / 2 + (in.x * roto[0][0] + in.y * roto[0][1]) * f * h / (f * h + pz); out->y = h / 2 + (in.x * roto[1][0] + in.y * roto[1][1]) * f * h / (f * h + pz); } But it's not similar. Note that I'm in the case of rotx = 0.0f, roty = 45.0f, rotz = 0.0f. So it simplifies to the following: void rotate3DPoint(Point2f in, Point2f *out, float w, float h) { float f = 2; float cy = cosf(45.0f / R2D); float sy = sinf(45.0f / R2D); out->x = w / 2 + (in.x * cy) * f * h / (f * h - in.x * sy); out->y = h / 2 + in.y * f * h / (f * h - in.x * sy); } But it's still not working. I also tried to invert the formula in this last function, but nothing better. What am I missing?

Viewing all articles
Browse latest Browse all 19555

Trending Articles