Transformation d'Image en OpenCV

cette question est liée à cette question: How to remove convexity defects in sudoku square

j'essayais de mettre en œuvre nikie's answer dans Mathematica to OpenCV-Python . Mais je suis bloqué à l'étape finale de la procédure.

c'est à dire j'ai eu le tous les points d'intersection dans le carré comme ci-dessous:

enter image description here

maintenant, je veux transformer ceci en un carré parfait de taille (450,450) comme indiqué ci-dessous:

enter image description here

(peu importe la différence de luminosité de deux images).

Question: Comment puis-je faire cela en OpenCV-Python? J'utilise la version cv2 .

19
demandé sur Community 2012-04-28 18:01:24

2 réponses

outre la suggestion d'etarion, vous pouvez également utiliser la fonction remap . J'ai écrit un script rapide pour montrer comment tu peux faire ça. Comme vous le voyez, le codage est très facile en Python. Voici l'image test:

distorted image

et c'est le résultat après gauchissement:

warped image

et voici le code:

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)

je suppose que vous pouvez google et trouver ce que griddata fait. En bref, il fait de l'interpolation et nous l'utilisons ici pour convertir des mappages épars en mappages denses comme cv2.le remap nécessite des mappages denses. Nous avons juste besoin de convertir les valeurs en float32 car OpenCV se plaint du type float64. S'il vous plaît laissez-moi savoir comment ça se passe.

Update : si vous ne voulez pas vous appuyer sur Scipy, une façon est d'implémenter la fonction d'interpolation 2d dans votre code, pour exemple, voir le code source de griddata dans Scipy ou un plus simple comme celui-ci http://inasafe.readthedocs.org/en/latest/_modules/engine/interpolation2d.html qui ne dépend que de numpy. Cependant, je suggérerais D'utiliser Scipy ou une autre bibliothèque pour cela, bien que je vois pourquoi exiger seulement CV2 et numpy peut être mieux pour un cas comme celui-ci. J'aimerais savoir comment votre code final résout Sudokus.

31
répondu fireant 2012-04-30 06:34:40

si vous avez des points source et des points de fin (vous n'avez besoin que de 4), Vous pouvez les brancher sur cv2.getPerspectiveTransform, et utiliser ce résultat dans cv2.warpPerspective. Vous donne un bon plat.

1
répondu john ktejik 2017-10-02 03:36:54