APLICACIÓN DE UMBRALES EN IMÁGENES (‘THRESHOLDING’), CON PYTHON Y ‘scikit-image’.

La umbralizacion (o ‘thresholding‘) es una técnica usada en el procesamiento de imágenes digitales, mediante el cual se convierte una imagen (generalmente en escala de grises) de una matriz de pixeles con valores de intensidad comprendidos entre 0 y 256, a una imagen binaria (es decir, una imagen en la que los valores de intensidad sean únicamente 0 o 1. Por ejemplo, asignando el valor 0 a aquellos pixeles cuyo valor de intensidad quede por debajo del umbral establecido y 1 a aquellos que lo igualen o superen). Se trata de una técnica usada con frecuencia en procesos de segmentación de imágenes y de reconocimiento o detección de determinados elementos en las mismas, usándose para ello, un umbral que variará en función a la naturaleza misma de la imagen y del tipo de elemento que queramos aislar o separar de la misma.

A continuación se muestra un ejemplo en el que tenemos a la izquierda una imagen en escala de grises (en donde los valores de intensidad de cada pixel, varía entre 0 y 256) y a la derecha se muestra una imagen a la que se ha aplicado un umbral, resultando una imagen binaria en la que la variación de intensidades vienen representados únicamente por los valores 0 y 1:

PRIMEROS PASOS CON ‘scikit-image’:

Antes de continuar, vamos a ver algunas operaciones que podemos realizar con ‘scikit-image‘ y que nos van a ser de gran utilidad para nuestros ejercicios sobre aplicación de umbrales y segmentación. Sin olvidarnos de antes, instalar ‘scikit-image‘ en nuestro equipo:

Una vez instalada la librería, podremos empezar a experimentar con nuestras imágenes. Aunque para este tutorial, vamos a hacer uso de una serie de imágenes de ejemplo que vienen con la propia librería y a las que podemos acceder con el módulo ‘data‘:

A continuación, para mostrar la imagen obtenida, usaremos la librería ‘matplotlib‘ dentro de una función a la que llamaremos ‘show_image()‘ y que utilizaremos en lo sucesivo, mara mostrar las imágenes en nuestros ejemplos. Una vez definida, la usaremos para mostrar nuestra primera imagen de ejemplo:

OUTPUT:

Tal y como hemos señalado antes, el uso de umbrales se aplica generalmente sobre imágenes en escala de grises. Por ello, contamos en ‘scikit-image‘ con un módulo ‘color‘, que nos permitirá convertir una imagen a color, a otra a escala de grises:

OUTPUT:

‘THRESHOLDING’ CON ‘scikit-image’:

Una vez vistas las anteriores posibilidades que ofrece ‘scikit-image‘ es hora de realizar nuestra primera separación entre los elementos en primer plano y el fondo de nuestra imagen. Para este caso, utilizaremos otra imagen disponible en el módulo ‘data‘ que después mostramos utilizando nuestra función ‘show_image()‘:

OUTPUT:

A continuación, vamos a aplicar un umbral a la imagen, para luego, generar nuestra imagen binaria con la que pretendemos destacar los elementos en primer plano sobre el fondo. Para ello ‘scikit-image‘ nos proporciona una función ‘threshold_otsu‘ que nos devolverá el umbral óptimo para nuestro propósito, el cual, almacenaremos en la variable ‘thresh‘:

Vemos como la función aplicada sobre nuestra imagen nos devuelve un valor de 102. Esto significa que para separar del modo más apropiado posible, el fondo de los elementos en primer plano, se aplicará el umbral de modo que aquellos pixeles cuyo valor de intensidad quede por encima de dicho valor (o sea igual) se le dará un valor de 1 (blanco) en la imagen binaria resultante, y aquellos que queden por debajo de dicha cifra, se les aplicará el valor de 0 (negro). Pasemos pues a aplicar nuestro umbral sobre la imagen y mostrar el resultado:

OUTPUT:

Cojamos ahora otra imagen de nuestro muestrario y usemos nuevamente nuestra función ‘show_image()‘ para mostrarla en pantalla:

OUTPUT:

Acto seguido llevaremos a cabo todas las operaciones vistas en el caso anterior utilizando los mismos métodos y funciones. Proceso con el que finalmente obtendremos este resultado:

Se ve como en este caso obtenemos un resultado más pobre que el del caso anterior. La razón de esto radica en que el uso de la función ‘threshold_otsu‘ conviene realizarla sobre imágenes en las que exista una adecuada distinción o diferenciación entre los elementos en primer plano y el fondo. Caso que no se da en este segundo ejemplo al no ser lo suficientemente homogénea la intensidad del fondo. Para este tipo de caso, usaremos ‘threshold_local‘ al definir el umbral óptimo, definiendo para ello la variable ‘block_size‘ con la que especificaremos el número de pixeles contiguos a cada pixel de la imagen, que van a ser utilizados para el calculo de dicho umbral para el conjunto:

