Reputation: 3564
I am trying to create a way to be able to smoothly generate images at different perspectives. The best way I can describe this is if I loop through the angles I can get a smooth rotating image, however, what I am trying to do here is to get a smooth tilting image, similar to a person viewing a billboard from different angles. I have included some sample images of proper perspective transformations as well as some invalid transformations that have seemed to return. Also if anyone can explain why or how these images look like shattered glass would help me understand what the cvWarpPerspective
function is doing in the background.
EDIT
I've included some additional code below to describe what I am currently doing to get these images. I am currently trying to get any value and compare to what is described as being a valid range to work with.
srcQuad[0].x = 0; //src Top left
srcQuad[0].y = 0;
srcQuad[1].x = src->width - 1; //src Top right
srcQuad[1].y = 0;
srcQuad[2].x = 0; //src Bottom left
srcQuad[2].y = src->height - 1;
srcQuad[3].x = src->width - 1; //src Bot right
srcQuad[3].y = src->height - 1;
dstQuad[0].x = src->width*theRNG().uniform(0.1, 1.);//dst Top left
dstQuad[0].y = src->height*theRNG().uniform(0.1, 1.);
dstQuad[1].x = src->width*theRNG().uniform(0.1, 1.);//dst Top right
dstQuad[1].y = src->height*theRNG().uniform(0.1, 1.);
dstQuad[2].x = src->width*theRNG().uniform(0.1, 1.);//dst Bottom left
dstQuad[2].y = src->height*theRNG().uniform(0.1, 1.);
dstQuad[3].x = src->width*theRNG().uniform(0.1, 1.);//dst Bot right
dstQuad[3].y = src->height*theRNG().uniform(0.1, 1.);
cvGetPerspectiveTransform(
srcQuad,
dstQuad,
warp_matrix
);
cvWarpPerspective( src, dst, warp_matrix );
Proper transforms:
Invalid, shattered glass, transforms:
Any advice would be greatly appreciated.
Upvotes: 2
Views: 1671
Reputation: 10728
That's happening because your left point is to the right of your right point and/or your top point is below your bottom point, so you're basically turning your image inside-out.
Here's a version that won't do that. I generate a random multiplier between 0 and 0.5 for the left and top coordinates and a multiplier between 0.5 and 1.0 for the right and bottom coordinates.
using namespace cv;
RNG rng;
int main(int argc, const char * argv[]) {
Mat target(Size(601,601), CV_8UC3);
for (int i=4; i>=0; i-=1) {
circle(target, Point(300,300), i * 50, Scalar((i & 1) * 255, (i & 1) * 255, 255), 100, 8);
}
Point2f srcQuad[4], dstQuad[4];
srcQuad[0] = Point2f(0,0); //src Top left
srcQuad[1] = Point2f(0, target.cols-1); //src Top right
srcQuad[2] = Point2f(target.rows-1, 0); //src Bottom left
srcQuad[3] = Point2f(target.rows-1, target.cols-1); //src Bottom Right
Mat warpTarget;
int keystroke = 0;
do {
dstQuad[0] = Point2f(target.rows * rng.uniform(0.0f, 0.5f), target.cols * rng.uniform(0.0f, 0.5f)); //src Top left
dstQuad[1] = Point2f(target.rows * rng.uniform(0.0f, 0.5f), target.cols * rng.uniform(0.5f, 1.0f)); //src Top right
dstQuad[2] = Point2f(target.rows * rng.uniform(0.5f, 1.0f), target.cols * rng.uniform(0.0f, 0.5f)); //src Bottom left
dstQuad[3] = Point2f(target.rows * rng.uniform(0.5f, 1.0f), target.cols * rng.uniform(0.5f, 1.0f)); //src Bottom Right
Mat warpMatrix = getPerspectiveTransform(srcQuad, dstQuad);
warpPerspective(target, warpTarget, warpMatrix, Size(600,600));
// create image window named "so7149300"
namedWindow("so7149300");
// show the image on window
imshow("so7149300", warpTarget);
// wait for key
keystroke = waitKey(0);
} while (keystroke != 27);
return 0;
}
Upvotes: 1