Principio de Calibración Automatizada con Nueve Puntos para Sistemas de Visión Industrial

En aplicaciones industriales, la calibración define la relación entre las coordenadas capturadas por una cámara y las coordenadas reales del sistema mecánico, como un pórtico o brazo robótico. Por ejemplo, si la cámara detecta un punto en coordenadas C1 (Cx, Cy), la calibración calcula el punto correspondiente R1 (Rx, Ry) en el sistema mecánico.

Esta relación se modela mediante transformaciones afines, que combinan traslación, escalado, rotación y cizallamiento. Para determinar la matriz de transformación afín, se requieren al menos seis parámetros, lo que puede lograrse con un mínimo de tres puntos de correspondencia, ya que cada punto proporciona dos ecuaciones. No obstante, el uso de nueve puntos mejora la precisión al ofrecer múltiples combinaciones para calcular un promedio estable, similar a cómo π=3.1415926 es suficiente para muchos cálculos.

Para implementar la calibración de nueve puntos, se obtienen las coordenadas de píxeles de la cámara [C1, C2, ..., C9] y las coordenadas mecánicas correspondientes [R1, R2, ..., R9]. Estos datos se aplican al operador vector_to_hom_mat2d de Halcon para calcular la matriz de transformación afín.


* Coordenadas de píxeles
pixelX:=[1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6]
pixelY:=[1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3]

* Coordenadas mecánicas
mecanX:=[50,51.999,54.999,56.999,59.999,62.996,-4.999,-3,0,1.999,4.999,7.995,-59.998,-57.001,-55.001,-52.001,-49.003,-45.005]
mecanY:=[-93.3,-47.299,0.002,45.499,91.498,135.493,-92.301,-44.3,0,46.999,91.497,135.494,-90.297,-44.297,1.003,46.999,91.497,134.494]

* Calcular la matriz de transformación afín
vector_to_hom_mat2d (pixelX, pixelY, mecanX, mecanY, MatrizAfin)

* Guardar la matriz en archivo
serialize_hom_mat2d (MatrizAfin, DatosSerializados)
open_file ('MatrizAfin.mat', 'output_binary', ArchivoHandle) 
fwrite_serialized_item (ArchivoHandle, DatosSerializados) 
close_file (ArchivoHandle)

El método tradicional para obtener los puntos de correspondencia utiliza una aguja física acoplada al sistema mecánico. Se posiciona la aguja en cada punto del patrón de calibración, registrando las coordenadas mecánicas reales, mientras la cámara captura las coordenadas de píxeles.

Una alternativa más automatizada elimina la aguja mediante rotaciones. Por ejemplo, al rotar 180 grados desde un punto mecánico R1 (Rx, Ry), se capturan dos coordenadas de píxeles C1 y C2, y el punto real se calcula como el punto medio entre ellas. Para mayor precisión, se pueden rotar múltiples ángulos para ajustar una elipse y validar el punto.

Este método se aplica a cámaras fijas (visión externa), como cámaras superiores o inferiores. Para sistemas con cámaras móviles (visión en mano), se requieren técnicas diferentes.


private Position actualizarMatrizPuntos(Position puntoPCB, Position puntoDestino)
{
    this.robotActual.IrAPosicion(puntoPCB);
    this.cilindroActual.Abrir();
    this.robotActual.IrAPosicion(puntoDestino);
    this.robotActual.IrAPosicion(puntoDestino);
    this.cilindroActual.Cerrar();
    Thread.Sleep(600);
    Position puntoElevado = puntoDestino.Copiar();
    puntoElevado.Z = this.robotActual.ObtenerZSegura();
    this.robotActual.IrAPosicion(puntoElevado);
    this.robotActual.IrAPosicion(puntoSeguro);
    Position puntoImagen1 = this.obtenerPuntoMarca();
    this.robotActual.IrAPosicion(puntoDestino);
    this.cilindroActual.Abrir();
    Position puntoDestino2 = puntoDestino.Copiar();
    puntoDestino2.Z = this.robotActual.ObtenerZSegura();
    this.robotActual.IrAPosicion(puntoDestino2);
    if (puntoDestino2.U > 90)
    {
        puntoDestino2.U -= 180;
    }
    else if (puntoDestino2.U < -90)
    {
        puntoDestino2.U += 180;
    }
    else
    {
        puntoDestino2.U += 180;
    }
    this.robotActual.IrAPosicion(puntoDestino2);
    puntoDestino2.Z = puntoDestino.Z;
    this.robotActual.IrAPosicion(puntoDestino2);
    this.cilindroActual.Cerrar();
    Thread.Sleep(600);
    this.robotActual.IrAPosicion(puntoSeguro);
    Position puntoImagen2 = this.obtenerPuntoMarca();
    listaPuntosImagen.Add(new Position() { X = (puntoImagen1.X + puntoImagen2.X) / 2, Y = (puntoImagen1.Y + puntoImagen2.Y) / 2 });
    listaPuntosRobot.Add(puntoDestino2.Copiar());
    return puntoDestino2;
}

public void GuardarMatriz(List<position> listaImagen, List<position> listaRobot, string ruta)
{
    HTuple coordenadasXImagen = new HTuple(), coordenadasYImagen = new HTuple();
    HTuple coordenadasXRobot = new HTuple(), coordenadasYRobot = new HTuple();
    for (int i = 0; i < listaImagen.Count; i++)
    {
        coordenadasXImagen[i] = listaImagen[i].X;
        coordenadasYImagen[i] = listaImagen[i].Y;
        coordenadasXRobot[i] = listaRobot[i].X;
        coordenadasYRobot[i] = listaRobot[i].Y;
    }
    HTuple matrizAfin = new HTuple(), datosSerializados = new HTuple();
    HTuple archivoHandle = new HTuple();
    matrizAfin.Dispose();
    HOperatorSet.VectorToHomMat2d(coordenadasXImagen, coordenadasYImagen, coordenadasXRobot, coordenadasYRobot, out matrizAfin);
    datosSerializados.Dispose();
    HOperatorSet.SerializeHomMat2d(matrizAfin, out datosSerializados);
    archivoHandle.Dispose();
    HOperatorSet.OpenFile(ruta, "output_binary", out archivoHandle);
    HOperatorSet.FwriteSerializedItem(archivoHandle, datosSerializados);
    HOperatorSet.CloseFile(archivoHandle);
    coordenadasXImagen.Dispose();
    coordenadasYImagen.Dispose();
    coordenadasXRobot.Dispose();
    coordenadasYRobot.Dispose();
    matrizAfin.Dispose();
    datosSerializados.Dispose();
    archivoHandle.Dispose();
}
</position></position>

Etiquetas: calibración de nueve puntos transformación afín visión industrial Halcon robótica industrial

Publicado el 7-10 19:54