/** **/

ITCooky Recetas

Vamos a cocinar it cositas

¡Bot de Telegram que aumenta y mejora fotos con la red neuronal GFPGAN en una tarjeta de video con CUDA!

дата junio 19, 2022

La idea inicial era esta: el bot de Telegram guarda todas las imágenes que le mandan, luego, cada dos minutos, comienza el procesamiento de las imágenes en la carpeta y el resultado se envía a todos. El nombre del destinatario estará en el nombre del archivo… todo parece ser simple, pero resultó ser muy difícil de hacer: debe profundizar en la asincronía y, en general… Entonces todo será simple y lineal, recibe una foto, va a procesarla de inmediato y ¡que los demas esperen! Y esta vez lo hare en Python, no en vano escuché (y bueno, hice toda las tareas) un curso gratisCS50’s Introduction to Programming with Python, y la vez anterior (hace 4 años ¡Mamma Mia!) todo estaba hecho en node.js Casa inteligente con TelegramBot en Node.js!

Karan Batra me ayudará a lanzar el bot Part 1: How to create a Telegram Bot in Python in under 10 minutes

Hardware
Tengo un coloso con pies de barro. Una tarjeta grafica, que auna esta buena para juegos, GIGABYTE GeForce RTX 2070 MINI ITX 8 Gb y motherboard ASRock J3355M con CPU integrado Intel® Celeron® J3355 que «no cuesta ni el cooler» de la tarjeta grafica! Bueno, y 4Gb de memoria… ¡pero no importa porque la tarjeta de video hara todos los calculos! ¡Y la prueba Geekbench5 CUDA lo confirma, dando el mismo 99000 que en el Ryzen 7 3700x!

Por cierto, la fuente de alimentación sin nombre de 350W no arranco con la tarjeta de video, instalé Zalman 600W

Y también noto que en todas los PC, antes de iniciar tareas para CUDA (ya sea DeeFaceLab o GFPGAN), parece congelarse por un minuto, se inicializa tal vez y luego todo funciona rápidamente una foto tras otra…

Creamos telegram bot’а
Creamos un bot a través de botfather, ¡para esto necesitas estar en Telegram! Haciendo como aquí core.telegram.org/bots#6-botfather

Y lo hago a través de la versión web, porque tendré que copiar el token. Empezando con
/newbot

Damos un nombre para bot, otro nombre corto y nos dan un token

Primer ararnque del bot de Telegram en Python
Python ya esta instalado o no, lo comprobaré
python -V

Python 3.9.10

Por supuesto ya esta instalado ¡ahora Python está en todas partes! Aunque, en algunos aspectos, es un idioma muy extraño: lo más extraño para mí es formatear con espacios, los espacios son cosas vacías invisibles para el ojo humano, y si pones 3 en lugar de 4, entonces ¡para de funcionar todo! Por lo tanto, es vital codificar en un programa que conozca estos espacops, aprovecho Visual Studio Code gratuito de Microsoft! Aquí necesitas instalar Remote-SSH, se encuentra justo ahí en Extensions Marketplace

Después de la instalación, haga clic en conectar en la parte inferior izquierda, se abre una nueva ventana, lo principal es encenderlo en Ver > Terminal y en él se conecta como a un SSH normal, y se puede navigar por nuestro servidor. Por lo general, aquí funciona un comando de VSC para crear un nuevo archivo
code main.py

Yaaa el formato torcido (cientificamente conocido como concatenación) de python arrgelado, pero en VSC también existe – le gusta cerrar por Usted paréntesis abiertas, pero esto es una insignificancia tan pequeña en el contexto de la primera ¡que ni siquiera quiero cavar para encontrar como apagarla!

Cómo configurar una tarjeta de video y GFPGAN he descrito aquí ya ¡Aumentamos y mejoramos fotos antiguas con GFPGAN en Windows a través de WSL2 y una tarjeta con CUDA (o sin ella)!. Aquí usamos python sin Conda, por así decirlo, pero es necesario para GFPGAN, ¡pero no ejecutamos telegram bot en Conda!

Para un bot de Telegram, necesitas esta cosa github.com/python-telegram-bot la instalamos con pip VSC!
pip install python-telegram-bot

En el archivo main.py agrego el código abreviado de Karan, por supuesto es estándar

from telegram.ext import Updater, CommandHandler, MessageHandler, Filters

# Define a few command handlers. These usually take the two arguments update and
# context. Error handlers also receive the raised TelegramError object in error.
def privet(update, context):
    """Send a message when the command /start is issued."""
    update.message.reply_text('What ho!')

def echo(update, context):
    """Echo the user message."""
    update.message.reply_text(update.message.text)

def main():
    """Start the bot."""
    # Create the Updater and pass it your bot's token.
    # Make sure to set use_context=True to use the new context based callbacks
    # Post version 12 this will no longer be necessary
    updater = Updater("TUT VASH TOKEN OT BOTFATHER", use_context=True)

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # on different commands - answer in Telegram
    dp.add_handler(CommandHandler("privet", privet))
  
    # on noncommand i.e message - echo the message on Telegram
    dp.add_handler(MessageHandler(Filters.text, echo))

    # Start the Bot
    updater.start_polling()

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()

if __name__ == '__main__':
    main()

TUT VASH TOKEN OT BOTFATHER – cambio al token por recibido debotfather

¡Otra cosa buena de VSC es que guarda todos los cambios por si mismo!

Lanzamiento del bot en VSC
python main.py

¡Busco mi bot de Telegram llamado ITCookyFoto y aquí está!

¿Qué puede hacer ahora?
– Repetir todos los mensajes de los usuarios
– Responde al comando /privet como Bertie Wooster

Gracias Qatar, sigo por mi mismo!

Para detener main.py presione [Ctrl] + [c] un par de veces

