Búsqueda de sitios web

Cómo crear experiencias inmersivas de realidad aumentada con OpenCV


La realidad aumentada puede ofrecer cualquier cosa, desde distracciones divertidas hasta modelos serios del mundo real, pero tendrás que empezar por lo básico.

La realidad aumentada (AR) fusiona la realidad con el contenido virtual superponiendo información digital en un entorno del mundo real. En los últimos años, los avances en visión por computadora y procesamiento de imágenes han facilitado el desarrollo de aplicaciones de RA.

OpenCV es una popular biblioteca de visión por computadora de código abierto. Proporciona herramientas y algoritmos que le ayudarán a crear experiencias de RA atractivas. Para crear el programa AR, elegirá una imagen de proyección, detectará un objeto marcador de posición físico y luego proyectará y renderizará el contenido AR.

Configurar el entorno

Antes de comenzar a codificar, debe preparar su entorno de desarrollo. Comience creando un entorno virtual, luego ejecute este comando de terminal para instalar NumPy y OpenCV:

pip install opencv-contrib-python numpy

Utilizará OpenCV para la funcionalidad de visión por computadora y NumPy para calcular una matriz de homografía más adelante en el código.

Asegúrese de instalar la biblioteca opencv-contrib-python y no opencv-python. Esto se debe a que opencv-python no tiene el módulo cv2.aruco en el que dependerá en gran medida para crear el programa de realidad aumentada.

El código fuente completo está disponible en un repositorio de GitHub.

Importar las bibliotecas necesarias

Crea un nuevo archivo Python. Al comienzo del script, importe OpenCV y NumPy:

import numpy as np
import cv2

Importar estas bibliotecas le permitirá utilizar sus funciones en su código.

Elegir la imagen superpuesta

Al renderizar objetos virtuales en la escena AR, necesita una imagen que la aplicación proyectará en los marcadores detectados. Cargue la imagen superpuesta usando la función cv2.imread.

overlay_image = cv2.imread('your_overlay_image.jpg')

Puede utilizar otros métodos para obtener una imagen superpuesta, como generar un modelo 3D dinámicamente.

Detección de marcadores ArUco

Después de elegir la imagen superpuesta, debe determinar la posición en su transmisión de video en la que superponer la imagen. Aquí es donde entran los marcadores ArUco. Son marcadores cuadrados con un patrón de identificación único que puede detectarse fácilmente mediante algoritmos de visión por computadora.

Cuando una aplicación detecta un marcador, puede responder, por ejemplo, proyectando una imagen en su lugar. A continuación se muestra un ejemplo de un marcador ArUco.

Cree una función que detecte marcadores ArUco en su transmisión de video. La función debería convertir la transmisión de video a escala de grises. Luego obtenga el diccionario ArUco según el tamaño de los marcadores y el total de marcadores. Finalmente, debería detectar los marcadores en el feed.

def findArucoMarkers(image, markerSize=6, totalMarkers=250):
    # Convert the image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # Get the Aruco dictionary based on the marker size and total markers
    dictionary_key = getattr(cv2.aruco, f'DICT_{markerSize}X'
                                        f'{markerSize}_{totalMarkers}')
    aruco_dictionary = cv2.aruco.getPredefinedDictionary(dictionary_key)
    # Set the Aruco detector parameters
    aruco_params = cv2.aruco.DetectorParameters()
    # Detect Aruco markers in the grayscale image
    marker_corners, marker_ids, _ = cv2.aruco.detectMarkers(gray, aruco_dictionary,
                                                            parameters=aruco_params)
    return marker_corners, marker_ids

La función devuelve las esquinas y los ID de los marcadores detectados.

Proyectar la imagen superpuesta sobre los marcadores

Una vez que haya detectado los marcadores en el cuadro de video, deberá proyectar la imagen superpuesta sobre ellos. Para lograr esto, escriba una función que calcule la matriz de homografía entre la imagen y el cuadro de video. Esto es para establecer una transformación geométrica que alinee la imagen superpuesta con el marcador ArUco detectado en el cuadro de video.

