Template matching tolerante a rotación para inspección pass/fail
cv2.matchTemplate con TM_CCOEFF_NORMED en cada ángulo y quedarse con la mejor puntuación. Una puntuación de 0.85 o superior significa que el marcaje impreso coincide con la referencia golden: la pieza pasa.Por qué rotar la captura y no la plantilla
cv2.warpAffine) mantiene la plantilla intacta. El rango de búsqueda de ±15° cubre lo que una pieza puede girar de forma realista en el utillaje; cualquier valor mayor es un error de posicionamiento que de todos modos merece rechazo.TM_CCOEFF_NORMED como puntuación pass/fail
Ajustar el paso de ángulo frente al tiempo de ciclo
Un fragmento de la implementación
Tal cual del ejemplo desplegado en el Raspberry Pi + cámara USB — cópialo libremente:
def binary_silkscreen(text="IS-42", angle=0.0, noise=False):
"""Generates a binary silkscreen image, optionally rotated."""
img = np.zeros((200, 300), np.uint8)
cv2.putText(img, text, (60, 120), cv2.FONT_HERSHEY_SIMPLEX,
1.5, 255, 4)
if angle:
M = cv2.getRotationMatrix2D((150, 100), angle, 1.0)
img = cv2.warpAffine(img, M, (300, 200))
if noise: # simulates stray pixels left by the adaptive threshold
salt = np.random.rand(*img.shape) > 0.995
img[salt] = 255
return imgEl ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.
Preguntas frecuentes
¿Por qué no usar feature matching como ORB o SIFT?
Las impresiones binarizadas tienen pocos keypoints estables, y el feature matching añade complejidad de ajuste. Para una cámara fija que comprueba un marcaje conocido, la búsqueda exhaustiva de rotación sobre template matching es más simple, determinista y suficientemente rápida.
¿Cómo se eligió el umbral de 0.85?
Empíricamente, registrando las puntuaciones de piezas buenas y defectuosas conocidas. Las piezas buenas se agrupaban por encima de 0.90 y las defectuosas por debajo de 0.75, así que 0.85 deja margen de seguridad en ambas direcciones.
¿Y si mis piezas pueden llegar con cualquier ángulo?
Amplía el bucle a 360 grados con una primera pasada gruesa y refina después alrededor del mejor ángulo. El ejemplo mantiene ±15° porque el utillaje limita la orientación en la línea real.