OpenCV中的图像转换

时间:2012-04-28 14:01:25

标签: python opencv wolfram-mathematica computer-vision

此问题与此问题有关:How to remove convexity defects in sudoku square

我试图在Mathematica to OpenCV-Python中实施nikie's answer。但我陷入了程序的最后一步。

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

enter image description here

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

enter image description here

(别介意两张图片的亮度差异。)

问题: 我怎么能在OpenCV-Python中做到这一点?我使用的是cv2版本。

2 个答案:

答案 0 :(得分:33)

除了etarion的建议外,您还可以使用remap功能。我写了一个快速的脚本来展示你如何做到这一点。在编辑时,这在Python中非常简单。这是测试图像:

distorted image

这是翘曲后的结果:

warped image

以下是代码:

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)

我想你可以google并找到griddata的功能。简而言之,它进行插值,在这里我们使用它将稀疏映射转换为密集映射,因为cv2.remap需要密集映射。我们只需要将值转换为float32,因为OpenCV会抱怨float64类型。请告诉我它是怎么回事。

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

答案 1 :(得分:1)

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