OUTPUT:

RECAPITULANDO:

En este artículo hemos visto en que consiste la aplicación de umbrales sobre imágenes y su utilidad para procesos de segmentación y detección de elementos en las mismas. También hemos visto (muy someramente) algunas funciones que ofrece la librería ‘scikit-image‘ para convertir imágenes en color a escala de grises, aplicar umbrales y obtención de umbral óptimo. Finalmente, hemos destacado la importancia de usar la función adecuada (‘threshold_otsu‘ o ‘threshold_local‘) para generar nuestra imagen binaria. Sin duda, se han quedado muchas cosas en el tintero, pero que iremos viendo en futuros artículos.

Saludos.

DETECTAR PULSACIONES DE TECLADO EN PYTHON, CON ‘pynput’.

Saludos, programadores y bienvenidos, una vez mas a vuestro blog sobre programación en Python, en una ocasión en la que, tal y como reza el título de esta entrada, vamos a ver, de forma sencilla, como podemos realizar la detección en tiempo real de las teclas de nuestro teclado, haciendo uso de la librería externa ‘pynput‘ que deberemos instalar previamente en nuestro equipo:

Una vez que tengamos instalado ‘pynput‘, podemos empezar a realizar nuestras pruebas. Esto lo haremos con un sencillo script al que llamaremos ‘keyboard_detector.py‘, que simplemente se encargará de detectar las teclas que pulsemos, mostrándolas en pantalla:

Como se ve, nuestro programa consta únicamente de dos funciones: La primera de ellas es ‘detect_k()‘ que tomará como argumento la tecla detectada y mostrará su nombre en formato string. La segunda es ‘release_k()‘ que tomando el mismo argumento mostrará el nombre de la tecla cuando esta sea soltada. A su vez, se encargará de finalizar el proceso de escucha, cuando la tecla que haya sido pulsada y soltada sea la ‘q‘ («if key == kb.KeyCode.from_char(‘q’):«).

Finalmente, tal y como se muestra en la imagen, iniciaremos el proceso de escucha, con ‘kb.Listener().run()‘ pasándole como argumentos las funciones de detección creadas y el orden en que deben ejecutarse:

OUTPUT:

A su vez, existe la posibilidad de que queramos ejecutar la escucha de teclado en un hilo diferente (por ejemplo cuando queremos realizar tal proceso, mientras se ejecuta un programa que haga uso de una interfaz gráfica). Para este caso introduciremos unas leves variaciones en nuestro código original, siendo la más relevante el empleo del método ‘.start()‘ en lugar del método ‘.run()‘ antes usado:

OUTPUT:

Y hasta aquí este primer acercamiento a la librería ‘pynput‘, la cual, naturalmente, ofrece muchas más posibilidades como puede ser, la detección de combinaciones de teclas, detección del ratón o el control del teclado y que iremos viendo en futuros artículos. Aunque, si lo desean, pueden echarle un vistazo a la documentación oficial en el siguiente enlace:

https://pynput.readthedocs.io/en/latest/

Saludos.

PROGRAMANDO BLOC DE NOTAS CON PYTHON Y TKINTER (EJERCICIO PRÁCTICO)

Quienes sigan este blog con cierta asiduidad, sabrán que en «El Programador Chapuzas» a menuda nos gusta realizar ejercicios prácticos en los que programamos alguna aplicación con nuestro lenguaje favorito. Pues bien, siguiendo con esa línea, hoy nos proponemos crear un sencillo bloc de notas ayudándonos de la librería para creación de interfaces gráficas, «Tkinter«.

Se trata de un sencillo ejemplo para el cual no necesitaremos instalar ningún recurso externo a las librerías nativas de Python. Con lo que simplemente bastará con importar las librerías y recursos que vayamos a utilizar:

PROGRAMANDO INTERFAZ GRÁFICA.

Como acostumbramos a hacer cuando creamos una aplicación de estas características, lo primero que haremos será crear nuestra interfaz gráfica de usuario. Proceso que iniciaremos definiendo la ventana en la que vamos a insertar los elementos de la misma:

OUTPUT:

Una ves que hemos creado la ventana de nuestra aplicación, definiendo sus dimensiones, color de fondo y título, es hora de empezar a añadir los diferentes elementos para interactuar con la aplicación. Empezando por una salida en la parte superior, que muestre el directorio en el que se está ejecutando nuestro programa. Para ello crearemos un elemento de entrada (con «Entry()«) en el que se mostrará el valor de una variable tipo «StringVar()» a la que hemos llamado «current_dir» que será igual al directorio de ejecución actual (que obtendremos con «os.getcwd()):

