【问题标题】:Image transformation in OpenCVOpenCV 中的图像转换
【发布时间】:2012-05-09 00:03:53
【问题描述】:

这个问题和这个问题有关:How to remove convexity defects in sudoku square

我试图在Mathematica to OpenCV-Python 中实现nikie's answer。但我被困在程序的最后一步。

我得到了正方形的所有交点,如下所示:

现在,我想把它转换成一个完美的正方形(450,450),如下所示:

(不要介意两张图像的亮度差异)。

问题: 我如何在 OpenCV-Python 中做到这一点?我正在使用cv2 版本。

【问题讨论】:

  • 正如他在回答中建议的那样,只需对每个单独的单元格使用标准转换(您在第一个问题中尝试使用的转换)...
  • 我使用了扭曲透视,它使用 4 个角进行变换。您是说使用相同的每个单元格取 4 分吗?这不是一个耗时的过程吗?
  • 你说的是嵌入式编程吗?我猜不是,因为您在台式机上使用 python ...,不,它不应该引起注意,因为它只有 81 个单元...
  • @AbidRahmanK:我还没有测试过,但我希望透视扭曲变换的运行时间与输出像素的数量成正比。因此,如果它足够快来转换整个网格,那么它应该足够快地转换 81 个网格单元,这些单元只有网格大小的 1/81。

标签: python opencv wolfram-mathematica computer-vision


【解决方案1】:

除了 etarion 的建议,你也可以使用remap 函数。我写了一个快速脚本来展示如何做到这一点。如您所见,这在 Python 中非常简单。这是测试图片:

这是变形后的结果:

这里是代码:

import cv2
from scipy.interpolate import griddata
import numpy as np

grid_x, grid_y = np.mgrid[0:149:150j, 0:149:150j]
destination = np.array([[0,0], [0,49], [0,99], [0,149],
                  [49,0],[49,49],[49,99],[49,149],
                  [99,0],[99,49],[99,99],[99,149],
                  [149,0],[149,49],[149,99],[149,149]])
source = np.array([[22,22], [24,68], [26,116], [25,162],
                  [64,19],[65,64],[65,114],[64,159],
                  [107,16],[108,62],[108,111],[107,157],
                  [151,11],[151,58],[151,107],[151,156]])
grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic')
map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(150,150)
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(150,150)
map_x_32 = map_x.astype('float32')
map_y_32 = map_y.astype('float32')

orig = cv2.imread("tmp.png")
warped = cv2.remap(orig, map_x_32, map_y_32, cv2.INTER_CUBIC)
cv2.imwrite("warped.png", warped)

我想你可以用谷歌搜索一下 griddata 是做什么的。简而言之,它进行插值,在这里我们使用它来将稀疏映射转换为密集映射,因为 cv2.remap 需要密集映射。我们只需要将值转换为 float32,因为 OpenCV 抱怨 float64 类型。请告诉我进展如何。

更新:如果你不想依赖Scipy,一种方法是在你的代码中实现2d插值功能,例如看Scipy中griddata的源代码或更简单的像这样的http://inasafe.readthedocs.org/en/latest/_modules/engine/interpolation2d.html 仅取决于 numpy。虽然,我建议为此使用 Scipy 或其他库,但我明白为什么只需要 CV2 和 numpy 对于这样的情况可能会更好。我想听听您的最终代码如何解决数独问题。

【讨论】:

  • 很好,太棒了。这就是我一直在寻找的。我知道我可以使用cv2.remap,但不知道如何使用。但是有必要使用scipy吗?不能只用 numpy 和 cv2 来完成吗?也可以在一个步骤中用于整个图像的相同方法(即不分成子块)?
  • 为了让自己更容易输入红点的坐标,对图像的一部分进行了处理。在“源”中,您有已经检测到的红点的坐标,在“目标”中,它们在常规网格中的坐标。如果您共享了您的代码,我可以在代码中展示如何执行此操作,无需将图像拆分为子区域。注册。没有使用 Scipy,请参阅答案中的更新。
  • I'd like to hear how your final code solves Sudokus。你想要哪一个?如何解决数独网格?或者关于如何做ocr等的opencv版本? (解数独网格取自我自己写的一篇博客,ocr部分等)
  • 我的意思是,当数独求解器准备好时,您会提供更新。如果这回答了您的问题,您可以通过选择作为答案来奖励我:-)
  • 你好,这段代码中创建grid_x、grid_y有什么用?它们是什么意思?
【解决方案2】:

如果你有源点和终点(你只需要 4 个),你可以将它们插入 cv2.getPerspectiveTransform,并在 cv2.warpPerspective 中使用该结果。给你一个很好的平坦结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多