Criando modelo para OpenCV part 1

Nesse pots, iremos montar um algoritmo para ajudar na montagem de uma classe para ser usada no OpenCV. Inicialmente precisamos criar uma pasta onde ira conter todas as imagens para o treino da maquina.

Afim de automatizar, usamos a biblioteca google_images_download e ao rodar o programa, o mesmo irá pedir informações como:

Índice de busca : quais serão os termos de busca no google, ex: carros, aviões, bicicletas.

Formato desejado: jpg ou png.

Label da classe : Nome pai da classe, você pode carregar várias buscas em uma só label. ex: Carros

Limite: numero da quantidade de imagens que você deseja fazer download, max de 100 por query de busca.

opencv_premakemodel.py

# Importando google_images_download 
from google_images_download import google_images_download 

# Criando Objeto
response = google_images_download.googleimagesdownload() 

# Aqui ira conter todas as palavras chaves para a busca
busca_modelo =[] 

# Loop para setar o busca_modelo
while True:
    mod = input("Insira o indice de busca do modelo desejados: ")
    busca_modelo.append(mod)
    op = input("Deseja adicionar mais modelos ? (s/n) ")
    if op == 'n' or op == 'N':
        break

form = input("Qual formato desejado ? ")

cate = input("Insira o label do modelo: ")
cate = "Modelos/" + cate

# Setando um limite maximo para nao dar crash
limit = int(input("Insira o numero de buscas desejadas (max:100): "))
if limit >= 101:
	limit = 100

def premakemodel(query): 
	arguments = {"keywords": query, 
				"format": form, 
				"limit": limit, 
				"print_urls":True, 
				"size": "medium",
                "output_directory" : cate,
                "no_directory" : True,
                "aspect_ratio" : "panoramic"
				} 
	try: 
		response.download(arguments) 
	

	except FileNotFoundError: 
		arguments = {"keywords": query, 
					"format": form, 
					"limit": limit, 
					"print_urls":True, 
					"size": "medium",
                    "no_directory" : True,
                    "output_directory" : cate
                    } 
					

		try: 
			response.download(arguments) 
		except: 
			pass


# Main
for modelo in busca_modelo: 
	premakemodel(modelo) 

Reconhecimento de Caligrafia com TensorFlow

TensorFlow é uma ferramenta de IA do google muito conhecida, nesse exemplo iremos usa-la para treinar um modelo com 60000 imagens e testar esse modelo com 10000 exemplos. Um código simples e comentado para iniciantes.

Para instalar as dependências:

pip install tensorflow
pip install numpy
pip install matplotlib

tensorflow_exe.py

# Importe do Tensorflow para desenvolver IA
# Matplotlib para imprimir o x_te
# Numpy para tirar o maior argumento do predict
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# Importa o Data
mnist = tf.keras.datasets.mnist

# Carrega as variáveis
# Ambiente de treino : x_tr y_tr
# Ambiente de teste :  x_te y_te
(x_tr, y_tr),(x_te, y_te) = mnist.load_data()

# As variaveis de entrada precisa ser convertidas de (0,255) para (0,1)
x_tr, x_te = x_tr / 255.0, x_te / 255.0