OUTPUT:

Debajo del elemento anterior, insertaremos 4 botones («Open«, «Save«, «Clear» y «Exit«) destinados a abrir un documento ya existente, guardar uno nuevo, borrar el contenido actual y salir, respectivamente. Para la creación de estos usaremos la función «Button()» (definiendo el texto de los mismos así como su posición) no sin antes crear un contenedor «Frame()» para albergar a dichos botones y que ubicaremos en la parte superior de la ventana con un guardando un margen horizontal de 10 y uno vertical de 5:

OUTPUT:

Finalmente crearemos el espacio para escribir texto junto a una barra de desplazamiento vertical que ubicaremos a su derecha. Esto lo haremos en 4 pasos: 1º- Creamos un espacio «Canvas()» en el que ubicaremos ambos elementos con margen horizontal de 10 y vertical de 5 indicando a su vez que queremos que rellene todo el espacio disponible. 2º- Crearemos la barra de scroll lateral, posicionándola en el lado derecho y usando la función «Scrollbar()«. 3º- Crearemos el espacio para escribir texto, mediante la función «Text()» definiendo un color de fondo, una fuente tipográfica así como su posición y 4º- Una vez creados el espacio para texto y la barra de desplazamiento lateral, usaremos «yscrollcommand» (para el espacio de entrada y «command» (para la barra de desplazamiento) para conectar ambos elementos, de modo que e el momento de llegar el texto al final, se active dicha barra.

OUTPUT:

Y con esto ya tendríamos elaborada la interfaz de nuestro bloc de notas. Ahora la siguiente fase será la de definir las funciones que harán que nuestro programa sea capaz de abrir archivos y guardar archivos nuevos, entre otras cosas.

PROGRAMANDO FUNCIONES.

Como ya hemos apuntado, ahora nos disponemos a definir las funciones que realizarán los botones que hemos creado, empezando por el primero de ellos «Open» que se encargará de abrir archivos de texto ya creados. Para este cometido, definiremos 2 funciones a las que llamaremos «openFile()» y «clearFile()«. Dichas funciones (al igual que las demás) las definiremos fuera del bloque que hemos utilizado para crear la interfaz:

Tenemos así una función «openFile()» que usará el método «askopenfile» para abrirnos un explorador de archivos, con el que podremos elegir el documento de texto que queramos abrir (cuta información se guardará en la variable «file») de modo que a continuación, el valor de este no es nulo (por no haber cerrado el explorador sin seleccionar) se procederá a la ejecución de la otra función «clearFile()» que borrará la información que pueda haber en el espacio de texto (usando el método «.delete()») en caso de que dicho espacio de texto no esté en blanco («if len(entry.get(‘1.0’,END))>1«). Finalmente se procederá a la lectura del archivo seleccionado almacenándose su información en la variable «content«, que a su vez se mostrará en el espacio de texto («entry.insert(INSERT, content)«). Finalmente para que esto pueda funcionar, tendremos que añadir el atributo «command» al botón correspondiente, indicando la función a ejecutar al presionar sobre el:

A su vez, ya que tenemos un botón «Clear» para borrar contenido del área de texto, agregaremos un «command» a este, que ejecute la función «clearFile()«:

Pasemos a programar la función a ejecutar al presionar el botón «Save«: Para ello definiremos una nueva función a la que llamaremos «saveFile()«:

Como sucedía en la función «openFile()«, en este caso, condicionaremos la ejecución del código a que haya algo escrito en el espacio para texto («if len(entry.get(‘1.0’,END))>1:«). En ese caso, utilizaremos «asksaveasfilename()» para abrir el explorador de archivos, pero en este caso para elegir el destino de nuestro nuevo archivo de texto (al que daremos el nombre por defecto de «my_text«, que el usuario podrá cambiar). Una vez elegido destino sin cerrar antes el explorador («if doc != «»«), utilizaremos las funciones «open()» para abrir en modo escritura el nuevo archivo («new_file = open(doc,»w»)«), «write()» para escribir en el la información que haya escrito en el área de texto («text = str(entry.get(‘1.0’, END))«) y «close()» para cerrar el archivo recién creado. Como antes, para que esto se ejecute, agregaremos el correspondiente «command» al botón «Save«:

Finalmente, definiremos una función «destroy_window()» que emplearemos para cerrar nuestro bloc de notas, con la peculiaridad de que, en caso que haya algo escrito en el espacio de texto, nos mostrará una ventana en la que se nos ofrecerá la posibilidad de guardar los cambios realizados (dicha ventana la generaremos usando el método «askquestion()» para luego usar la función «saveFile()» antes definida para guardar los cambios en un archivo) antes de cerrar la ventana con «.destroy()«:

Como en los casos anteriores añadiremos el «command» para el botón «Exit«, indicando la función a ejecutar:

OUTPUT:

Y con ello ya tendríamos hecho nuestro bloc de notas con Python y Tkinter. Un proyecto sencillo que nos ha ayudado a recordar y aplicar conceptos clave a la hora de programar aplicaciones gráficas en Python y cuyo código completo (al que se le ha añadido la posibilidad de copiar texto usando «threading» y «pyperclip«) podéis visitar en el siguiente enlace:

https://github.com/antonioam82/ejercicios-python/blob/master/notepad.py

Saludos.

CREACIÓN DE MARCOS («LABEL FRAMES») EN TKINTER.

Saludos y bienvenidos nuevamente a este sitio en el que tratamos los diferentes aspectos y funcionalidades relacionadas con la programación en lenguaje Python. En esta ocasión (tal y como reza el título) vamos a aprender a crear marcos (label frames) en Tkinter la cual (para quién no lo sepa) constituye una de las librerías más usadas en Python a la hora de crear interfaces gráficas que nos faciliten la interacción con nuestros programas.

Un marco consiste en un contenedor en el que, a su vez, podemos alojar otros widgets, y que nos sirve para organizar mejor el espacio en nuestra interfaz, agrupando dentro de un mismo marco, elementos o widgets que puedan estar más relacionados. La creación de estos en Tkinter es bien sencilla, simplemente hemos de utilizar la función «LabelFrame()» tal y como se muestra en este sencillo ejemplo:

OUTPUT:

Como se ve en el código, hemos empezado creando nuestra ventana («root«) en la que después hemos incluido nuestro contenedor empleando la función «LabelFrame()» y pasándole varios argumentos: El nombre de la ventana en la que vamos a insertarlo («root«), el texto que vamos a darle («Buscador«) y que aparecerá en la parte superior izquierda, el color de dicho texto (‘blue’) y los valores relativos a los márgenes que queramos que guarde con respecto a los elementos insertos en su interior («padx» y «pady«). Tras ello hemos procedido a insertar en dicho marco dos elementos: Uno de tipo entrada («Entry«) y un botón («Button«) los cuales hemos emplazado usando el método «.grid«. Nótese aquí que para que estos dos elementos se integren dentro de nuestro marco, debemos indicar el nombre que hemos dado al marco («buscador«) como primer argumento a introducir al usar las respectivas funciones «Entry» y «Button«.

Como hemos dicho, podemos usar los valores «padx» y «pady«, dentro de la función «LabelFrame()» para cambiar las dimensiones de la misma respecto de la los elementos que tenga dentro. Así, en nuestro ejemplo, si reducimos su valor a la mitad, veremos como nuestro marco se encoje:

OUTPUT:

Un efecto similar obtendremos, esta vez respecto de la ventana principal, cambiando los referidos valores dentro del método «.grid()«:

OUTPUT:

Y con esto ya tenemos las bases para empezar a trabajar con marcos en nuestras interfaces gráficas, lo que nos permitirá crear diseños más ordenados y de aspecto más profesional.

Saludos.

TRABAJANDO CON EXPRESIONES ALGEBRAICAS EN PYTHON, USANDO «sympy».

Bienvenidos sean una vez más a vuestro blog sobre programación en Python, en una ocasión en las que nos disponemos a dar nuestro primeros pasos en el manejo de la librería «sympy«, la cual, nos permitirá trabajar matemáticas de forma simbólica, permitiendo realizar acciones tales como la resolución de sistemas de ecuaciones, factorización, desarrollo de expresiones algebraicas, resolución de derivadas, de integrales, manejo de vectores y matrices, entre otras cosas. En esta ocasión nos centraremos en la manipulación de expresiones algebraicas. Pero antes de empezar, debemos instalar «sympy» en nuestro equipo:

DEFINIENDO SIMBOLOS.

Tal y como hemos señalado, «sympy» es un módulo especializado en el manejo de matemáticas simbólicas. Con lo cual, antes de definir una expresión algebraica, deberemos definir previamente los símbolos que vamos a usar en nuestras expresiones. Dicha definición la realizaremos asignando dicho símbolo a una variable, usando la función «Symbol()«:

Una vez que tenemos definidas las variables, podemos hacer uso de ellas incluyéndolas en nuestras expresiones algebraicas, las cuales podremos asignar a variables para después operar con ellas:

FACTORIZACIÓN Y EXPANSIÓN.

También podemos efectuar ciertas operaciones sobre nuestras expresiones como son la factorización y expansión de las mismas:

Definida la expresión y asociada a una variable, podemos usar las funciones «factor()» y «expand()» para efectuar las tres operaciones mencionadas:

SIMPLIFICACIÓN.

Otra de las acciones que podemos realizar sobre una expresión es la de simplificación de la misma. Para ello usaremos la función «simplify()» a la que pasaremos la expresión que vamos a simplificar. En los ejemplos anteriores hemos asociado previamente la expresión a una variable, pero también podemos introducir directamente dicha expresión en las funciones (nótese que aquí incorporamos el símbolo «y» sin problemas ya que lo definimos anteriormente mediante la función «Symbol()«):

SUSTITUCIÓN.

También podemos efectuar la sustitución de símbolos por valores. Así, partiendo de una expresión que incluye los símbolos «x«, «y» y «z» (ya definidos anteriormente) podemos asignar un valor a cada uno mediante el método «subs()» que aplicaremos a la variable en la que hayamos almacenado la expresión. Lo que finalmente nos devolverá el resultado de la operación tras la asignación de valores:

Como se ve, hemos usado el método «subs()» al que hemos pasado una lista de tuplas compuestas por el símbolo al que queremos asignar un valor y el valor mismo.

RESOLUCIÓN DE ECUACIONES.

Aunque hablaremos más detalladamente de ello en futuros artículos, «sympy» nos permite también resolver ecuaciones de modo muy sencillo. Para ello utilizaremos la función «solve()» a la que pasaremos nuestra función el valor con respecto al cual queremos efectuar el calculo:

A su vez, también podemos utilizar «solve()» para despejar una variable.

CONSIDERACIONES FINALES.

En este artículo hemos visto una serie de operaciones elementales que podemos realizar sobre expresiones algebraicas. Aunque con «sympy» podemos hacer muchas otras cosas como son la resolución de sistemas de ecuaciones, ecuaciones diferenciales, calculo de derivadas, operaciones con matrices y vectores…etc. Aspectos tales que nos hemos dejado en este breve esbozo de las posibilidades de calculo que ofrece «sympy» pero que iremos viendo en detalle en futuras entradas del blog.

Saludos.

CREANDO TEXTO EN CARACTERES ASCII, CON «PYFIGLET».

Es sabido que cuando programamos una aplicación de consola, no podemos llevar a cabo personalizaciones de la apariencia de esta, tal y como si hacemos cuando trabajamos con interfaces gráficas. No obstante podemos darle algún toque personal, recurriendo a recursos como puede ser el color del texto (lo que ya hemos abordado en alguna ocasión en la que hemos hablado de la librería «colorama«) o la inclusión de fuentes en «ascii» para nuestras presentaciones. Para esto último tenemos una curiosa librería llamada «pyfiglet» que nos facilitará grandemente el trabajo.

Con ‘pyfiglet’ podemos crear textos en ascii que nos permitirán personalizar nuestras aplicaciones de consola.

Para empezar a trabajar con esta librería, lo primero que deberemos hacer (si no lo hemos hecho ya) es instalarla en nuestro equipo:

Hecho esto, ya estamos en condiciones de empezar. Empezaremos mostrando mostrando el mensaje «hello world!» en el estilo de fuente predeterminado:

Para ello, hemos usado el método «figlet_format()» al que en este caso solo hemos pasado como argumento, el texto a representar. Mostrándose este en la fuente ‘standard’ (la que viene establecida por defecto). No obstante, podemos elegir otra de las muchas fuentes y estilos disponibles, añadiendo un segundo argumento «font«. Así quedaría nuestro texto usando la fuente «speed«:

Como se ve, cada vez que usemos el método «figlet_format()«, nuestro texto se mostrará por defecto alineado a la izquierda. Sin embargo, podemos usar un nuevo argumento «justify» para especificar si lo queremos alineado a la izquierda, centrado o derecha (siempre que la longitud del mismo lo permita):

Un cuarto argumento que podemos incluir es «width» con el cual, especificaremos el espacio que vamos a necesitar para nuestro ejemplo. Así, pongamos que queremos mostrar «hello world» en fuente llamada «isometric3«:

Vemos como, dado tanto el tipo de fuente como la longitud del texto, este ha de mostrarse en dos líneas. Es aquí donde el valor «width» nos permite ampliar el espacio para nuestro texto, de modo que este pueda mostrarse entero en una sola línea:

Pyfiglet, cuenta con un gran número de fuentes a cuyos nombres podemos acceder a través del método «getFonts()«:

Lo que mostrará en pantalla la lista con los nombres de todas las fuentes que podemos utilizar:

Finalmente, recordar que podemos usar esta librería conjuntamente con otras herramientas como «colorama» (de la que ya hemos hablado) para personalizar y darle un toque más atractivo a nuestras aplicaciones de consola:

Y hasta aquí este breve artículo en el que hemos visto el modo en que podemos dar un toque más personal y llamativo a nuestras aplicaciones de consola mediante esta curiosa e interesante librería.

Saludos.

PROGRAMACIÓN CON SOCKETS EN PYTHON I: ESTABLECIENDO CONEXIÓN CLIENTE-SERVIDOR.

Bienvenidos nuevamente a este blog sobre programación en lenguaje Python. En esta ocasión os traemos un primer artículo acerca de la programación en Python usando sockets. Concretamente, lo que haremos será establecer una primera comunicación en la que un servidor recibirá una petición de conexión por parte de un cliente, y una vez establecida esta, devolverá una información a este último.

QUÉ SON LOS SOCKETS.

Para empezar, diremos que la programación con sockets, lo que pretende es el establecimiento de una conexión o comunicación de red (clienteservidor) entre dos nodos en los cuales vamos a tener código de Python en ejecución. Dicha conexión la estableceremos a partir de una dirección de red que determinará el destino y origen de la comunicación, y un puerto que definirá el medio o camino por el que se va a trasmitir dicha información.

En el transcurso de dicho proceso de conexión, tanto en el lado del servidor como en el del cliente, van a ejecutarse una serie de métodos cuyo flujo y relaciones, pueden contemplarse en el siguiente diagrama:

Tenemos aquí un servidor que empieza creando una puerta de entrada-salida de información a través de una dirección IP y un puerto que asociará con esta mediante el método «bind()«. Una vez creada dicha asociación pondrá el socket en modo escucha a través del método «listen()«, dejando el socket, mediante «accept()» a la espera de recibir alguna solicitud de conexión por parte del cliente, el cual, tras haber igualmente creado su correspondiente socket a partir de una IP y un puerto, realizará dicha solicitud al servidor, usando el método «connect()«. Una vez aceptada dicha solicitud por el servidor, ambos entrarán en una fase en la que podrán mutuamente, recibir y mandarse información, usando los métodos «recv()» y «send()» respectivamente.

CODIFICACIÓN EN PYTHON.

Visto someramente el modo en que se establece la conexión clienteservidor, es hora de hacer nuestra simulación de conexión en Python. Para lo cual, crearemos dos archivos «server.py» y «client.py» que ejecutarán las acciones vistas anteriormente tanto de un lado como del otro.

Lo que haremos ahora, es crear un servidor que pondremos a la espera de recibir una solicitud de conexión por parte de un cliente. De modo que cuando esta se produzca, mostrará un mensaje de conexión establecida recibiendo una información de dicho cliente, que después devolverá a este. Para ello, como ya hemos dicho, crearemos dos scripts que simularán a ambas partes de la conexión, empezando por el servidor:

«server.py»

Como se ve, empezamos importando el módulo «socket» para poder trabajar con estas conexiones, tras lo cual, pasaremos a definir la dirección en la que se ejecuta nuestro servidor. Puesto que el servidor se va a ejecutar en nuestro equipo, usaremos el host 127.0.0.1 que es el correspondiente al host local (la misma auto referencia conseguiremos introduciendo «localhost» en su lugar). Acto seguido definiremos el puerto a través del cual se producirá dicha conexión. Definidos tales parámetros, (y con estos) pasamos a iniciar el socket, asociando dicha información al mismo usando el método «bind()» para a continuación, empleando el método «listen()«, ponerlo en modo escucha, a la espera de posibles solicitudes de conexión entrantes, que captaremos con el método «accept()» el cual nos devolverá dos valores: la conexión entrante (que guardaremos en la variable «conn«) y la dirección IP de procedencia (que se guardará en la variable «addr«). Una vez establecida la conexión, usaremos el método «recv()» (en el que especificaremos la cantidad, en bytes, de información, que podrá recibir el servidor) para obtener la información del cliente, la cual a continuación devolveremos a este, usando esta vez, el método «sendall()«.

Visto, el código de nuestro servidor, pasemos ahora a ver el del cliente, que como cabe de esperar viendo el diagrama expuesto más arriba, tiene una codificación más simple:

«client.py»

En este caso, después de la pertinente importación del módulo «socket«, pasamos a definir la dirección IP de destino, la cual, (dado el hecho que en este caso, tanto el servidor como el cliente se ejecutan en la misma máquina) será la misma que en el caso anterior. A su vez, por razones obvias, el puerto (que es el canal de comunicación entre ambas partes) también será el mismo. Una vez que tenemos definida la conexión, abrimos el socket ejecutando el método «connect()» que enviará una solicitud de conexión al servidor, quedando mientras a la espera de ser aceptada por este. Una vez que se consiga la conexión, con el método «sendall()» mandaremos un mensaje a dicho servidor, el cual, a su vez, se lo devolverá al cliente, recibiéndolo este mediante el método «recv()» para mostrarlo nuevamente en su terminal.

EJECUTANDO PRUEBA.

Una vez que tenemos escritos nuestros scripts, pasaremos a ejecutarlos. Para ello, deberemos abrir dos terminales de nuestro CMD, de modo que en uno de ellos ejecutaremos el archivo «server.py«:

Servidor a la espera de conexiones entrantes.

Hecho esto, veremos como nuestro servidor, quedará a la espera de recibir alguna solicitud de conexión. Dicha solicitud la efectuaremos ejecutando «client.py» en el otro terminal que tendremos abierto:

El terminal del cliente muestra el mensaje enviado de vuelta por el servidor.

Vemos como al ejecutar nuestro cliente este recibe por parte del servidor el mensaje que le hemos mandado y que este ha recibido, después de mostrar el mensaje de conexión establecida:

Al recibir conexión entrante, el servidor muestra la dirección del cliente con el que ha conectado.

Y hasta aquí este sencillo ejercicio en el que hemos procedido a establecer nuestra primera conexión clienteservidor realizando nuestra primera transferencia de datos entre ambos usando sockets con Python. En este caso, solo hemos transmitido un sencillo texto en formato bytes, pero en futuras entregas realizaremos operaciones más interesantes como puede ser la transferencia de archivos entre ambos. De todos modos este es un buen comienzo a partir del cual podremos empezar a realizar nuestras propias pruebas y experimentos para proyectos más ambiciosos.

En los siguientes enlaces tenéis el acceso al código tanto del archivo «server.py» como al de «client.py«:

https://github.com/antonioam82/ejercicios-python/blob/master/server.py

https://github.com/antonioam82/ejercicios-python/blob/master/client.py

DETECCIÓN Y DIFUMINADO DE ROSTROS EN IMÁGENES EN PYTHON.

Hace ya algún tiempo, estuvimos viendo la manera en la que podemos realizar la detección de rostros humanos en una imagen usando la librería «OpenCv«. Hoy, a aquella practica vamos a añadir la técnica de difuminado de dichos rostros, usando igualmente, la citada librería Esta operación la realizaremos tanto a partir de una foto de prueba, como a partir de la entrada por cámara.

DETECCIÓN Y DIFUMINADO DE ROSTROS EN FOTOGRAFÍAS.

En este primer ejercicio realizaremos la detección y difuminado de un rostro en una imagen de prueba:

Imagen original.

Tal y como hicimos en su momento, empezaremos efectuando la detección del rostro de nuestra imagen usando la librería «OpenCV» y el modelo creado a tal efecto, definido en el archivo «haarcascade_frontalface_default.xml«. Así, comenzaremos cargando nuestra imagen de prueba y creando nuestro detector con dicho modelo:

Una vez cargada la imagen y el modelo que vamos a usar, pasaremos a aplicar este sobre nuestra imagen para a continuación dibujar el área de detección, para finalmente mostrar el resultado mediante el método «imshow()«:

OUTPUT:

Detección de rostro.

Con esto ya tenemos la detección realizada correctamente. Una vez que tenemos delimitada el área, solo nos resta aplicar el efecto de difuminado sobre la misma. Para ello, empezaremos delimitando el área sobre el que vamos a aplicar el efecto (que coincidirá con la del rectángulo dibujado) para finalmente aplicarle el filtro correspondiente. Así reescribiremos el bloque de código anterior para poder aplicar el filtro:

OUTPUT:

Aplicación de difuminado sobre área deseada.

DIFUMINADO DE ROSTRO A PARTIR DE ENTRADA POR CÁMARA.

El procedimiento para la detección de rostros en una entrada por cámara es, en líneas generales, bastante similar (en cuanto a los pasos a dar) al que veíamos en el caso anterior. Solo que en este caso, en lugar de usar «OpenCv» para abrir una imagen, lo vamos a usar para mostrar la entrada recogida por la cámara de nuestro dispositivo, utilizando el método «videoCapture()«. Así, empezaremos iniciando la cámara de nuestro dispositivo y cargando el modelo para detección de rostros del mismo modo que en el ejemplo anterior:

En el bloque siguiente pasaremos a manipular la secuencia de fotogramas que componen la salida de video por cámara al tiempo que en cada uno, procedemos a usar nuestro modelo de detección, para dibujar el área correspondiente:

Por su parte, para aplicar el efecto de difuminado sobre el rostro, simplemente tendremos (tal y como hicimos en el ejemplo anterior) que encontrar el área detectada y usar el método «medianBlur()» para lograr el efecto. Para ello introduciremos los cambios pertinentes en el bloque de código anterior:

OUTPUT:

En los siguientes enlaces tenéis el código completo de ambos ejemplos para que lo probéis vosotros mismos:

PRIMER EJEMPLO:

https://github.com/antonioam82/ejercicios-python/blob/master/blurring_faces_images.py

SEGUNDO EJEMPLO:

https://github.com/antonioam82/ejercicios-python/blob/master/blurring_faces_video.py

A su vez, en el siguiente enlace podéis obtener el modelo usado para la detección de rostros en imágenes:

https://github.com/antonioam82/FaceDetect

Saludos.

MOSTRAR FECHA DE CREACIÓN Y MODIFICACIÓN DE UN ARCHIVO, EN PYTHON.

Saludos programadores, hoy os vamos a mostrar un sencillo modo de obtener la fecha de creación y modificación de un archivo en Python, usando solamente los módulos ‘os‘ y ‘time‘, y empleando los métodos ‘getctime()‘ y ‘getmtime()‘ del módulo ‘path‘ del sistema operativo, que nos devolverá en segundos, el tiempo de creación y modificación respectivamente, del archivo cuya ruta hemos especificado en la variable ‘path‘:

El inconveniente aquí es que el resultado en segundos es posible que no nos diga nada. Por lo que resulta conveniente traducir el resultado obtenido a un formato de fecha que sea fácil de leer. Para ello, podemos usar el método ‘ctime()‘ del módulo ‘time‘, tal y como se muestra a continuación:

Así, usando el método ‘ctime()‘ y pasándole la información obtenida previamente, obtenemos tanto la fecha de creación, como la de modificación en un formato de fecha, bastante mas comprensible por nosotros, mostrándose tanto la fecha como la hora.

No obstante, es posible que a su vez queramos modificar el orden o modo en que se estructura la información de fecha y hora. Para ello, usaríamos en primer lugar, ‘strptime()‘ para crear el objeto tiempo al que después daremos formato mediante el método ‘strftime()‘. Así, para mostrar el resultado en formato día, mes, año y hora, escribiremos lo siguiente:

Y con esto tendríamos visto el modo en que podemos usar Python para obtener tanto la fecha de creación de un archivo, así como la fecha de su última modificación.

Saludos.

MOSTRANDO GRÁFICAS EN EL TERMINAL EN PYTHON, CON ‘PLOTEXT’.

Bienvenidos una vez más a este blog sobre programación en lenguaje Python, en un día en el que os mostraremos una interesante librería, ‘Plotext‘, que nos permitirá mostrar graficas directamente en el terminal, usando una sintaxis muy parecida a la de librerías como «matplotlib«. Así que pasemos a ver unos sencillos ejemplos, no sin antes realizar la pertinente instalación de dicha librería en nuestro equipo:

Una vez instalada nuestra librería, pasemos a nuestro primer ejemplo, consistente en la representación de una sencilla señal sinusoidal (para la que usaremos el método «.sin()«, tal y como se muestra a continuación:

Guardando el script como «sinpy.py» pasaremos a ejecutarlo en nuestra terminal de Python:

También podemos escoger el tipo de escala, que puede ser lineal (la opción por defecto) o logarítmica, lo que especificaremos mediante los métodos «yscale()» (para el eje ‘y’) y «xscale()» (para el ‘x’):

OUTPUT:

También podemos representar gráficos con múltiples variables. Aquí se muestra la función anterior junto a su inversa:

OUTPUT:

Por otra parte, si lo queremos podemos incluir animaciones en nuestras presentaciones como en el siguiente ejemplo:

OUTPUT:

Además, ‘plottext‘ incluye también métodos y funciones útiles para el análisis financiero. De modo que podemos mostrar en nuestro terminal, series temporales. En este ejemplo mostramos la serie temporal de precios de una conocida compañía, usando también la librería «yfinance» de la que también hemos hablado en alguna ocasión:

OUTPUT:

Como última muestra, también podemos usar el método «image_plot()» para mostrar fotografías en nuestra terminal:

OUTPUT:

Con estos sencillos ejemplos, esperamos haberos proporcionado una visión general acerca de las posibilidades que ofrece ‘plotext‘ a la hora de mostrar elementos gráficos directamente en el terminal, y cuya documentación os invitamos a leer más en profundidad en su página de github:

https://github.com/piccolomo/plotext

Saludos.