Iphone 基于点的图像透视校正

Iphone 基于点的图像透视校正,iphone,ios,image-processing,quartz-2d,Iphone,Ios,Image Processing,Quartz 2d,我正在开发一个应用程序,允许用户拍照,例如名片或照片 然后,用户将标记对象的四个角(他们从中拍摄了一张照片)——就像在许多文档/图像/名片扫描应用程序中看到的那样: 我的问题是如何根据这四点裁剪和修复透视图?我已经搜索了好几天,并没有任何运气地查看了几个图像处理库 有谁能给我指出正确的方向吗?如果这个图像是作为纹理加载的,那么使用OpenGL扭曲它就非常简单了。你只需画一个全屏四元图,并使用黄色校正点作为每个点的UV坐标。我不知道你的情况的确切解决方案,但梯形有一种方法:-其思想是连续构建变换

我正在开发一个应用程序,允许用户拍照,例如名片或照片

然后,用户将标记对象的四个角(他们从中拍摄了一张照片)——就像在许多文档/图像/名片扫描应用程序中看到的那样:

我的问题是如何根据这四点裁剪和修复透视图?我已经搜索了好几天,并没有任何运气地查看了几个图像处理库


有谁能给我指出正确的方向吗?

如果这个图像是作为纹理加载的,那么使用OpenGL扭曲它就非常简单了。你只需画一个全屏四元图,并使用黄色校正点作为每个点的UV坐标。

我不知道你的情况的确切解决方案,但梯形有一种方法:-其思想是连续构建变换矩阵。从理论上讲,您可以添加将形状转换为trapecy的变换


还有很多类似的问题:,但我没有检查解决方案。

我不确定您是否尝试过Opencv库,但它有一种非常好的方法来消除图像的扭曲。我这里有一个小片段,它需要一个角数组,例如四个角,以及一个最终的大小来映射它

您可以在上阅读的手册页


在iOS8+中,有一个用于核心映像的过滤器,名为。你所需要做的就是传递图像和四个点


另外还有一个支持iOS6+的过滤器,名为,可以以类似的方式使用(倾斜图像)。

矩形上的纹理将被扭曲,因此可以看到对角线。为了正确地映射“透视”矩形,我们需要使用纹理z坐标进行拨号。在这种浅角度下,我不认为这会有太大的影响。但是,如果正确处理这一点非常重要,那么使用OpenGL仍然很容易。只需将图像绘制为四边形(此时仅保留UV坐标),但不要将相机正面对准它,而是稍微调整相机位置以补偿原始图片的倾斜。现在唯一的挑战是找出相机的放置位置。该解决方案的唯一问题是,任何希望进行透视校正的人都希望以完整的原始分辨率保存图像(或者在控制点进行自然裁剪的情况下尽可能接近原始分辨率)。因此,在本例中,您可以在屏幕上很好地显示透视校正后的图像,但是否可以将其保存到磁盘?谢谢您的建议-听起来是一个不错的解决方案!我现在的问题是如何“做”和实现这一点。我对OpenGL ES有一个基本的了解,但我不确定如何将图像绘制为四边形。绘制四边形是您可以做的最简单的事情。你只需要用两个三角形画一个平面矩形。同时检查这个问题并回答:这里有另一种方法来实现这一点:让我知道这是否有帮助。嗨,你得到答案了吗?请你把这个问题的代码贴出来。我需要像这样的精确答案。@mani我从来没有找到解决这个问题的好办法。很遗憾,谢谢,我会调查的@JakobHalskov,你是否每次都尝试过这个,或者找到了不同的解决方案?@JakobHalskov,如果你尝试过我提供的解决方案或其他人的解决方案,那就太好了。代码是否不清楚或需要更多解释?感谢您让我意识到这一点:)
cv::Mat deskew(cv::Mat& capturedFrame, cv::Point2f source_points[], cv::Size finalSize)
{
    cv::Point2f dest_points[4];

    // Output of deskew operation has same color space as source frame, but
    // is proportional to the area the document occupied; this is to reduce
    // blur effects from a scaling component.
    cv::Mat deskewedMat = cv::Mat(finalSize, capturedFrame.type());

    cv::Size s = capturedFrame.size();

    // Deskew to full output image corners
    dest_points[0] = cv::Point2f(0,s.height); // lower left
    dest_points[1] = cv::Point2f(0,0);        // upper left
    dest_points[2] = cv::Point2f(s.width,0);  // upper right
    dest_points[3] = cv::Point2f(s.width,s.height);  // lower right

    // Build quandrangle "de-skew" transform matrix values
    cv::Mat transform = cv::getPerspectiveTransform( source_points, dest_points  );
    // Apply the deskew transform
    cv::warpPerspective( capturedFrame, deskewedMat, transform, s, cv::INTER_CUBIC );

    return deskewedMat;
}