“AÑO DE LA UNIDAD, LA PAZ Y EL DESARROLLO” UNIVERSIDAD NACIONAL DE SAN AGUSTÍN FACULTAD DE PRODUCCIÓN Y SERVICIOS ESCUELA PROFESIONAL DE INGENIERÍA INDUSTRIAL CURSO: SISTEMAS INTELIGENTES (E) DOCENTE: ING. VELIZ VILCA ISMAEL ESTUDIANTE: ALBERTH RENZO CUAYLA MARCA GRUPO: A CUI: 20074148 AREQUIPA - PERÚ 2023 TABLA DE CONTENIDO TABLA DE CONTENIDO.........................................................................................................1 MARCO TEÓRICO.................................................................................................................. 2 1. Problema del Agente Viajero..........................................................................................2 2. Visión Artificial................................................................................................................ 2 3. Herramientas de Programación..................................................................................... 3 DESARROLLO DE APLICATIVOS......................................................................................... 5 Aplicativo Modelo del Agente Viajero:................................................................................5 Imagen 01 - Captura Aplicativo Agente Viajero..........................................................11 Imagen 02 - Captura Aplicativo Agente Viajero..........................................................11 Aplicativo Visión Artificial:.................................................................................................12 Imagen 03 - Escala de Colores HSV Fuente: https://assets.clip-studio.com/en-us/detail?id=1911795................................12 Imagen 04 - Captura Aplicativo Visión Artificial..........................................................15 Imagen 05 - Captura Aplicativo Visión Artificial..........................................................15 Imagen 06 - Captura Aplicativo Visión Artificial..........................................................16 CONCLUSIONES:................................................................................................................. 17 1 MARCO TEÓRICO 1. Problema del Agente Viajero El Problema del Agente Viajero (PAV) es un desafío fundamental en la optimización combinatoria y la teoría de grafos. Se trata de encontrar la ruta más corta que un agente debe seguir para visitar un conjunto dado de ciudades exactamente una vez y regresar al punto de partida. El PAV tiene aplicaciones en diversos campos, como la logística, la planificación de rutas, la distribución de recursos y la programación de circuitos electrónicos. Para resolver este problema, se han desarrollado diversas estrategias, incluyendo algoritmos exactos como el de Ramificación y Poda, así como algoritmos heurísticos como el Algoritmo del Vecino más Cercano y la Búsqueda Tabú. Además, técnicas más avanzadas como la optimización por enjambre de partículas y algoritmos genéticos también se han aplicado con éxito al PAV, ofreciendo soluciones aproximadas eficientes para instancias de gran tamaño. 2. Visión Artificial La Visión Artificial es un campo interdisciplinario que combina la informática, las matemáticas y la neurociencia para dotar a las máquinas de la capacidad de interpretar y comprender el mundo visual de la misma manera que lo hacen los seres humanos. Python, con sus bibliotecas robustas como OpenCV y TensorFlow, se ha convertido en el lenguaje preferido para desarrollar aplicaciones de Visión Artificial. OpenCV proporciona herramientas para el procesamiento de imágenes y videos, permitiendo tareas como detección de objetos, seguimiento de movimiento, calibración de cámaras y más. TensorFlow, por su parte, facilita la creación y el entrenamiento de redes neuronales profundas para tareas de clasificación, segmentación y generación de imágenes. El uso de Python en Visión Artificial ha democratizado el acceso a esta tecnología, permitiendo a investigadores y desarrolladores implementar soluciones avanzadas y creativas en campos tan diversos como la medicina, la automatización industrial, los vehículos autónomos y la realidad aumentada. 2 3. Herramientas de Programación Para llevar a cabo la implementación de los conceptos teóricos expuestos, se utilizarán diversas herramientas de programación. A continuación, se detallan las bibliotecas y lenguajes de programación específicos que se utilizarán: Python: Se utilizará como lenguaje de programación principal en este trabajo. Python es un lenguaje de programación versátil y de fácil lectura, que proporciona una amplia gama de bibliotecas y herramientas para el desarrollo de aplicaciones científicas y de inteligencia artificial. Se aprovechará su facilidad de uso, su extensa comunidad de desarrollo y su integración con las bibliotecas requeridas. VSCode: Se empleará Visual Studio Code como el entorno de desarrollo integrado (IDE) principal para escribir y depurar el código. VSCode proporciona una interfaz intuitiva y funcionalidades avanzadas que facilitan el desarrollo de programas en Python y Prolog. Su soporte para extensiones y su integración con herramientas de control de versiones mejorarán la productividad durante el desarrollo del trabajo. OpenCV (cv2): OpenCV, o Open Source Computer Vision Library, es una biblioteca de código abierto diseñada para el procesamiento de imágenes y videos. Proporciona una amplia gama de funciones para manipular imágenes y videos, realizar análisis de imágenes, detección y seguimiento de objetos, calibración de cámaras, entre otros. OpenCV es ampliamente utilizada en aplicaciones de Visión Artificial, desde tareas simples de procesamiento de imágenes hasta aplicaciones más complejas como la detección de rostros, la visión por computadora en tiempo real y la robótica. NumPy (np): NumPy es una biblioteca fundamental para la computación numérica en Python. Ofrece soporte para arreglos multidimensionales (matrices y vectores), así como funciones matemáticas y operaciones de álgebra lineal. NumPy es ampliamente utilizado en aplicaciones científicas y de análisis de datos, proporcionando una base sólida para el manejo eficiente de datos numéricos. Tkinter (tk): Tkinter es una biblioteca estándar de Python utilizada para crear interfaces gráficas de usuario (GUI). Proporciona herramientas para crear ventanas, botones, etiquetas y otros componentes de interfaz gráfica. Tkinter es una opción 3 popular para desarrollar aplicaciones con interfaces de usuario simples y es ampliamente utilizada en aplicaciones de escritorio. PIL (Image, ImageTk): Python Imaging Library (PIL) proporciona capacidades de procesamiento de imágenes en Python. Image es una clase que permite cargar, manipular y guardar imágenes en diversos formatos. ImageTk es un módulo que permite mostrar imágenes de PIL en interfaces gráficas creadas con Tkinter, lo que facilita la integración de imágenes en aplicaciones GUI. Pandas (pd): Pandas es una biblioteca de Python utilizada para el análisis y manipulación de datos. Ofrece estructuras de datos flexibles, como DataFrames, que permiten trabajar con datos tabulares de manera eficiente. Pandas es ampliamente utilizado en análisis de datos, limpieza y transformación de datos, así como en la preparación de datos para su posterior análisis o visualización. Matplotlib (plt) y FigureCanvasTkAgg: Matplotlib es una biblioteca de visualización en 2D que permite crear gráficos y visualizaciones de datos en Python. FigureCanvasTkAgg es un módulo de Matplotlib que facilita la integración de gráficos de Matplotlib en interfaces gráficas creadas con Tkinter. Esto permite mostrar gráficos generados con Matplotlib dentro de ventanas de Tkinter, lo que es útil para la visualización interactiva de datos en aplicaciones GUI 4 DESARROLLO DE APLICATIVOS Aplicativo Modelo del Agente Viajero: ENUNCIADO: Buscamos desarrollar un aplicativo en el cual se generará de manera aleatoria un número determinado de ciudades en las cuales mediante el ingreso de datos relevantes se irán poco a poco generando combinaciones en las cuales se irán analizando las distancias de las conexiones de dichas ciudades eligiendo como mejor exponentes aquellos que minimicen la distancia total. CÓDIGO EN PYTHON: from tkinter import * import numpy as np, random, operator, pandas as pd, matplotlib.pyplot as plt import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg class City: def __init__(self,name, x, y): self.name = name self.x = x self.y = y def distance(self, city): xDis = abs(self.x - city.x) yDis = abs(self.y - city.y) distance = np.sqrt((xDis ** 2) + (yDis ** 2)) return distance def __repr__(self): return "(" + str(self.name)+ ")" class Fitness: def __init__(self, route): self.route = route self.distance = 0 self.fitness= 0.0 def routeDistance(self): if self.distance ==0: pathDistance = 0 for i in range(0, len(self.route)): 5 fromCity = self.route[i] toCity = None if i + 1 < len(self.route): toCity = self.route[i + 1] else: toCity = self.route[0] pathDistance += fromCity.distance(toCity) self.distance = pathDistance return self.distance def routeFitness(self): if self.fitness == 0: self.fitness = 1 / float(self.routeDistance()) return self.fitness def createRoute(cityList): route = random.sample(cityList, len(cityList)) return route def initialPopulation(popSize, cityList): population = [] for i in range(0, popSize): population.append(createRoute(cityList)) return population def rankRoutes(population): fitnessResults = {} for i in range(0,len(population)): fitnessResults[i] = Fitness(population[i]).routeFitness() sorted_results=sorted(fitnessResults.items(), key = operator.itemgetter(1), reverse = True) return sorted_results def selection(popRanked, eliteSize): selectionResults = [] df = pd.DataFrame(np.array(popRanked), columns=["Index","Fitness"]) df['cum_sum'] = df.Fitness.cumsum() df['cum_perc'] = 100*df.cum_sum/df.Fitness.sum() for i in range(0, eliteSize): selectionResults.append(popRanked[i][0]) for i in range(0, len(popRanked) - eliteSize): pick = 100*random.random() for i in range(0, len(popRanked)): if pick <= df.iat[i,3]: selectionResults.append(popRanked[i][0]) break 6 return selectionResults def matingPool(population, selectionResults): matingpool = [] for i in range(0, len(selectionResults)): index = selectionResults[i] matingpool.append(population[index]) return matingpool def breed(parent1, parent2): child = [] childP1 = [] childP2 = [] geneA = int(random.random() * len(parent1)) geneB = int(random.random() * len(parent1)) startGene = min(geneA, geneB) endGene = max(geneA, geneB) for i in range(startGene, endGene): childP1.append(parent1[i]) childP2 = [item for item in parent2 if item not in childP1] T1.insert(END, str(startGene) + '\n') T1.insert(END, str(endGene) + '\n') T1.insert(END, str(parent1) + '\n') T1.insert(END, str(parent2) + '\n') T1.insert(END, str(childP1) + '\n') T1.insert(END, str(childP2) + '\n') child = childP1 + childP2 T1.insert(END, str(child) + '\n') return child def breedPopulation(matingpool, eliteSize): children = [] length = len(matingpool) - eliteSize pool = random.sample(matingpool, len(matingpool)) for i in range(0,eliteSize): children.append(matingpool[i]) for i in range(0, length): child = breed(pool[i], pool[len(matingpool)-i-1]) children.append(child) return children def mutate(individual, mutationRate): for swapped in range(len(individual)): if(random.random() < mutationRate): swapWith = int(random.random() * len(individual)) city1 = individual[swapped] 7 city2 = individual[swapWith] individual[swapped] = city2 individual[swapWith] = city1 return individual def mutatePopulation(population, mutationRate): mutatedPop = [] for ind in range(0, len(population)): mutatedInd = mutate(population[ind], mutationRate) mutatedPop.append(mutatedInd) return mutatedPop def nextGeneration(currentGen, eliteSize, mutationRate): popRanked = rankRoutes(currentGen) selectionResults = selection(popRanked, eliteSize) matingpool = matingPool(currentGen, selectionResults) children = breedPopulation(matingpool, eliteSize) nextGeneration = mutatePopulation(children, mutationRate) return nextGeneration def geneticAlgorithm(population, popSize, eliteSize, mutationRate, generations): pop = initialPopulation(popSize, population) progress = [1 / rankRoutes(pop)[0][1]] T1.insert(END,"Initial distance: " + str(progress[0]) + '\n') for i in range(1, generations+1): pop = nextGeneration(pop, eliteSize, mutationRate) progress.append(1 / rankRoutes(pop)[0][1]) if i%50==0: T1.insert(END,'Generation: '+ str(i) + " Distance: " + str(progress[i]) + '\n') bestRouteIndex = rankRoutes(pop)[0][0] bestRoute = pop[bestRouteIndex] fig1, ax = plt.subplots() ax.plot(progress) ax.set_xlabel('Distancias') ax.set_ylabel('Generacion') ax.set_title('Grafica: Mejor Fitness vs Generacion') C1 = FigureCanvasTkAgg(fig1, master=F2); C1.draw(); C1.get_tk_widget().pack(expand=True, fill=BOTH) return bestRoute def RunAlgorithm(*args): cityList = [] Ciud = Cant_Ciudades.get() Indv = Cant_Indv.get() 8 Elit = int(Cant_Indv.get()*Porc_Corte.get()) Mut = Porc_Mutac.get() Gens = Cant_Gen.get() for i in range(Ciud): cityList.append(City(name = i, x=int(random.random() * 100), y=int(random.random() * 100))) best_route=geneticAlgorithm(population=cityList, popSize=Indv, eliteSize=Elit, mutationRate=Mut, generations=Gens) x=[] y=[] for i in best_route: x.append(i.x) y.append(i.y) x.append(best_route[0].x) y.append(best_route[0].y) fig2, bx = plt.subplots(1,1) bx.plot(x, y, '--o') bx.set_xlabel('X') bx.set_ylabel('Y') cx=plt.gca() bx.set_title('Ruta Optima Obtenida') bbox_props = dict(boxstyle="circle,pad=0.3", fc='C0', ec="black", lw=0.5) for i in range(1,len(cityList)+1): cx.text(cityList[i-1].x, cityList[i-1].y, str(i), ha="center", va="center", size=8, bbox=bbox_props) C2 = FigureCanvasTkAgg(fig2, master=F4) C2.draw() C2.get_tk_widget().pack(expand=True, fill=BOTH) gui = Tk() gui.title('Agente Viajero') F1 F2 F3 F4 = = = = Frame(gui); Frame(gui); Frame(gui); Frame(gui); F1.grid(row=0, F2.grid(row=0, F3.grid(row=1, F4.grid(row=0, column=0) column=1) column=0, columnspan=3) column=2) Cant_Ciudades = IntVar(value=5) Cant_Indv = IntVar(value=50) Porc_Corte = DoubleVar(value=0.1) Porc_Mutac = DoubleVar(value=0.01) Cant_Gen = IntVar(value=500) 9 L1 = Label(F1, text='Cantidad de Ciudades:'); L1.pack(pady=5) S1 = Spinbox(F1, from_=5, to=20, textvariable=Cant_Ciudades, state='readonly'); S1.pack(pady=5) L2 = Label(F1, text='Numero de Individuos por Generación:'); L2.pack(pady=5) S2 = Spinbox(F1, from_=10, to=100, increment=10, textvariable=Cant_Indv, state='readonly'); S2.pack(pady=5) L3 = Label(F1, text='Porcentaje de Corte Superior:'); L3.pack(pady=5) S3 = Spinbox(F1, from_=0.1, to=0.25, increment=0.01, textvariable=Porc_Corte, state='readonly'); S3.pack(pady=5) L4 = Label(F1, text='Porcentaje de Mutación:'); L4.pack(pady=5) S4 = Spinbox(F1, from_=0.01, to=0.10, increment=0.01, textvariable=Porc_Mutac, state='readonly'); S4.pack(pady=5) L5 = Label(F1, text='Numero de Generaciones:'); L5.pack(pady=5) S5 = Spinbox(F1, from_=100, to=2000, increment=100, textvariable=Cant_Gen, state='readonly'); S5.pack(pady=5) B1 = Button(F1, text='Generar', command=RunAlgorithm); B1.pack(padx=5, pady=10) SC1 = Scrollbar(F3, orient=VERTICAL); SC1.pack(side=RIGHT, fill=Y) T1 = Text(F3, width=100, height=10, yscrollcommand=SC1.set); T1.pack(fill=BOTH, expand=True); SC1.config( command = T1.yview ) gui.mainloop() 10 Imagen 01 - Captura Aplicativo Agente Viajero Fuente: Elaboración propia Imagen 02 - Captura Aplicativo Agente Viajero Fuente: Elaboración propia 11 Aplicativo Visión Artificial: ENUNCIADO: Buscamos desarrollar un aplicativo en el cual, cargando un archivo de imagen, nuestro programa colocará un borde verde sobre la amplitud de color que se ingresa mediante una amplitud haciendo uso del sistema de color HSV. Por limitaciones de la librería OPENCV, en lugar de ir del 0 al 359 (360 Grados), estos van desde 0 a 179 (180 Grados). Simplemente cualquier valor de la rueda cromatica deberá ser dividido 2 para poder ir al aplicativo desarrollado. Imagen 03 - Escala de Colores HSV Fuente: https://assets.clip-studio.com/en-us/detail?id=1911795 12 CÓDIGO EN PYTHON: import cv2 import numpy as np import tkinter as tk from tkinter import filedialog from PIL import Image, ImageTk def detect_color_object(): global original_image, result_image hue_min = int(hue_min_spinbox.get()) hue_max = int(hue_max_spinbox.get()) saturation_min = int(saturation_min_spinbox.get()) saturation_max = int(saturation_max_spinbox.get()) lower_color = np.array([hue_min, saturation_min, 0]) upper_color = np.array([hue_max, saturation_max, 255]) result_image = detect_color_in_image(original_image, lower_color, upper_color) original_image_resized = cv2.resize(original_image, (400, 400)) result_image_resized = cv2.resize(result_image, (400, 400)) update_images(original_image_resized, result_image_resized) def load_image(): global original_image, img_label file_path = filedialog.askopenfilename() if file_path: original_image = cv2.imread(file_path) update_images(original_image, np.zeros_like(original_image)) def update_images(original_img, result_img): global img_label, result_img_label original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB) original_img = Image.fromarray(original_img) original_img = ImageTk.PhotoImage(original_img) img_label.config(image=original_img) img_label.image = original_img result_img = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB) result_img = Image.fromarray(result_img) result_img = ImageTk.PhotoImage(result_img) result_img_label.config(image=result_img) result_img_label.image = result_img def detect_color_in_image(image, lower_color_range, upper_color_range): hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv_image, lower_color_range, upper_color_range) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 13 result_image = image.copy() for contour in contours: cv2.drawContours(result_image, [contour], -1, (0, 255, 0), 2) return result_image root = tk.Tk() root.title("Aplicativo de Vision Artificial") frame_widgets = tk.Frame(root) frame_widgets.grid(row=0, column=0, padx=10, pady=10, rowspan=3) load_button = tk.Button(frame_widgets, text="Cargar Imagen", command=load_image) load_button.pack(pady=10) hue_min_label = tk.Label(frame_widgets, text="Hue Mínimo:") hue_min_label.pack() hue_min_spinbox = tk.Spinbox(frame_widgets, from_=0, to=179) hue_min_spinbox.pack() saturation_min_label = tk.Label(frame_widgets, text="Saturación Mínima:") saturation_min_label.pack() saturation_min_spinbox = tk.Spinbox(frame_widgets, from_=0, to=255) saturation_min_spinbox.pack() hue_max_label = tk.Label(frame_widgets, text="Hue Máximo:") hue_max_label.pack() hue_max_spinbox = tk.Spinbox(frame_widgets, from_=0, to=179) hue_max_spinbox.pack() saturation_max_label = tk.Label(frame_widgets, text="Saturación Máxima:") saturation_max_label.pack() saturation_max_spinbox = tk.Spinbox(frame_widgets, from_=0, to=255) saturation_max_spinbox.pack() generate_button = tk.Button(frame_widgets, text="Generar Imágenes", command=detect_color_object) generate_button.pack(pady=10) frame_original_image = tk.Frame(root) frame_original_image.grid(row=0, column=1, padx=10, pady=10) img_label = tk.Label(frame_original_image) img_label.pack() frame_result_image = tk.Frame(root) frame_result_image.grid(row=0, column=2, padx=10, pady=10) result_img_label = tk.Label(frame_result_image) result_img_label.pack() original_image = np.zeros((400, 400, 3), dtype=np.uint8) result_image = np.zeros((400, 400, 3), dtype=np.uint8) 14 root.mainloop() Imagen 04 - Captura Aplicativo Visión Artificial Fuente: Elaboración propia Imagen 05 - Captura Aplicativo Visión Artificial Fuente: Elaboración propia 15 Imagen 06 - Captura Aplicativo Visión Artificial Fuente: Elaboración propia 16 CONCLUSIONES: Algoritmo Genético para el Problema del Viajante (TSP): El código implementa un algoritmo genético que resuelve el TSP, encontrando la ruta más corta para visitar ciudades una vez y regresar. Las ciudades se representan como objetos y se aplican operaciones genéticas como selección, cruce y mutación para evolucionar rutas. El código tiene una GUI que permite al usuario configurar parámetros como el número de ciudades e individuos. Tras presionar "Generar", el algoritmo evoluciona rutas y muestra el progreso y la mejor ruta en gráficos. Se utiliza matplotlib para mostrar el progreso del algoritmo y la mejor ruta en gráficos. La GUI brinda una ventana con información de progreso y parámetros. Interfaz Gráfica para Detección de Color: El código crea una interfaz gráfica en Python utilizando la biblioteca Tkinter para cargar imágenes y detectar objetos de diferentes colores. La detección se basa en valores HSV y los resultados se muestran en tiempo real. La aplicación incorpora un ComboBox que permite seleccionar colores del arcoíris. Al elegir un color, los valores de los Spinboxes se ajustan automáticamente para definir el rango de detección de ese color, simplificando el proceso para los usuarios. Las imágenes originales y las procesadas se redimensionan a 400x400 píxeles para una visualización conveniente en la interfaz gráfica. Esto proporciona una forma rápida y clara de observar los resultados de la detección de color. 17