{"id":50,"date":"2025-02-19T19:06:40","date_gmt":"2025-02-19T19:06:40","guid":{"rendered":"https:\/\/e-icus.net\/blog\/?p=50"},"modified":"2025-02-19T21:17:53","modified_gmt":"2025-02-19T21:17:53","slug":"50","status":"publish","type":"post","link":"https:\/\/e-icus.net\/blog\/2025\/02\/19\/50\/","title":{"rendered":"Creando una app de reconocimiento de patrones con Tkinter y TensorFlow"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"992\" src=\"https:\/\/e-icus.net\/blog\/wp-content\/uploads\/2025\/02\/image-1-1024x992.png\" alt=\"\" class=\"wp-image-58\" srcset=\"https:\/\/e-icus.net\/blog\/wp-content\/uploads\/2025\/02\/image-1-1024x992.png 1024w, https:\/\/e-icus.net\/blog\/wp-content\/uploads\/2025\/02\/image-1-300x291.png 300w, https:\/\/e-icus.net\/blog\/wp-content\/uploads\/2025\/02\/image-1-768x744.png 768w, https:\/\/e-icus.net\/blog\/wp-content\/uploads\/2025\/02\/image-1.png 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>La inteligencia artificial (IA) es una disciplina que permite a las computadoras aprender y tomar decisiones basadas en datos. Utilizando modelos de aprendizaje autom\u00e1tico, es posible entrenar algoritmos para reconocer patrones y hacer predicciones. En esta breve entrada, se muestra c\u00f3mo desarrollar una aplicaci\u00f3n en Python que permita el reconocimiento de patrones, para este caso, reconocer los n\u00fameros del 0 &#8211; 9  utilizando una red neuronal entrenada con TensorFlow. y para la interfaz gr\u00e1fica, Tkinter, en python.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Librerias<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tkinter<\/strong>: Para la interfaz gr\u00e1fica.<\/li>\n\n\n\n<li><strong>NumPy<\/strong>: Para manejar la matriz de datos.<\/li>\n\n\n\n<li><strong>TensorFlow\/Keras<\/strong>: Para cargar y utilizar un modelo de reconocimiento de patrones.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Carga del Modelo de Reconocimiento<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.utils import to_categorical\n\n# Ejemplos simples para 0 al 9\ndigits = {\n    0: &#91;\n        &#91;0,1,1,0],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;0,1,1,0]\n    ],\n    1: &#91;\n        &#91;0,0,1,0],\n        &#91;0,1,1,0],\n        &#91;0,0,1,0],\n        &#91;0,0,1,0],\n        &#91;0,0,1,0],\n        &#91;0,1,1,1]\n    ],\n    2: &#91;\n        &#91;0,1,1,0],\n        &#91;1,0,0,1],\n        &#91;0,0,1,0],\n        &#91;0,1,0,0],\n        &#91;1,0,0,0],\n        &#91;1,1,1,1]\n    ],\n    3: &#91;\n        &#91;1,1,1,0],\n        &#91;0,0,0,1],\n        &#91;0,1,1,0],\n        &#91;0,0,0,1],\n        &#91;0,0,0,1],\n        &#91;1,1,1,0]\n    ],\n    4: &#91;\n        &#91;0,0,1,0],\n        &#91;0,1,1,0],\n        &#91;1,0,1,0],\n        &#91;1,1,1,1],\n        &#91;0,0,1,0],\n        &#91;0,0,1,0]\n    ],\n    5: &#91;\n        &#91;1,1,1,1],\n        &#91;1,0,0,0],\n        &#91;1,1,1,0],\n        &#91;0,0,0,1],\n        &#91;1,0,0,1],\n        &#91;0,1,1,0]\n    ],\n    6: &#91;\n        &#91;0,1,1,0],\n        &#91;1,0,0,0],\n        &#91;1,1,1,0],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;0,1,1,0]\n    ],\n    7: &#91;\n        &#91;1,1,1,1],\n        &#91;0,0,0,1],\n        &#91;0,0,1,0],\n        &#91;0,1,0,0],\n        &#91;1,0,0,0],\n        &#91;1,0,0,0]\n    ],\n    8: &#91;\n        &#91;0,1,1,0],\n        &#91;1,0,0,1],\n        &#91;0,1,1,0],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;0,1,1,0]\n    ],\n    9: &#91;\n        &#91;0,1,1,0],\n        &#91;1,0,0,1],\n        &#91;1,0,0,1],\n        &#91;0,1,1,1],\n        &#91;0,0,0,1],\n        &#91;0,1,1,0]\n    ]\n}\n\n# Preparaci\u00f3n de los datos\nX = np.array(&#91;np.array(digits&#91;d]).flatten() for d in digits])  # Convertir a vectores de 24 elementos\ny = np.array(list(digits.keys()))\n\n# Codificaci\u00f3n one-hot para las etiquetas\ny_categorical = to_categorical(y, num_classes=10)\n\n# Definir el modelo de red neuronal\nmodel = Sequential(&#91;\n    Dense(32, activation='relu', input_shape=(24,)),\n    Dense(16, activation='relu'),\n    Dense(10, activation='softmax')  # 10 clases (0 al 9)\n])\n\n# Compilar el modelo\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=&#91;'accuracy'])\n\n# Entrenar el modelo\nmodel.fit(X, y_categorical, epochs=1000, verbose=1)\n\n# Guardar el modelo entrenado\nmodel.save(\"modeloReconocimiento0-9.keras\")\n\nprint(\"Modelo guardado exitosamente como 'modelo_numeros.keras\")\n<\/code><\/pre>\n\n\n\n<p>El primer paso es cargar el modelo previamente entrenado. En este caso, el modelo debe haber sido guardado en un archivo <code>modelo0-9.keras<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import tensorflow as tf\nimport numpy as np\nimport tkinter as tk\n\n# Cargar el modelo\ntry:\n    model = tf.keras.models.load_model('modelo0-9.keras')  \nexcept:\n    print(\" No se encontr\u00f3 el archivo 'modelo0-9.keras'. Aseg\u00farate de entrenar y guardar el modelo.\")\n    exit()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Creaci\u00f3n de la Interfaz Gr\u00e1fica con Tkinter<\/h3>\n\n\n\n<p>La interfaz se basa en un lienzo donde el usuario puede dibujar un patr\u00f3n de 6&#215;4 celdas. Cada celda puede activarse o desactivarse haciendo clic en ella.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Dimensiones de la matriz\nROWS = 6\nCOLS = 4\nCELL_SIZE = 50  \n\nmatrix = np.zeros((ROWS, COLS), dtype=int)\n\nroot = tk.Tk()\nroot.title(\"Reconocimiento de Patrones (Canvas)\")\nroot.configure(bg=\"white\")\n\ncanvas = tk.Canvas(root, width=COLS * CELL_SIZE, height=ROWS * CELL_SIZE, bg=\"white\")\ncanvas.grid(row=0, column=0, columnspan=4, padx=10, pady=10)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Funcionalidad de Dibujo<\/h3>\n\n\n\n<p>Cada clic del usuario alterna el estado de la celda, cambiando su color de blanco a negro y viceversa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rectangles = {}\n\ndef toggle_cell(event):\n    col = event.x \/\/ CELL_SIZE\n    row = event.y \/\/ CELL_SIZE  \n    if 0 &lt;= row &lt; ROWS and 0 &lt;= col &lt; COLS:\n        matrix&#91;row, col] = 1 if matrix&#91;row, col] == 0 else 0\n        color = \"black\" if matrix&#91;row, col] == 1 else \"white\"\n        canvas.itemconfig(rectangles&#91;(row, col)], fill=color)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Creaci\u00f3n de la Cuadr\u00edcula<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>for r in range(ROWS):\n    for c in range(COLS):\n        x1, y1 = c * CELL_SIZE, r * CELL_SIZE\n        x2, y2 = x1 + CELL_SIZE, y1 + CELL_SIZE\n        rect = canvas.create_rectangle(x1, y1, x2, y2, fill=\"white\", outline=\"gray\")\n        rectangles&#91;(r, c)] = rect\n\ncanvas.bind(\"&lt;Button-1&gt;\", toggle_cell)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Reconocimiento del Patr\u00f3n<\/h3>\n\n\n\n<p>Al presionar el bot\u00f3n \u00abReconocer\u00bb, la matriz se procesa y se pasa al modelo para obtener una predicci\u00f3n.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def recognize_number():\n    flattened_matrix = matrix.flatten().reshape(1, -1)\n    prediction = model.predict(flattened_matrix)\n    result_label.config(text=f\"N\u00famero reconocido: {np.argmax(prediction)}\")<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Reinicio del Dibujo<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>def reset_matrix():\n    global matrix\n    matrix = np.zeros((ROWS, COLS), dtype=int)\n    for (r, c), rect in rectangles.items():\n        canvas.itemconfig(rect, fill=\"white\")  <\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Botones de Interacci\u00f3n<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>recognize_btn = tk.Button(root, text=\"Reconocer\", command=recognize_number, font=(\"Arial\", 12), bg=\"lightblue\")\nrecognize_btn.grid(row=1, column=0, columnspan=2, pady=10)\n\nreset_btn = tk.Button(root, text=\"Reiniciar\", command=reset_matrix, font=(\"Arial\", 12), bg=\"lightblue\", fg=\"black\")\nreset_btn.grid(row=1, column=2, columnspan=2, pady=10)\n\nresult_label = tk.Label(root, text=\"Dibuja un n\u00famero y presiona 'Reconocer'\", font=(\"Arial\", 12), bg=\"white\")\nresult_label.grid(row=2, column=0, columnspan=4)<\/code><\/pre>\n\n\n\n<p>Finalmente, iniciamos el bucle de Tkinter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root.mainloop()<\/code><\/pre>\n\n\n\n<p>Esta aplicaci\u00f3n es un ejemplo pr\u00e1ctico de c\u00f3mo integrar modelos de inteligencia artificial en interfaces gr\u00e1ficas de usuario. Puedes mejorarla entrenando modelos m\u00e1s precisos o ampliando la resoluci\u00f3n de la cuadr\u00edcula para mejorar la precisi\u00f3n en el reconocimiento.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La inteligencia artificial (IA) es una disciplina que permite a las computadoras aprender y tomar decisiones basadas en datos. Utilizando modelos de aprendizaje autom\u00e1tico, es posible entrenar algoritmos para reconocer patrones y hacer predicciones. En esta breve entrada, se muestra c\u00f3mo desarrollar una aplicaci\u00f3n en Python que permita el reconocimiento de patrones, para este caso,&hellip; <a class=\"more-link\" href=\"https:\/\/e-icus.net\/blog\/2025\/02\/19\/50\/\">Seguir leyendo <span class=\"screen-reader-text\">Creando una app de reconocimiento de patrones con Tkinter y TensorFlow<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,5,6,8],"tags":[],"class_list":["post-50","post","type-post","status-publish","format-standard","hentry","category-ia","category-programacion","category-python","category-tensorflow","entry"],"_links":{"self":[{"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":6,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":61,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/posts\/50\/revisions\/61"}],"wp:attachment":[{"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/e-icus.net\/blog\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}