Luego debes deformar la imagen superpuesta según la homografía. Luego cree una máscara para definir la región de la superposición y, finalmente, combine la imagen de superposición enmascarada con el cuadro de video.

def superimposeImageOnMarkers(video_frame, aruco_markers, overlay_image,
                              video_width, video_height):
    frame_height, frame_width = video_frame.shape[:2]
    if len(aruco_markers[0]) != 0:
        for i, marker_corner in enumerate(aruco_markers[0]):
            marker_corners = marker_corner.reshape((4, 2)).astype(np.int32)
            # Draw a polygon around the marker corners
            cv2.polylines(video_frame, [marker_corners], True, (0, 255, 0), 2)
            # Add marker ID as text on the top-left corner of the marker
            cv2.putText(video_frame, str(aruco_markers[1][i]),
                        tuple(marker_corners[0]),
                        cv2.FONT_HERSHEY_SIMPLEX,0.5, (0, 255, 0), 2)
            # Find the homography matrix to map the overlay image onto the marker
            homography_matrix, _ = cv2.findHomography(
                np.array([[0, 0], [video_width, 0], [video_width, video_height],
                          [0, video_height]], dtype="float32"), marker_corners)
            # Warp the overlay image to align with the marker using homography matrix
            warped_image = cv2.warpPerspective(overlay_image, homography_matrix,
                                               (frame_width, frame_height))
            # Create a mask to apply the warped image only on the marker area
            mask = np.zeros((frame_height, frame_width), dtype="uint8")
            cv2.fillConvexPoly(mask, marker_corners, (255, 255, 255), cv2.LINE_AA)
            masked_warped_image = cv2.bitwise_and(warped_image, warped_image,
                                                 mask=mask)
            # Apply the inverse mask to the video frame
            masked_video_frame = cv2.bitwise_and(video_frame, video_frame,
                                                mask=cv2.bitwise_not(mask))
            # Combine the masked warped image and masked video frame
            video_frame = cv2.add(masked_warped_image, masked_video_frame)
    return video_frame

La función devuelve el cuadro de video con la imagen superpuesta superpuesta a los marcadores ArUco detectados.

Representar el contenido AR

Para renderizar el contenido AR, cree una función que combine los pasos de detección de marcadores y proyección de imágenes. La función debería capturar continuamente fotogramas de vídeo y detectar los marcadores ArUco. Luego debería superponer la imagen superpuesta a los marcadores.

def processVideoFeed(overlay_image):
    # Set the dimensions of the video feed
    video_height = 480
    video_width = 640
    # Open the video capture
    video_capture = cv2.VideoCapture(0)
    # Load and resize the overlay image
    overlay_image = cv2.resize(overlay_image, (video_width, video_height))
    while video_capture.isOpened():
        # Read a frame from the video capture
        ret, video_frame = video_capture.read()
        if ret:
            # Find Aruco markers in the video frame
            aruco_markers = findArucoMarkers(video_frame, totalMarkers=100)
            # Superimpose the overlay image on the markers in the video frame
            video_frame = superimposeImageOnMarkers(video_frame, aruco_markers,
                                                    overlay_image, video_width,
                                                    video_height)
            # Display the video frame with overlay
            cv2.imshow("Camera Feed", video_frame)
        # Check for 'q' key press to exit the loop
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    video_capture.release()
    cv2.destroyAllWindows()

La función muestra el fotograma de vídeo resultante, creando la ilusión de objetos virtuales que aparecen en el mundo real.

Para ejecutar el programa, ejecute la función processVideoFeed.

# Start processing the video feed
processVideoFeed(overlay_image)

Puedes ver un ejemplo de salida del programa en este vídeo:

El marcador en su transmisión de video debe tener el mismo tamaño de marcador y propiedades de marcador totales que los que especificó en el código.

¿Dónde se aplica la realidad aumentada?

Diversas industrias y campos utilizan la realidad aumentada para mejorar la experiencia del cliente. Las aplicaciones AR utilizadas en estas industrias permiten a los clientes visualizar cómo se verían los productos en el mundo real.

Familiarícese con este tipo de aplicación para ver la tecnología en acción.

Artículos relacionados: