Instituto Politécnico Nacional
Unidad Profesional Interdisciplinaria en Ingeniería y
Tecnologías Avanzadas
AUTOMATIZACION DE LINEA DE PRODUCCION
VISIÓN ARTIFICIAL
Autor:
Cadena Hernández Marco
Torres Tellez Josue Tonatiuh
Carmona Arias Antony Daniel Profesor:
JUAN MENDOZA CAMARGO
Ingeniería Mecatrónica
30 de junio de 2025
Resumen
En este trabajo se presenta el desarrollo e implementación de un sistema de visión
artificial para la clasificación automática de piezas geométricas, específicamente prismas
y cilindros, mediante una cámara USB portátil y un algoritmo de procesamiento de
imágenes desarrollado en Python. El sistema se integra con un robot Mitsubishi RV-M1
para la manipulación automatizada de las piezas. Actualmente, el sistema está funcional
y listo para su validación experimental en condiciones controladas, etapa que se planifica
en el futuro inmediato.
Introducción
La automatización y control de calidad en la industria manufacturera requieren soluciones
eficientes para la inspección y clasificación de productos. La visión artificial se ha
convertido en una herramienta clave para mejorar estos procesos al proporcionar
inspección rápida y precisa. Este proyecto desarrolla un sistema que utiliza una cámara
USB portátil para capturar imágenes de piezas geométricas que luego son clasificadas
mediante un algoritmo en Python basado en procesamiento de imágenes. La integración
con un robot industrial permite la manipulación automática de las piezas, optimizando el
flujo productivo.
Metodología
Tipo de Investigación
La presente investigación se enmarca dentro de un enfoque aplicado, cuantitativo y de
diseño experimental. Se considera aplicada porque busca la resolución práctica de un
problema industrial concreto: la automatización de la inspección y clasificación de
piezas mediante visión artificial integrada a un sistema robótico. El enfoque cuantitativo
se justifica por la necesidad de medir objetivamente el desempeño del sistema a través
de parámetros cuantificables, tales como la precisión en la identificación, el tiempo de
procesamiento y la repetibilidad del proceso. Finalmente, se optó por un diseño
experimental ya que el sistema se desarrolló y evaluó bajo condiciones controladas,
permitiendo realizar ajustes en función de los resultados obtenidos y garantizar la
robustez del sistema antes de su implementación en entornos reales.
Fases del Proyecto
El desarrollo del sistema se dividió en cinco fases principales que abarcan desde la
selección y configuración de los materiales hasta la preparación para la validación
experimental.
Fase de diseño: Esta fase consistió en la selección cuidadosa de los componentes
tanto de hardware como de software. Se eligió una cámara portátil USB de alta
definición con micrófono integrado y reducción de ruido para asegurar la calidad óptica
y acústica de las capturas. La cámara fue montada sobre un trípode para mantener
estabilidad y se colocó una luz LED adicional en el laboratorio para eliminar sombras y
mejorar la uniformidad de iluminación. En paralelo, se estructuró el ambiente de
desarrollo en Visual Studio Code utilizando Python como lenguaje principal, debido a
su versatilidad y amplia disponibilidad de librerías para procesamiento de imágenes.
Fase de recopilación y organización de datos: Se organizaron dos carpetas principales
denominadas “train” y “test”, que contienen subcarpetas con imágenes de las piezas a
clasificar: prismas y cilindros, cada uno dividido en correctos e incorrectos. Esta
organización permite un entrenamiento supervisado del sistema y una evaluación
posterior, asegurando que los datos estén balanceados y que cada imagen mantenga
una resolución uniforme para evitar distorsiones en el procesamiento.
Fase de desarrollo del algoritmo: En esta etapa se diseñó y programó el algoritmo de
visión artificial que comprende las etapas de captura, preprocesamiento,
segmentación, extracción de características y clasificación. El preprocesamiento
incluye la normalización de la imagen y filtrado para reducir ruido, mientras que la
segmentación se realiza para aislar la pieza del fondo. La extracción de características
se basa en medidas geométricas y texturales, que alimentan un modelo probabilístico
para la clasificación de la pieza en una de las cuatro categorías definidas. El sistema
está diseñado para operar en tiempo real, lo que facilita su integración con el robot
industrial.
Fase de integración con sistema robótico: Aunque esta fase está en desarrollo, se
definieron los protocolos para la interacción del algoritmo con el robot Mitsubishi RV-
M1, encargado de posicionar las piezas en la base de inspección. Se diseñó una
interfaz que permita la comunicación fluida entre el sistema de visión y el robot,
garantizando una sincronización precisa para que la inspección sea automática y
eficiente.
Fase de validación: Se planificó un protocolo para pruebas experimentales que incluirá
la evaluación de la precisión en la clasificación, el tiempo total de operación desde la
captura hasta la decisión final, y la repetibilidad del sistema bajo condiciones
constantes. Estos indicadores serán fundamentales para cuantificar la efectividad del
sistema y detectar áreas de mejora.
Materiales y Herramientas
Para el desarrollo del sistema se seleccionaron componentes accesibles y compatibles
con el entorno de desarrollo, lo que facilita la reproducibilidad y escalabilidad del
proyecto. Se utilizó una cámara portátil USB con lente de vidrio de alta definición y
función de enfoque automático, equipada con micrófono y tecnología de reducción de
ruido para asegurar la calidad de captura tanto en imagen como en audio, aunque el
foco principal fue la imagen. La cámara fue montada sobre un trípode en el laboratorio,
complementada con iluminación LED para mejorar las condiciones visuales durante la
captura. En cuanto al software, se empleó Python debido a su robustez y la
disponibilidad de librerías especializadas para procesamiento de imágenes, como
OpenCV y NumPy, y para el desarrollo del entorno se utilizó Visual Studio Code. El
conjunto de datos consistió en imágenes organizadas en carpetas para entrenamiento
y prueba, asegurando una estructura ordenada para facilitar la implementación del
modelo.
Protocolo de Validación
El protocolo diseñado para validar el sistema tiene como propósito verificar su
funcionalidad y eficiencia en un entorno controlado antes de su implementación en
condiciones industriales reales. La validación comprenderá la realización de pruebas
funcionales donde se posicionarán piezas por medio del robot Mitsubishi RV-M1 sobre
la base de inspección, donde la cámara capturará las imágenes que serán procesadas
en tiempo real por el algoritmo de clasificación. Se medirán parámetros clave como la
precisión, definida como la tasa de aciertos en la clasificación correcta de las piezas;
el tiempo de operación, que incluye la captura, procesamiento y decisión; y la
repetibilidad, que evalúa la consistencia del sistema al clasificar múltiples piezas bajo
las mismas condiciones. La recopilación y análisis de estos datos permitirán determinar
la efectividad del sistema y establecer bases para futuros ajustes y optimizaciones.
Conclusión
El desarrollo del sistema de visión artificial integrado al robot Mitsubishi RV-M1 ha
demostrado ser un avance significativo hacia la automatización del proceso de
inspección y clasificación de piezas industriales. A lo largo de la metodología aplicada,
se logró diseñar e implementar un sistema funcional capaz de capturar y procesar
imágenes en tiempo real, utilizando una cámara USB de alta definición y un algoritmo
de clasificación basado en características geométricas y probabilísticas. La
estructuración cuidadosa del conjunto de datos y la programación en Python
proporcionaron una base sólida para el procesamiento y análisis de las piezas.
Aunque aún no se han realizado las pruebas experimentales de validación en el
entorno real, el sistema desarrollado cuenta con los elementos esenciales para evaluar
su desempeño en condiciones controladas, lo que permitirá medir parámetros clave
como la precisión, el tiempo de respuesta y la repetibilidad. Este enfoque garantiza que
los ajustes y mejoras futuras se fundamenten en datos objetivos y cuantificables.
En conclusión, el trabajo realizado sienta las bases para una solución robusta y
escalable en la inspección automatizada de piezas, contribuyendo a la optimización de
procesos industriales y a la reducción de errores humanos. La implementación futura
de la fase de validación será determinante para confirmar el potencial del sistema y su
aplicabilidad en entornos productivos reales.
ANEXOS Codigo que procesa el dataset de
prueba y divide en dos subconjuntos,
import tensorflow as tf entrenamiento y validacion, siendo
esta ultima del 20%
import numpy as np
"""
import cv2
train_ds =
from tensorflow.keras import datasets,
tf.keras.utils.image_dataset_from_dire
layers, models, Sequential
ctory(
import matplotlib.pyplot as plt
# Carga las imagenes de
entrenamiento
from tensorflow import keras r'C:\Users\anton\Desktop\Automatiz
acion\Vision_Artificial\Train',
from tensorflow.keras import layers
validation_split=0.2,
from tensorflow.keras.models import
Sequential subset="training",
seed=123,
"""## Carga de dataset para # Escalado de imagenes, se
entrenamiento recomienda 300,300 en escala de
grises
image_size=(3072, 4096)) ax = plt.subplot(6, 6, i + 1)
plt.imshow(images[i].numpy().ast
ype("uint8"))
val_ds =
tf.keras.utils.image_dataset_from_dire plt.title(class_names[labels[i]])
ctory(
plt.axis("off")
r'C:\Users\anton\Desktop\Automatiz
acion\Vision_Artificial\Test',
validation_split=0.2, #Verificasmos que que las
dimensiones del arreglo sean
subset="validation", correctas
seed=123,
image_size=(50, 50)) for image_batch, labels_batch in
train_ds:
print(image_batch.shape)
#Verificar que las clases a clasificar
sean correctas print(labels_batch.shape)
break
class_names = train_ds.class_names
print("clases: ",class_names) # Primera aproximacion
# Creamos el modelo del tutorial de
Tensorflow
#Sacar muestras del dataset de
entrenamiento
num_classes = len(class_names)
import matplotlib.pyplot as plt #
Importar la libreria de matplolib para
graficar model = Sequential([
layers.Rescaling(1. / 255,
input_shape=(50, 50, 3)),
plt.figure(figsize=(10, 10))
layers.Conv2D(16, 3,
for images, labels in train_ds.take(1): padding='same', activation='relu'),
for i in range(30): layers.MaxPooling2D(),
layers.Conv2D(32, 3, history = model.fit(
padding='same', activation='relu'),
train_ds,
layers.MaxPooling2D(),
validation_data=val_ds,
layers.Conv2D(64, 3,
padding='same', activation='relu'), epochs=epochs
layers.MaxPooling2D(), )
layers.Flatten(),
layers.Dense(128, activation='relu'), # Realizamos las graficas de perdida
y exactitud para validacion y
layers.Dense(num_classes) entrenamiento
])
#Compilacion del modelo con acc = history.history['accuracy']
optimizador adam y Cross entropy para
la perdida, metrica la exactitud val_acc =
history.history['val_accuracy']
model.compile(optimizer='adam',
loss = history.history['loss']
loss=tf.keras.losses.SparseC
ategoricalCrossentropy(from_logits=Tr val_loss = history.history['val_loss']
ue),
metrics=['accuracy'])
epochs_range = range(epochs)
#Vemos la estructura del modelo
plt.figure(figsize=(8, 8))
compilado
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc,
model.summary()
label='Training Accuracy')
plt.plot(epochs_range, val_acc,
# Entrenamos el modelo label='Validation Accuracy')
plt.legend(loc='lower right')
epochs = 2 plt.title('Training and Validation
Accuracy')
print(
plt.subplot(1, 2, 2) "Esta imagen parece ser {} con un
{:.2f} % de exactitud."
plt.plot(epochs_range, loss,
label='Training Loss') .format(class_names[np.argmax(
score)], 100 * np.max(score))
plt.plot(epochs_range, val_loss,
label='Validation Loss') )
plt.legend(loc='upper right')
plt.title('Training and Validation Loss') # Guardamos el modelo para evitar
realizar otra vez el entrenamiento"""
plt.show()
model.save(r'C:\Users\anton\Desktop\
# Cargamos una imagen individual Automatizacion\Vision_Artificial\Model
de prueba y realizamos una prediccion o')
image_path = #Cargamos el modelo guardado
r'C:\Users\anton\Desktop\Automatizaci
on\Vision_Artificial\Producion'
image = loaded_model =
tf.keras.preprocessing.image.load_im tf.keras.models.load_model(r'C:\Users
g(image_path) \anton\Desktop\Automatizacion\Vision
_Artificial\Modelo')
input_arr =
tf.keras.preprocessing.image.img_to_
array(image)
"""Realizamos otra prediccion"""
input_arr = np.array([input_arr]) #
Convert single image to a batch.
predictions = model.predict(input_arr) image_path =
r'C:\Users\anton\Desktop\Automatizaci
on\Vision_Artificial\Test\Cilindro_Corre
cto\WhatsApp Image 2025-06-24 at
# Imprimimos la predeccion 18.29.19 (1).jpeg'
image =
tf.keras.preprocessing.image.load_im
score = tf.nn.softmax(predictions[0])
g(image_path)
input_arr = "Esta imagen parece ser {} con un
tf.keras.preprocessing.image.img_to_ {:.2f} % de exactitud."
array(image)
.format(class_names[np.argmax(
input_arr = np.array([input_arr]) # score)], 100 * np.max(score))
Convert single image to a batch.
)
predictions = model.predict(input_arr)
score = tf.nn.softmax(predictions[0])
image_path =
print( r'C:\Users\anton\Desktop\Automatizaci
on\Vision_Artificial\Test\Cilindro_Corre
"Esta imagen parece ser {} con un cto\WhatsApp Image 2025-06-24 at
{:.2f} % de exactitud." 18.29.19 (1).jpeg'
.format(class_names[np.argmax( image =
score)], 100 * np.max(score)) tf.keras.preprocessing.image.load_im
g(image_path)
)
input_arr =
tf.keras.preprocessing.image.img_to_
image_path = array(image)
r'C:\Users\anton\Desktop\Automatizaci
input_arr = np.array([input_arr]) #
on\Vision_Artificial\Test\Cilindro_Corre
Convert single image to a batch.
cto\WhatsApp Image 2025-06-24 at
18.29.19 (1).jpeg' predictions = model.predict(input_arr)
image = score = tf.nn.softmax(predictions[0])
tf.keras.preprocessing.image.load_im
g(image_path) print(
input_arr = "Esta imagen parece ser {} con un
tf.keras.preprocessing.image.img_to_ {:.2f} % de exactitud."
array(image)
.format(class_names[np.argmax(
input_arr = np.array([input_arr]) # score)], 100 * np.max(score))
Convert single image to a batch.
)
predictions = model.predict(input_arr)
score = tf.nn.softmax(predictions[0])
image_path =
print( r'C:\Users\anton\Desktop\Automatizaci
on\Vision_Artificial\Test\Cilindro_Corre
cto\WhatsApp Image 2025-06-24 at layers.Rescaling(1. / 255,
18.29.19 (1).jpeg' input_shape=(50, 50, 3)),
#image = layers.Conv2D(16, 3,
tf.keras.preprocessing.image.load_im padding='same', activation='relu'),
g(image_path)
layers.MaxPooling2D(),
image
=cv2.imread(image_path,cv2.IMREAD layers.Conv2D(32, 3,
_UNCHANGED) padding='same', activation='relu'),
image = layers.MaxPooling2D(),
cv2.resize(image,(50,50),interpolation
layers.Conv2D(64, 3,
= cv2.INTER_AREA)
padding='same', activation='relu'),
input_arr =
layers.MaxPooling2D(),
tf.keras.preprocessing.image.img_to_
array(image) layers.Flatten(),
input_arr = np.array([input_arr]) # layers.Dropout(0.2),
Convert single image to a batch.
layers.Dense(128, activation='relu'),
predictions = model.predict(input_arr)
layers.Dense(num_classes)
score = tf.nn.softmax(predictions[0])
])
print(
"Esta imagen parece ser {} con un
{:.2f} % de exactitud." """Compilamos el modelo"""
.format(class_names[np.argmax(
score)], 100 * np.max(score))
model.compile(optimizer='adam',
)
loss=tf.keras.losses.SparseC
"""### Dropout ategoricalCrossentropy(from_logits=Tr
ue),
Agregamos dropout al modelo de la
primera aproximacion metrics=['accuracy'])
"""
"""Vemos la estructura del modelo
compilado"""
model = Sequential([
model.summary() epochs_range = range(epochs)
"""Realizamos el entrenamiento""" plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
epochs = 2 plt.plot(epochs_range, acc,
label='Training Accuracy')
history = model.fit(
plt.plot(epochs_range, val_acc,
train_ds, label='Validation Accuracy')
validation_data=val_ds, plt.legend(loc='lower right')
epochs=epochs plt.title('Training and Validation
Accuracy')
)
plt.subplot(1, 2, 2)
"""Realizamos la graficas de perdida y
exactitud, en entrenamiento y plt.plot(epochs_range, loss,
validacion""" label='Training Loss')
plt.plot(epochs_range, val_loss,
label='Validation Loss')
acc = history.history['accuracy']
plt.legend(loc='upper right')
val_acc =
history.history['val_accuracy'] plt.title('Training and Validation Loss')
plt.show()
loss = history.history['loss']
val_loss = history.history['val_loss'] """Guardamos el modelo"""