Error de reproyección y calibración mano-ojo del robot basado en OpenCV-Python (método de calibración de nueve puntos) - código adjunto

Calibración y reproyección de mano-ojo de robot basada en OpenCV-Python (método de calibración de 9 puntos)

Prefacio:

El artículo anterior se reimprimió y escribió el principio de la calibración de nueve puntos.

Este artículo es para registrar cómo calibrar y calcular los parámetros de calibración y la precisión de la reproyección.
Parece que no he buscado las palabras clave relacionadas de "calibración de 9 puntos" y "reproyección" en la comunidad china.
Pero en el método de calibración de Zhang Zhengyou, hay un concepto de error de reproyección.
La matriz de transformación calculada M se sustituye en la fórmula de transformación para calcular el error entre la nueva coordenada objetivo y la coordenada original.
Expresado por la fórmula:

new_target_pos = origin_pos * M
e = MSE (new_target_pos, target_pos)

Intuitivamente, si nuestros parámetros de calibración cubren todas las muestras y se ajustan por el método de mínimos cuadrados, entonces el error obtenido debería ser relativamente pequeño.
Así que tomé prestados los métodos de aprendizaje profundo de uso común y dividí el conjunto de entrenamiento y el conjunto de prueba.
Y probó el impacto de diferentes muestras de entrenamiento en los resultados.
¡El resultado es asombroso!

  1. De hecho, esta función se puede usar con 3 puntos, pero debe haber al menos 3 puntos, porque 1 punto tiene dos ecuaciones y hay 6 incógnitas.
    Puede haber algunos puntos anormales en el conjunto de datos, ¡y los puntos anormales tienen una gran influencia en los resultados!
  2. Siempre que encuentre los puntos de datos correctos, los resultados serán mejores si la optimización no está optimizada.
  3. Si hay un error particularmente grande, use un poco más de datos, el efecto también es bueno.
  4. El error de reproyección es de 0,4 mm o 0,4 píxeles.

proceso de experimento:

Calibración ojo a mano: la
cámara está fija y la posición relativa al sistema de coordenadas de la base del robot permanece sin cambios. Y el extremo del robot se mueve en un plano fijo, es decir, solo se requiere una relación de transformación de una matriz de homografía.

El proceso del experimento es el siguiente:

  1. Configure la escena del sistema mano-ojo: la cámara está fija y el brazo robótico impulsa la punta de la aguja para que se mueva en un plano fijo.
  2. Recolección de muestras de calibración. Incluida la adquisición de imágenes de la cámara y la correspondiente adquisición de la configuración de la articulación del robot. –Calibration_data_collected_main.py
  3. El procesamiento de imágenes extrae la punta de la aguja de calibración y calcula las coordenadas de la punta de la aguja en el sistema de coordenadas del robot. Registre las coordenadas de píxeles de la punta, las coordenadas mundiales de la punta y las coordenadas finales de cada punto de ubicación
  4. Calcule la matriz de parámetros de calibración M--calibration_class.py
  5. Calcule el error de reproyección avg_e--calibration_class.py

La configuración del entorno principal y las herramientas utilizadas en el experimento de calibración son:

  • Sistema operativo: Windows 7 de 64 bits

  • Herramienta de procesamiento de imágenes: OpenCV-Python 3.4. * Si no se puede instalar, la versión es 4. * o superior, y estimado2DAffine parece funcionar. No lo he probado.

  • Robot y cámara: brazo robótico colaborativo de siete grados de libertad Siasun SCR5, cámara industrial Hikvision MV-CA013-21UC

Calibration_class.py se puede utilizar solo. Siempre que haya un conjunto independiente de puntos de calibración.

Entonces, ¿ir al código?

Código:

Primero cuelgue mi enlace de github, este código es demasiado.
https://github.com/kaixindelele/Eye-to-Hand-Calibration
Si le ayuda, recuerde pedir una estrella ~
Código principal:

Calcular la matriz de conversión m

    def get_m(self,
              origin_points_set,
              target_points_set):
        # 确保两个点集的数量级不要差距过大,否则会输出None,看到这个输出,我直接好家伙。
        # 明明回家前,还能输出一个好的转换矩阵,为什么一回家就报错?我错哪儿了...
        m = cv2.estimateRigidTransform(origin_points_set, 
                                       target_points_set,
                                       fullAffine=True)
        return m

Cálculo del error de reproyección:

def reproject(self, 
                  origin_points_set,
                  target_points_set,
                  m):
        error_list = []
        for index in range(len(origin_points_set)):
            p_origin = list(origin_points_set[index])
            p_origin.append(1)
            p_origin = np.array(p_origin)
            p_tar = target_points_set[index]    
            new_tar = np.dot(m, p_origin)
            error = np.linalg.norm(new_tar-p_tar[:2])            
            error_list.append(error)

        print("avg_e:", np.mean(np.array(error_list)))
        return np.mean(np.array(error_list))

Prueba de número de muestra de entrenamiento de errores de reproyección:

Análisis de datos: el
eje horizontal es el número de muestras de entrenamiento, comenzando desde 9 y terminando en 29, y el tamaño total de la muestra es 37; el
eje vertical es el tamaño del error, en milímetros;
explicación del título: xy son las coordenadas de la punta de la aguja, uv son las coordenadas del píxel del píxel de la aguja, xy2uv Significa calcular m en uv = m xy a través de la calibración de nueve puntos, y luego sustituir m en la muestra de prueba para calcular el nuevo uv_pred_test = m xy_test, y el error de cálculo e = mse (uv_pred, uv_origin_test)
si es mt, entonces lo es. Después de calcular m por uv = m * xy, use un sistema de ecuaciones lineales similar al siguiente:
t_rx = (A * t_px) + B * t_py + C);
t_ry = (D * t_px) + E * t_py + F) ;

Resuelva el mt en xy = mt * uv. Luego calcule el error de reproyección.
Los resultados se han analizado en el prefacio.

Por favor agregue la descripción de la imagen

Por favor agregue la descripción de la imagen
Por favor agregue la descripción de la imagen
Por favor agregue la descripción de la imagen

para resumir:

Con tantos registros, de hecho, el contenido principal no es nada innovador.
En cuanto al error de reproyección de la calibración de nueve puntos, vi que había un artículo en ICRA en 19 años que realmente se usó.
Pero tienen una estructura de ojo en mano. Los dos brazos robóticos son mucho más complicados en estructura y principio que el mío ...
Mi pequeño proyecto me llevó cerca de una semana. ¿A dónde se fue el tiempo?
Lo revisé:
una es la duda sobre todo el proceso de calibración, nunca calibré este tipo de estructura mano-ojo, ni encontré un juego de herramientas listo para usar.
No entendía todo el flujo de información, por lo que ni siquiera sabía qué datos recopilar al principio.
La segunda es que no tenemos una placa de calibración. Para la detección de puntos característicos, tenemos que usar el programa de detección de puntas escrito por mí. He ajustado este programa durante mucho tiempo. Finalmente, usando la información de la escena, escribí un módulo de detección optimizado y mejor, que puede ser en 0.04 segundos. A la velocidad de un cuadro, se logra un error dentro de 2 píxeles.
Luego está este problema de la versión de OpenCV basura, las versiones superiores a 4 no tienen cv2.estimateRigidTransform. Solo puedo encontrar la versión 3.4.
Finalmente, existe el problema de la precisión del número de punto flotante, porque el rango de coordenadas de píxeles es 0-280, y el rango de coordenadas iniciales de punto de aguja es 0-0,8, que es una diferencia de tres órdenes de magnitud. El conjunto de puntos es directamente en la función Diferentes computadoras El valor de retorno es diferente para diferentes hardware. Puedo obtener una matriz m con un valor muy pequeño en la computadora de escritorio, pero en mi computadora portátil, el valor de retorno es Ninguno con el mismo código y datos. Me pregunté si mi computadora portátil estaba rota.
Haz una prueba: prueba
en el laboratorio de Google, la máxima precisión es float128 El
script de prueba es muy simple:

import numpy as np
print(np.finfo(np.longdouble))

out:Machine parameters for float128
---------------------------------------------------------------
precision =  18   resolution = 1e-18
machep =    -63   eps =        1.084202172485504434e-19
negep =     -64   epsneg =     5.42101086242752217e-20
minexp = -16382   tiny =       3.3621031431120935063e-4932
maxexp =  16384   max =        1.189731495357231765e+4932
nexp =       15   min =        -max

Y la máxima precisión de mi portátil es float64. Interesante, este pozo debe ser recordado, tal vez cuando será atacado por esta cosa.

Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max

Supongo que te gusta

Origin blog.csdn.net/hehedadaq/article/details/113486527
Recomendado
Clasificación