【问题标题】:Perspective correction of UIImage from Points从 Points 对 UIImage 进行透视校正
【发布时间】:2012-01-04 08:06:17
【问题描述】:

我正在开发一个应用程序,可以让用户拍照,例如名片或照片。

然后,用户将标记对象的四个角(他们将其拍下来) - 就像在许多文档/图像/名片扫描应用程序中看到的那样:

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

谁能指出我正确的方向?

【问题讨论】:

  • 这是实现此目的的另一种方法:stackoverflow.com/questions/9470493/… 如果这有帮助,请告诉我。
  • 嗨,你得到解决方案了吗?请您发布此问题的代码。我需要完全一样的。
  • @mani 我从来没有找到一个好的解决方案。不幸的是。

标签: iphone ios image-processing quartz-2d


【解决方案1】:

从 iOS8+ 开始,有一个名为 CIPerspectiveCorrection 的 Core Image 过滤器。你需要做的就是通过图像和四个点。

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

【讨论】:

  • 感谢您让我意识到这一点 :)
【解决方案2】:

如果此图像作为纹理加载,则使用 OpenGL 将其倾斜非常简单。您实际上只需绘制一个全屏四边形,并使用黄色校正点作为每个点的 UV 坐标。

【讨论】:

  • 矩形上的纹理将被扭曲,因此可以看到对角线。要正确映射“透视”矩形,我们需要使用纹理 z 坐标进行拨号。
  • 在这种浅角度的情况下,我不认为这会很重要。但是如果把它做好是非常重要的,那么使用 OpenGL 仍然很容易。只需将图像绘制为四边形(这次仅保留 UV 坐标),但不要将相机正面对准它,而是稍微调整相机位置以补偿原始图片的倾斜。现在唯一的挑战是弄清楚相机的放置位置。
  • 该解决方案的唯一问题是任何想要进行透视校正的人都希望以完整的原始分辨率保存图像(或者考虑到控件进行的自然裁剪,尽可能接近它)点)。因此,在这种情况下,您可以在屏幕上很好地显示经过透视校正的图像,但是否可以将其保存到磁盘?
  • 感谢您的建议 - 这听起来是一个不错的解决方案!我现在的问题是如何“做”并实现这一点。我对 OpenGL ES 有基本的了解,但我不确定如何将图像绘制为四边形。
  • 绘制一个四边形是您能做的最简单的事情。您只需使用两个三角形绘制一个平面矩形。
【解决方案3】:

我不确定您是否尝试过 Opencv 库,但它有一个非常好的方法来纠偏图像。我这里有一个小的 sn-p,它需要一个角数组,例如你的四个角,以及将其映射到的最终大小。

您可以在OpenCV site 上阅读warpPerspective 的手册页。

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

【讨论】:

  • 谢谢,我会调查的!
  • @JakobHalskov,你们每个人都试过这个,还是找到不同的解决方案?
  • @JakobHalskov,如果您尝试我提供的解决方案或其他人的解决方案会很好。代码不清楚还是需要更多解释?
【解决方案4】:

我不知道您的情况的确切解决方案,但有梯形的方法:http://www.comp.nus.edu.sg/~tants/tsm/TSM_recipe.html - 这个想法是不断构建变换矩阵。从理论上讲,您可以添加将您的形状转换为 Trapecy 的转换。

还有很多这样的问题:https://math.stackexchange.com/questions/13404/mapping-irregular-quadrilateral-to-a-rectangle,但是我没有查解决办法。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-09-10
  • 2014-05-04
  • 2018-01-11
  • 1970-01-01
  • 2014-12-20
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多