Sistema de riego sencilla: corrigiendo la fecha

Un inconveniente que surgió con la captura de las imágenes desde la cámara IP es la fecha y hora de la cámara, hasta el momento no encontré manera de setear la fecha correcta, por ende en todas las imágenes la marca de agua con la fecha y hora es incorrecta.

Alma en el fondo de la imágen

La imagen anterior se corresponde con la marca de tiempo 2019-09-04 13:20:09, sin embargo en la marca de agua figura otra fecha del 2018.

La forma que encontré hasta el momento es correr un pequeño script en Python para corregir la fecha superponiendo un recuadro negro con la fecha correcta, la cual toma del nombre del archivo; para esto dos funciones de OpenCV.

El script es sencillo consta de tres partes:
1. Lista todos los archivos png dentro de la carpeta donde se estan guardando las imágenes.


1
2
3
4
5
ruta = "C:/Users/Guillermo/Desktop/img_riego"
output = "C:/Users/Guillermo/Desktop/output/"
for file in os.listdir(ruta):
    if file.endswith(".png"):
        print(file)

Simplemente recorremos los archivos dentro de la ruta (vble que contiene el path hasta las imágenes) y evaluamos si el archivo termina con .png o no para validar que sean imágenes.


2. Abre cada archivo, agrega el rectángulo negro y el texto. El texto además identifica que nro. de días es, no muestra la fecha. Es para poder identificar rápidamente el paso del tiempo.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        img = cv2.imread(ruta+"/"+file)

        cv2.rectangle(img,(850,54),(1261,84),(0,0,0),-1)

        t = file.split("_")

        if(nombre != str(t[0])):
            nombre = str(t[0])
            nroDia = nroDia + 1

        hora = t[1].split(".")[0]
        texto = "Dia "+str(nroDia)+" "+str(hora)

        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img,texto,(850,82), font, 1,(255,255,255),2,cv2.LINE_AA)

Abrimos la imagen y almacenamos en img; agregamos el rectangulo cuya coordenamas previamente las sacamos por medio de algun soft de edicion de imagenes, en este caso siempre seran las mismas.

Evaluamos si en el nombre de la imagen cambio o no la fecha, en caso que haya cambiado, incrementamos el nro de dias en 1.

Por ultimo ponemos el texto en la imagen.


3. Guarda la imagen en una carpeta de salida, de manera de conservar el original:


1
cv2.imwrite(output+file,img)

Se puede encontrar el script completo aqui.

Basta con hacer algunos pequeños ajustes para que se pueda utilizar para cualquier tipo de foto.

El resultado es el siguiente:

Serial a SQL

En un articulo anterior había comentado como logré tomar los datos que transmite un Arduino (provenientes de un sensor) y guardarlos en una hoja de calculo. En esta oportunidad quiero comentarles algo que esta en la misma dirección, en lugar de guardar en una hoja de calculo, llevarlos a una base de datos.

Para cumplir esto desarrolle una sencilla herramienta de terminal, que la pueden encontrar:

https://github.com/gsampallo/serial2sql

Luego de descargar la herramienta, el primer punto es tener acceso a un motor de base de datos; en mi caso utilice MySQL, puesto que es la más común y fácil de implementar. Debemos tener disponible los datos de las credenciales y permisos sobre una base de datos, luego el script se ocupara de crear una tabla e insertar en ella los datos. También existe la opción de no guardar los datos en la base al momento de recibirlos sino guardarlos en un archivo sql para luego insertarlos donde necesitemos. Está en las necesidades puntuales de cada uno ver cual es el uso optimo para cada aplicación.

Sera necesario proveerle un mínimo de información al script para que este realizar las acciones, para ello se utiliza una archivo config.json con la siguiente estructura:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "port":"/dev/ttyUSB0",
    "baudrate": 115200,
    "credentials" : {
    "host":"host",
    "database":"databaseName",
    "user":"userName",
    "password":"password",
    "raise_on_warnings": "True"
    },
    "tableName": "tableName",
    "fields": [
        { "name":"indice","type":"INT(10)" },
        { "name":"valor","type":"INT(10)" }
    ]
}

Se debe editar el archivo para que sea congruente con los datos de nuestra instalación.

Basicamente contiene la información de los datos de conexion del puerto serie: puerto y velocidad que se van a emplear para conectarse. Asi como tambien el nombre de la tabla (tableName) que utilizara para almacenar los datos, a continuación tenemos fields, que es una lista que contiene el nombre de cada campo junto con el tipo de dato que almacenara.

Un punto a tener en cuenta, es que el tipo de datos empleado es SQL, por lo que es sencillo definirlo; en este caso utilizamos los tipos de MySQL. En el json de ejemplo solo empleamos dos campos indice y valor, ambos enteros; pero esto podemos establecerlo según las necesidades puntuales. Siempre sabiendo de antemano cuales serán los datos que Arduino transmitirá por el puerto serie.

Si por ejemplo Arduino transmitiera cuatro campos: A,B,C,D donde A,B y C son enteros y D es una cadena de texto, deberíamos especificar el segmento fields de la siguiente manera:


1
2
3
4
5
6
    "fields": [
        { "name":"A","type":"INT(10)" },
        { "name":"B","type":"INT(10)" },
        { "name":"C","type":"INT(10)" },
        { "name":"D","type":"VARCHAR(80)" }
    ]

La longitud dependerá de lo que almacenemos.

Luego de establecido el archivo config.json simplemente basta ejecutarlo de la siguiente manera:

python serial2sql.py

Si estuviéramos en linux debemos anteponer el comando sudo para tener permisos sobre el puerto.

Adicionalmente también existe la posibilidad de guardar los datos a un archivo sql, de forma de poder insertarlos luego, para hacerlo basta especificar el parametro -o y el nombre del archivo:

python serial2sql.py -o output.sql

Otra variante interesante es utilizar la extensión csv en lugar sql, los datos de serán almacenados en formato csv:

python serial2sql.py -o output.csv

Especificando estas dos opciones no se guardara en la base de datos, ni se creara la tabla, solo se guardara el archivo.