# Cria um modelo que possui:
# Input de 28x28 referente aos pixels da imagem.
# Camada de entrada com 128 nós seguindo ativação linear
# Drop de 20% para evitar over
# Camade de abstração de caracteristicas com 64 nós com ativação linear
# Camada de Saida com 10 nós. (Valores de 0 a 9)
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(64, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

print("Treinando Modelo ------------------------------------")
# Configurações do modelo, otimizador, perdas e metrica
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# Começa o treino com 60000 exemplos
model.fit(x_tr, y_tr, epochs=10)
print("Testando Modelo -------------------------------------")
# Testa o modelo com 10000 exemplos
model.evaluate(x_te, y_te)

# Cria uma previsão dos 10000 modelos com base em x
predicty  = model.predict(x_te)

# Um loop para teste
while True:
    vlin = int(input("Insira qual posição deseja testar: (1-10k) "))

# Matplot vai criar uma caixa com a imagem x escolhida
    plt.figure()
    plt.imshow(x_te[vlin])
    plt.colorbar()
    plt.grid(True)
    plt.show()

# Np.argmax é uma função do numpy que irá extrair a caracteristica
# que teve maior probabilidade.
    print("Valor previsto: ", np.argmax(predicty[vlin]))
    op = input("Deseja fazer nova busca ? (s/n) ")
    if op == 'n' or op == 'N':
        break

Node.js + Visual Recognition Parte 1.

Com o Node.js instalado no computador host do app, iremos criar o arquivo inicial do nosso servidor com: npm init, registrado o app, é necessário importar bibliotecas para montar a estrutura base do nosso webserver, seguindo o recomendado, irei importar:

        npm install express –save
	npm install express-generator –save
	npm install multer –save
	npm install ibm-watson-cloud –save
	npm install nodemon –g

O express e o express-generator são micro frameworks que ajuda na configuração das rotas do servidor, multer será responsável por manipular a imagem que nosso usuário irá inserir no front-end e salvar em uma pasta dentro do servidor pelo nosso back-end. Para nossa api de classificação de imagens, iremos importar a lib responsável pela comunicação com a IA Watson. Buscando melhor eficiência no projeto, iremos usar o nodemon apenas para desenvolvimento, com ele poderá fazer alterações no código do servidor sem a necessidade de ficar reiniciando. Ao terminar o download iremos executar o express –view ejs via console e o mesmo irá gerar todas as pastas e arquivos necessário para executar a primeira api no servidor.

Estruturalmente, um servidor Node.js possui uma pasta bin, no qual contém o primeiro arquivo a ser executado quando o servidor estiver ligado. Node_modules carrega todos os módulos importados pelas tags –save ao instalar os pacotes, routes irá assumir nossas rotas de tráfego e as views será front-end renderizada em ejs. O arquivo app.js irá conter todas as informações e configurações do nosso servidor.

No app.js iremos adicionar:

var apiRouter = require('./routes/api');
app.use('/api', apiRouter);

Função responsável para criar uma rota para nossa api.

api.js

var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
  res.render('end', { title: 'Express' });
});
module.exports = router;

Criado um arquivo javascript que irá contar todo o conteúdo necessário para exemplificar nosso exemplo de reconhecimento visual. Inicialmente irá receber um método get e responder com uma view end.ejs com dados que futuramente será recebido da cloud.

            Foi criado uma view index.ejs apenas com um input de imagem, requerendo um método post para a api. Precisa-se criar uma resposta para a requisição post do index.ejs e o mesmo salvar a imagem em um arquivo local. Essa imagem será criada de forma estática, como é um exemplo de como usar a ferramenta, para não consumir banco de dados e várias linhas de código tratando strings e inserts, o foco é o potencial da ferramenta de reconhecimento visual.

const multer = require('multer');
const fs = require('fs');

Importando o multer, responsável pela manipulação de nossa imagem. Multer cria um storage que contém informações do nosso path de destino e de entrada, configurando a variável para aceitar requisição post e salvar a imagem.

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '../ProjIA/public/img');
  },
  filename: function (req, file, cb) {
     var exts = file.originalname.split('.')[1];
    cb(null, '1' + '.' + exts);
  }
});
var upload = multer({ storage: storage });
router.post('/', upload.single('file'), function(req, res, next) {});

VoeBem

Nesse artigo venho apresentar um pequeno sistema de gerenciamento de voo, que foi entregue como trabalho da faculdade.

/*  Voe Bem - sistema de gerenciamento de voos */
/*  Desenvolvido por Eduardo Bertin            */
/*  contato@eduardobertin.com.br               */
/*  www.eduardobertin.com.br                   */
/*                                             */
/*  ui.h : biblioteca user interface.          */
/*  core.h : gerenciamento de estruturas.      */
/*  data.h : arquivamento, banco de dados.     */
/*                                             */
/*---------------------------------------------*/

Chat Simples com Node.js

Geralmente apps de chat de tempo real, são muito complicados para desenvolver, diferente do popular Lamp(PHP), Socket.io é uma solução bem plausível para desenvolvimento de real-time chat.

Essa lib da Node.js, cria um canal de comunicação bi-direcional entre o cliente e o server. Podendo enviar sinal para todos os clientes presentes.

Será necessária uma configuração, primeiramente a instalação do Node.JS que pode ser encontrado em:

https://nodejs.org/en/

Depois de criado a pasta do nosso aplicativo um npm init irá gera o package.json, nosso pacote onde irá ter todas as libs que iremos usar em nosso projeto.

Pronto, agora podemos instalar nossa lib Express e começar nosso desenvolvimento do app, para instalar o express, digite esse comando no prompt dentro da pasta do seu projeto.

npm install express --save

