如何在OpenCV中获得平滑的透视变形

时间:2011-08-22 14:52:05

标签: c opencv image-manipulation

我正在尝试创建一种能够在不同视角平滑生成图像的方法。我能描述的最好的方法是,如果我在角度中循环,我可以获得平滑的旋转图像,但是,我在这里要做的是获得平滑的倾斜图像,类似于从不同角度观看广告牌的人。我已经包含了一些正确透视变换的示例图像以及一些似乎已经返回的无效变换。此外,如果有人能解释为什么或如何这些图像看起来像破碎的玻璃将帮助我理解cvWarpPerspective函数在后台正在做什么。

修改

我在下面添加了一些额外的代码来描述我目前正在做什么来获取这些图像。我目前正试图获得任何价值,并与所描述的有效范围进行比较。

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 );

正确转换:

enter image description here enter image description here

无效,破碎的玻璃,变形:

enter image description here enter image description here

非常感谢任何建议。

1 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为您的左点位于右侧点的右侧和/或您的顶点位于您的底部点之下,因此您基本上将图像从里到外翻转。

这是一个不会那样做的版本。我为左坐标和顶坐标生成0到0.5之间的随机乘数,为右坐标和底坐标生成0.5到1.0之间的乘数。

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;
}