…ha pasado una semana (no fue el tiempo dedicado a la codificación)

Publico código

Hay que crear un archivo
vi /home/alexandr/python/main.py

code

import os, subprocess
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters

os.chdir("/home/alexandr/python/")

def start(update, context):
    update.message.reply_text('What ho! This bot enhances with GFPGAN (github.com/TencentARC/GFPGAN) and resizes x2 your small fotos! It operates on RTX 2070 video card with CUDA.\n Created by www.itcooky.com', disable_web_page_preview=True)

def gfpgan(filename):
    try:
        subprocess.run(f"/home/alexandr/miniforge3/bin/conda run -n GFPGAN python /home/alexandr/python/inference_gfpgan.py -i /home/alexandr/python/{filename} -o /home/alexandr/python/res -v 1.3 -s 2", shell=True, check=True, stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/{filename}", shell=True, check=True, stderr=subprocess.DEVNULL)
        return False


def image_handler(update, context):
    user = str(update.message.from_user.id)
    file = update.message.photo[-1].file_id
    obj = context.bot.get_file(file)
    obj.download()
    filename =   str(obj.file_path).split('/')[-1]
    #print(filename)
    update.message.reply_text("File received. Wait few minutes for your  resized and enhanced foto!")
    result = gfpgan(filename)
    if result:
        update.message.reply_text("Done")
        pathres = "/home/alexandr/python/res/restored_imgs/" + filename
        update.message.reply_document(document = open(pathres, "rb"))
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/{filename}", shell=True, check=True, stderr=subprocess.DEVNULL)
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/res/cmp/*", shell=True, check=True, stderr=subprocess.DEVNULL)
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/res/cropped_faces/*", shell=True, check=True, stderr=subprocess.DEVNULL)
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/res/restored_faces/*", shell=True, check=True, stderr=subprocess.DEVNULL)
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/res/restored_imgs/*", shell=True, check=True, stderr=subprocess.DEVNULL)
    else:
        update.message.reply_text("Error: Try another image file")

def main():
    """Start the bot."""
    updater = Updater("TUT VASH TOKEN OT BOTFATHER", use_context=True)

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    dp.add_handler(MessageHandler(Filters.photo, image_handler))
    dp.add_handler(CommandHandler("start", start))

    # Start the Bot
    updater.start_polling()

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()

if __name__ == '__main__':
    main()

En la misma carpeta /home/alexandr/python/ puse todo lo que estaba en la carpeta GFPGAN

Acerca de code

os.chdir("/home/alexandr/python/")

– esto es algo muy importante que dice desde qué directorio se está ejecutando el script – siempre que lo ejecute manualmente, no importa en absoluto, y cuándo lo iniciará el sistema, debe indicarse en qué carpeta. Por lo tanto, el resto de las rutas estan escritas completas.

Función gfpgan: inicia un comando para procesar la imagen y regresa con éxito o no.

La función image_handler es la función principal. Guarda la foto que envía el usuario. Ejecuta la función gfpgan, si funcionó correctamente, envía una foto de un lugar conocido, y si no, escribe que no. Al final, elimina todas las fotos enviadas y procesadas.

Más detalladamente

    file = update.message.photo[-1].file_id
    obj = context.bot.get_file(file)
    obj.download()

– este código guarda la foto enviada..a que es divertido – si pones 0 en lugar de -1 entonces, por alguna razón, guardará una foto muy pequeña… ¿no? ¿No crees que es gracioso? A mi me hizo mucha gracia al enterarme de esto después de un par de horas de diagnosticar GFPGAN, ¡no pude entender por qué, después del aumento, la foto que me enviaron en respuesta, es aun mas pequeña!

filename =   str(obj.file_path).split('/')[-1] 

– sacamos con qué nombre el bot guardó la foto. Por cierto, no necesitamos el nombre de usuario a quién enviar el resultado en el marco de esta función, ya se sabe a quién enviarlo.

result = gfpgan(filename)

– iniciar el procesamiento de la foto, pasar el nombre de la foto, en respuesta True si es bueno y False si es malo

    if result:

– es True

        update.message.reply_text("Done")

– escribe que todo esta bien

        pathres = "/home/alexandr/python/res/restored_imgs/" + filename 
        update.message.reply_document(document = open(pathres, "rb"))

– formar la ruta al archivo procesado en pathres. Y luego enviamos una foto como respuesta. Aquí es necesario enviar a través de document si a través de photo se reducirá segun la pantalla y no se descargará la completa.

        subprocess.run(f"/usr/bin/rm /home/alexandr/python/{filename}", shell=True, check=True, stderr=subprocess.DEVNULL)
        subprocess.run(f"/usr/bin/rm /home/alexandr/python/res/restored_imgs/{filename}", shell=True, check=True, stderr=subprocess.DEVNULL)

– borrar fotos

Aquí está el enlace al bot
t.me/ITCookyFotoBot

Esta es la foto ideal

Leo el de antes…

…y despues

Ejecute nuestro script de python como un servicio

sudo vi /lib/systemd/system/telegrambot.service

Agregar texto

[Unit]
Description=Telegram Bot GFPGAN
After=multi-user.target
Conflicts=getty@tty1.service

[Service]
Type=simple
ExecStart=/home/alexandr/miniforge3/bin/python /home/alexandr/python/main.py
StandardInput=tty-force

[Install]
WantedBy=multi-user.target

Releyendo los demonios
sudo systemctl daemon-reload

Ahora hay que hacerlo lanzable en boot, y lo lanzamos ahora mismo sin boot
sudo systemctl enable telegrambot.service
sudo systemctl start telegrambot.service

Ahora todo siempre se ejecutará solo.


Deja una respuesta

Tu dirección de correo electrónico no será publicada.