python - procesamiento - Transformación de imágenes en OpenCV.
segmentacion de imagenes python (2)
Esta pregunta está relacionada con esta pregunta: How to remove convexity defects in sudoku square
Estaba intentando implementar nikie''s answer
en Mathematica to OpenCV-Python
. Pero estoy atascado en el paso final del procedimiento.
es decir, tengo todos los puntos de intersección en el cuadrado como a continuación:
Ahora, quiero transformar esto en un cuadrado perfecto de tamaño (450,450) como se indica a continuación:
(No importa la diferencia de brillo de dos imágenes).
Pregunta: ¿Cómo puedo hacer esto en OpenCV-Python? Estoy usando la versión cv2
.
Además de la sugerencia de etarion, también puede utilizar la función de remap . Escribí un guión rápido para mostrar cómo puedes hacer esto. Como ves, la codificación es muy fácil en Python. Esta es la imagen de prueba:
y este es el resultado después de la deformación:
Y aquí está el código:
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)
Supongo que puedes buscar en google y encontrar lo que hace griddata. En resumen, hace interpolación y aquí la usamos para convertir asignaciones dispersas en asignaciones densas, ya que cv2.remap requiere asignaciones densas. Solo tenemos que convertir los valores a float32 ya que OpenCV se queja sobre el tipo float64. Hágame saber como va por favor.
Actualización : si no desea confiar en Scipy, una forma es implementar la función de interpolación 2d en su código, por ejemplo, ver el código fuente de griddata en Scipy o uno más simple como este http://inasafe.readthedocs.org/en/latest/_modules/engine/interpolation2d.html que depende solo de numpy. Sin embargo, sugeriría usar Scipy u otra biblioteca para esto, aunque veo por qué requerir solo CV2 y numpy puede ser mejor para un caso como este. Me gustaría saber cómo resuelve Sudokus tu código final.
Si tiene puntos de origen y puntos finales (solo necesita 4), puede enchufarlos en cv2.getPerspectiveTransform, y usar ese resultado en cv2.warpPerspective. Te da un buen resultado plano.