2016-05-13 42 views
3

我从Image transformation in OpenCV的答案https://stackoverflow.com/a/10374811/4828720中的代码,并试图使其适应我的图像。我的OpenCV重映射()ing有什么问题?

我的源图像: My source image

在这里面,我确定的格子砖的中心的像素坐标,这里所示:

Source points

我的目标分辨率784我计算像素的目标坐标。我得到的代码是这样的:

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

source = np.array([ 
    [315, 15], 
    [962, 18], 
    [526, 213], 
    [754, 215], 
    [516, 434], 
    [761, 433], 
    [225, 701], 
    [1036, 694], 
], dtype=int) 

destination = np.array([ 
    [14, 14], 
    [770, 14], 
    [238, 238], 
    [546, 238], 
    [238, 546], 
    [546, 546], 
    [14, 770], 
    [770, 770] 
], dtype=int) 

source_image = cv2.imread('frames.png') 

grid_x, grid_y = np.mgrid[0:783:784j, 0:783:784j] 
grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic') 
map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(784,784) 
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(784,784) 
map_x_32 = map_x.astype('float32') 
map_y_32 = map_y.astype('float32') 
warped_image = cv2.remap(source_image, map_x_32, map_y_32, cv2.INTER_CUBIC) 
cv2.imwrite("/tmp/warped2.png", warped_image) 

如果我运行它,没有源点在他们的目的地结束了,但我得到一个扭曲的混乱来代替。我添加的目标点之上的位置:

My result

我要去哪里错了?我注意到我的网格和地图数组并不像示例中那样分布得很好。我的积分是否太少?我是否需要在常规电网中使用它们?我只尝试使用外角的四个点也没有运气。

回答

0

整个问题是,我再次得到了由numpy的的行/列的索引,而不是X/Y混淆。 #opencv IRC频道中的人指出了它。我的源和目的数组必须有自己的列切换:

source = np.array([ 
    [15, 315], 
    [18, 962], 
    [213, 526], 
    [215, 754], 
    [434, 516], 
    [433, 761], 
    [701, 225], 
    [694, 1036], 
], dtype=int) 

destination = np.array([ 
    [14, 14], 
    [14, 770], 
    [238, 238], 
    [238, 546], 
    [546, 238], 
    [546, 546], 
    [770, 14], 
    [770, 770] 
], dtype=int) 

然后它的工作如预期(忽略丑陋扭曲,这是坐标的简单列表中找到的bug):

enter image description here

1

如果你只有8点扭曲你的图像没有真正的扭曲,我会建议使用透视转换here描述。

您引用的链接会尝试消除导致非直线的额外扭曲,但图像中的所有线条都是笔直的。

代码是这样:

import cv2 
import numpy as np 
import matplotlib.pyplot as plt 

img = cv2.imread('image.png') 
rows,cols,ch = img.shape 

pts1 = np.float32([ 
    [315, 15], 
    [962, 18], 
    [225, 701], 
    [1036, 694], 
], dtype=int) 

pts2 = np.float32([ 
    [14, 14], 
    [770, 14], 
    [14, 770], 
    [770, 770] 
], dtype=int) 

M = cv2.getPerspectiveTransform(pts1,pts2) 

dst = cv2.warpPerspective(img,M,(784,784)) 

plt.subplot(121),plt.imshow(img),plt.title('Input') 
plt.subplot(122),plt.imshow(dst),plt.title('Output') 
plt.show() 

enter image description here

+0

我的意思是包括一段说透视矫正是不够的。它几乎是,但我想要更多。对不起,谢谢!这里http://i.imgur.com/Is5rwrq.png是在你的结果上绘制的黑条,你可以看到图像的某些部分存在弯曲失真。我的8分实际上只是一种简化,实际上我会用更多。我失去了为什么它现在无法正常工作。 – bugmenot123

+0

在这种情况下,我建议你检测每一行的交集。这里有一个源代码的绚丽例子:http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-a-sudoku-square/11366549#11366549 – tfv

+0

这是我的计划,但它没有为我的图像开箱即用(我的网格几乎没有区别),再加上我认为重新映射值得一试。 – bugmenot123