Após instalar a lib express, iremos iniciar a programação do nosso APP. Com o index.js:

var app = require('express')();
 var http = require('http').Server(app);
 
 app.get('/', function(req, res){
   res.send('<h1>Olá Mundo</h1>');
 });
 
 http.listen(3000, function(){
   console.log('Servidor rodando na porta: 3000);
 }); 

Inicialmente, declaramos duas variáveis, uma do tipo express (nossa lib previamente instalada) e http onde iremos carregar nosso servidor http.

A função app.get irá redirecionar qualquer cliente que se conectar no path ‘/’ (raiz do programa) e irá enviar uma mensagem Olá Mundo, lembrando que req irá carregar qualquer requisição da função e res irá dar uma função de resposta para nossa função get APP.

Após servidor http criado e nossa rota com o app setado, chamaremos a função listen, que irá ouvir nossas requisições na porta 3000, ou seja, http://localhost:3000.

Lembrando que estamos trabalhando em ambiente localhost para desenvolvimento. Agora, iremos rodar nosso APP, para exemplificar oque desenvolvemos até agora.

No Prompt do comando iremos exexcutar:

node index.js

Ao acessar o endereço localhost, notamos que foi exibido nossa tela “Olá Mundo”, e no nosso prompt irá exibir a porta em que o server irá ouvir as solicitações.

Observamos que nosso aplicativo utiliza o res.send() para enviar nossa mensagem de “Ola Mundo”, porem é apenas uma string e seria inviável criar um html pelo res.send dentro do index.js. Então iremos redirecionar nosso GET para um endereço index.html.

app.get('/',function(req,res){
   res.sendFile(__dirname+'/index.html');
 });

Essa substituição do nosso APP get, irá redirecionar todos os métodos GET na pasta raiz do nosso APP para um endereço de html.

Nosso html de forma simplificada e mais didática(sem css e configs).

<!doctype html>
 <html>
   <head>
     <title>Socket.IO Exemplo (chat)</title>
   </head>
   <body>
     <ul id="messages"></ul>
     <form action="">
       <input id="m" autocomplete="off" /><button>Enviar</button>
     </form>
   </body>
 </html>

Nosso html tem uma simples lista que irá retornar as mensagens de todos os clientes, e um botão Enviar.


Após configurar o JS e montar nosso template em html, iremos importar a lib Socket.IO.

Essa lib é composta por duas partes:

  • A primeira é responsável por integrar nossa lib com o Server http. (Server-side)
  • Já a segunda, é responsável pelo carregamento de nosso browser (Client-side)

Para instalar nossa lib em nosso projeto, iremos apenas executar uma linha de comando em nosso prompt na raiz da aplicação.

npm install socket.io --save

Ao conferir seu package.json, observe que sua lib já foi incluída nas dependências do projeto.

Em index.js iremos declarar nossa variável io do tipo socket recebe do tipo http para ouvir todas as possíveis conexões http.

var io = require('socket.io')(http);

Após declarar nosso socket, iremos conectá-los.

io.on('connection', function(socket){
  console.log('Um usuário conectou.');
});

Será informado no nosso log do servidor quando um cliente conectar. Ao executar o código usando node index.js iremos observar que toda vez que nosso cliente requisitar por get nosso index.html, o mesmo irá executar a função de conexão com o socket.

Precisamos também criar uma função de retorno para quando nosso client desconectar.

io.on('connection', function(socket){
  console.log('Um usuário conectou');
  socket.on('disconnect', function(){
    console.log(' Um usuário desconectou');
  });
});

Agora temos uma conexão servidor-cliente, nosso próximo passo é enviar ao nosso cliente informações recebidas por todas as conexões de socket que tivermos.

Para isso, iremos utilizar no server-side, o emit.

Lembrando que temos as opções:

io.emit('evento', { for: 'everyone' });

Irá enviar um evento para todos os clientes.

socket.broadcast.emit('Olá');

Irá enviar para todos os clientes com exceção de um específico socket.

Agora iremos pegar as mensagens de todos os clientes e enviar de novo para eles.

io.emit('chat message', msg);

E na versão browser (client-side) iremos adicionar a nossa tag Javascript uma função que recebe essa mensagem do servidor e salva na lista com id #m

<script>
  $(function () {
    var socket = io();
    $('form').submit(function(e){
      e.preventDefault(); // prevents page reloading
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

Marca d’Agua (WaterMark)

Nesse exemplo iremos criar uma marca d’agua em uma imagem escolhida, o algoritmo irá perguntar se o usuário deseja salvar a composição final.

water_mark.py

# Importa a lib Pillow, pip install pillow
from PIL import Image, ImageDraw, ImageFont

# Abre a imagem escolhida e converte para RGBA
# on A é alpha (opacidade)
img_entrada = Image.open('teste.jpg').convert('RGBA')

# Pega altura e largura da imagem
width, height = img_entrada.size

# Cria uma nova imagem, com as dimensões iguais a da entrada
# com o typo RGBA, e seu alpha = 0 , totalmente invisivel.
texto = Image.new('RGBA', img_entrada.size, (255,255,255,0))

# Cria um tipo de font, e seta o tamanho
fnt = ImageFont.truetype('gang_wolfik.ttf', 60)

# Escreve o texto na variavel.
txt_draw = ImageDraw.Draw(texto)

# Escreve o texto com a posição escolhida, valor, tipo da fonte
# e preenchendo parcialmente o Alpha para gerar a transparencia.
txt_draw.text((width-170,height-30), "NodoOne", font=fnt, fill=(255,255,255,128))

saida = Image.alpha_composite(img_entrada, texto)

saida.show()

while True:
    saved = input("Deseja salvar essa alteração? (s/n): ")
    if saved == 'S' or saved == 's':
        saida.save("teste1.png")
        break
    elif saved == 'N' or saved == 'n':
        break

Criando Thumbnails

Neste exemplo iremos abordar um algoritmo que busca todas as imagens dentro de uma pasta com o glob, divide as imagens em arquivo e extensão com o auxilio do OS e splitext, redimensiona a imagem para formato thumbnail (128×128) e seta seu tipo para JPEG e extensão .thumbnail.

Exemplo:

Imagem *.jpg Grande
Imagem *.thumbnail 128×128

thumbnails.py

# pip install Pillow
from PIL import Image
# Importa glob e os para a busca na pasta
import glob, os

# Seta o tamanho do thumbnail 
tamanho = 128, 128

# Loop que procura todas as fotos jpg dentro da pasta
for img_entrada in glob.glob("*.jpg"):
    # Divide o nome do arquivo e sua extensão
    file, ext = os.path.splitext(img_entrada)
    # Abre a imagem
    img = Image.open(img_entrada)
    # Converte o tamanho da foto para o escolhido.
    img.thumbnail(tamanho)
    # Salva a nova imagem no formato JPEG com extensão .thumbnail
    img.save(file + ".thumbnail", "JPEG")

Redimensionamento de Imagens

Esse algoritmo foi extraído de um curso EAD da Harvard, sua função é redimensionar uma imagem de entrada e gerar uma imagem de saída, usando a biblioteca Pillow, que pode ser obtida pelo pip install pillow.

resize.py

# pip install Pillow
from PIL import Image
# Import Nativo
from sys import argv

# Irá conferir se a entrada possui 4 argumentos.
if len(argv) != 4:
    exit("Uso: python resize.py n entrada saida")

# N irá receber o valor da proporção que a imagem irá alterar.
n = int(argv[1])

# Path da imagem de entrada
entrada = argv[2]

# Path da imagem de saída
saida = argv[3]

# Cria uma variável que recebe a imagem de entrada.
img_entrada = Image.open(entrada)
# Importa valores de altura e largura da imagem de entrada.
width, height = img_entrada.size
# Cria uma imagem de saida redimencionando altura e largura original.
img_saida = img_entrada.resize((width*n, height*n))

# Salva a alteração na imagem de saida
img_saida.save(saida)

Bubble Sort

Um algoritmo de busca bem simples que irá buscar posições dentro do array, se a condição imposta for verdadeira, ela troca os elementos entre si.

bubble_sort.py

# Importando Sys
import sys

# Definindo Main
def main():

# Usuário irá digitar uma array int e o
# bubble sort irá buscar e organizar.

    print('Bubble Sort')
    print('Digite uma array com espaços  | Ex: 12 23 4 6 21 13')
    print('-------------------------------------------------------------------')
    array = list(map(int,input().split()))
    bubble_sort(array)

    print('Array organizado de forma crescente: ', array)
   
# Função bubble sort irá organizar o array
# Ele atravessa o array entre 0 e (qtderegistros)-i-1, troca o elemento
# se mesmo for maior que o próximo.
def bubble_sort(array):
# Carrega array_len com o valor do numero de registro que o mesmo persiste.
    array_len = len(array)

    for i in range(array_len):
# Quando a condição for verdade, os elementos trocam entre si de posição
        for j in range(0, (array_len-i)-1):
            if array[j] >> array[j+1]:
                array[j], array[j+1] = array[j+1], array


# Primeira call será a main
if __name__ == '__main__':
    main()

Selection Sort

Nesse exemplo, iremos usar a técnica de Selection Sort, esse algoritmo irá comparar todos os valores da array, e enviar o menor valor para o inicio.

Select_sort.py

# Importando Sys
import sys

# Definindo Main
def main():

# Usuário irá digitar uma array int e o
# select sort irá buscar e organizar.

    print('Selection Sort')
    print('Digite uma array com espaços  | Ex: 12 23 4 6 21 13')
    print('-------------------------------------------------------------------')
    array = list(map(int,input().split()))
    select_sort(array)

    print('Array organizado de forma crescente: ', array)
   


# Função select sort irá organizar o array
# Ele comprara os valores e o menor vai para o inicio do array
def select_sort(array):
    for i in range(len(array)):
        min_index = i
        for j in range(i+1, len(array)):
            if array[min_index] > array[j]:
                min_index = j

# Se o valor for menor, irá inserir no começo do array
        array[i], array[min_index] = array[min_index], array[i]



# Primeira call será a main
if __name__ == '__main__':
    main()

Insert Sort

O usuário fornece um array de forma não organizada, e a função insert_sort irá organizar de forma crescente.

insert_sort.py

import sys

# Definindo Main
def main():

# Usuário irá digitar uma array int e a função
# Insert Sort irá ordenar de forma crescente.
    print('Insert Sort')
    print('Digite uma array com espaços | Ex: 32 23 13 12 22 33')
    print('-------------------------------------------------------------------')
    array = list(map(int,input().split()))
    insert_sort(array) 
    print ("Array organizado de forma crescente:") 
    print(array)

def insert_sort(array):
    for i in range(0, len(array)):
        chave = array[i]
        j = i-1
        while j >= 0 and chave < array[j]:
            array[j+1] = array[j]
            j -= 1
        array[j+1] = chave

# Primeira call será a main
if __name__ == '__main__':
    main()

Busca Linear



Um algoritmo de busca linear, basta inserir a array na ordem crescente e informar qual numero você deseja saber o index.

busca_linear.py

# Importando Sys
import sys

# Definindo Main
def main():

# Usuário irá digitar uma array int com ordem crescente
# e inserir o valor int escolhido, a função linear
# retorna a posição do index do array.

    print('Busca Linear')
    print('Digite uma array com espaços em ordem crescente | Ex: 1 3 4 6 10 12')
    print('-------------------------------------------------------------------')
    array = list(map(int,input().split()))
    x = int(input('Entre com o valor escolhido.'))
    pos = busca_linear(array, x)

    if pos >= 0:
        print('Posição do index da array: ', pos)
    else:
        print('Não encontrado')


# Função linear para busca do index no array
def busca_linear(array, x):
    for i in range(0, len(array)):
        if array[i] == x:
            return i
    return -1

# Primeira call será a main
if __name__ == '__main__':
    main()

Busca Binária

Um exemplo de busca binária utilizando python, lembrando que a array deve ser preenchida na ordem crescente.

busca_binaria.py

# Importando Sys
import sys

# Definindo Main
def main():

# Usuário irá digitar uma array int com ordem crescente
# e inserir o valor int escolhido, a função recursiva
# retorna a posição do index do array.

    print('Busca Binaria Recursiva')
    print('Digite uma array com espaços em ordem crescente | Ex: 1 2 5 6 10 12')
    print('-------------------------------------------------------------------')
    array = list(map(int,input().split()))
    x = int(input('Entre com o valor escolhido.'))
    pos = busca_binaria(array, 0, len(array), x)

    if pos >= 0:
        print('Posição do index da array: ', pos)
    else:
        print('Não encontrado')


# Função recursiva para busca do index no array
def busca_binaria(array, p, r, x):

    if p <= r:
        q = (p+r) // 2

        if x > array[q]:
            return busca_binaria(array, q+1, r, x)
        elif x < array[q]:
            return busca_binaria(array, p, q-1, x)
        else:
            return q
    return -1 # retorna -1 se não existe o elemento na array.


# Primeira call será a main
if __name__ == '__main__':
    main()