Tengo 2 imágenes de prueba aquí. Mi pregunta es, ¿cómo hacer el mapa de la plaza en la primera imagen en el cuadrilátero en la segunda imagen sin recortar la imagen.

Imagen 1:
Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

Imagen 2:
Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

Aquí está mi código actual usando openCV warpPerspective función.

import cv2
import numpy as np

img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]])
img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]])

h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners)
im = cv2.imread("image1.png")
out = cv2.warpPerspective(im, h, (800,800))
cv2.imwrite("result.png", out)

Resultado:
Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

Como se puede ver, porque de dsize=(800,800) parámetro en el warpPerspective función, que no puede obtener una vista completa de la imagen 1. Si puedo ajustar el dsize, la plaza no se asigne correctamente. Hay alguna forma de cambiar el tamaño de la imagen de salida, por lo que puedo conseguir todo el cuadro de la imagen 1?

podría usted comentar «Si puedo ajustar el dsize, la plaza no se asigne correctamente»? Es deformado? traducido? escala? ect. Otra imagen sería útil

OriginalEl autor Rafiq Rahim | 2012-10-25

3 Comentarios

  1. 8

    Sí, pero usted debe darse cuenta de que la imagen de salida podría ser muy grande. Rápidamente me escribió el siguiente código en Python, pero incluso un 3000 x 3000 de la imagen podría no encajar en la salida, es simplemente demasiado grande, debido a la transformación. Aunque, aquí está mi código, espero que sea de utilidad para usted.

    import cv2
    import numpy as np
    import cv           #the old cv interface
    
    img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]])
    img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]])
    
    h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners)
    im = cv2.imread("image1.png")

    Crear una imagen de salida aquí, he utilizado (3000, 3000) como un ejemplo.

    out_2 = cv.fromarray(np.zeros((3000,3000,3),np.uint8))

    Usando la vieja cv interfaz, escribí directamente a la salida, y para que no se recorta. He intentado esto con la cv2 interfaz, pero por alguna razón no funcionó… tal vez alguien puede arrojar algo de luz sobre esto?

    cv.WarpPerspective(cv.fromarray(im), out_2, cv.fromarray(h))
    cv.ShowImage("test", out_2)
    cv.SaveImage("result.png", out_2)
    cv2.waitKey()

    De todos modos, esto da una imagen muy grande, que contiene la imagen original 1, deformado. Toda la imagen será visible si se especifica la salida de la imagen a ser lo suficientemente grande. (Que puede ser muy grande, de hecho!)

    Espero que este código puede ayudar a usted.

    Al principio iba a añadir el factor de traducción de la homografía, obtener las opiniones de las distintas regiones de la imagen transformada y, a continuación, combinar los puntos de vista por completo. Pero la solución parece mejor! Gracias!
    No hay problema, me alegro de que mi solución ayudado a usted.

    OriginalEl autor hjweide

  2. 33

    Mi solución es calcular el resultado del tamaño de la imagen y, a continuación, hacer una traducción.

    def warpTwoImages(img1, img2, H):
    '''warp img2 to img1 with homograph H'''
    h1,w1 = img1.shape[:2]
    h2,w2 = img2.shape[:2]
    pts1 = float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2)
    pts2 = float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2)
    pts2_ = cv2.perspectiveTransform(pts2, H)
    pts = concatenate((pts1, pts2_), axis=0)
    [xmin, ymin] = int32(pts.min(axis=0).ravel() - 0.5)
    [xmax, ymax] = int32(pts.max(axis=0).ravel() + 0.5)
    t = [-xmin,-ymin]
    Ht = array([[1,0,t[0]],[0,1,t[1]],[0,0,1]]) # translate
    result = cv2.warpPerspective(img2, Ht.dot(H), (xmax-xmin, ymax-ymin))
    result[t[1]:h1+t[1],t[0]:w1+t[0]] = img1
    return result
    dst_pts = float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)
    src_pts = float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    result = warpTwoImages(img1_color, img2_color, M)

    Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

    OriginalEl autor arcticfox

  3. 0

    Primero, siga la anterior solución para el cálculo de la matriz de homografía. Después de la matriz de homografía, usted necesita para deformar la imagen con respecto a la matriz de Homografía. Por último, la combinación de la imagen distorsionada.

    Aquí, voy a compartir otra idea que podría ser utilizado para combinar las imágenes deformadas. (La anterior respuesta, utiliza una serie de índices para ser superposición, aquí estoy usando la máscara de retorno de la inversión)

    Máscara de la Región de Interés (ROI) y la Imagen con el Negro. Luego agregar la imagen con el retorno de la inversión. (Ver OpenCV Máscara De Bits Tutorial)

    def copyOver(source, destination):
    result_grey = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(result_grey, 10, 255, cv2.THRESH_BINARY)
    mask_inv = cv2.bitwise_not(mask)
    roi = cv2.bitwise_and(source, source, mask=mask)
    im2 = cv2.bitwise_and(destination, destination, mask=mask_inv)
    result = cv2.add(im2, roi)
    return result
    warpedImageB = cv2.warpPerspective(imageB, H, (imageA.shape[1], imageA.shape[0]))
    result = copyOver(imageA, warpedImageB)

    Primera Imagen:

    Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

    Segunda Imagen:

    Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

    Cosido Imagen:
    Cómo mostrar la imagen completa cuando el uso de OpenCV warpPerspective

    Hay una forma automática para quitar el exceso de «negro» áreas para el cosido de la imagen? O deformar el cosido de la imagen para que ocupe toda el área de la imagen?
    Yo no lo he probado, pero tal vez usted podría tratar de encontrar la mayor rectángulo delimitador y el cultivo. Aunque, yo no lo he probado, puedo prever que no es fácil.
    trató de esta manera, pero hay un fallo en la línea de warpedImageB = cv2.warpPerspective(imageB, H, (imageA.shape[1], imageA.shape[0])) porque esto va a suponer un recorte de una parte de la imageB después de la deformación. Mira la respuesta de @articfox cuando una traducción se añade para incluir la imagen después de la deformación.

    OriginalEl autor Yeo

Dejar respuesta

Please enter your comment!
Please enter your name here