Treinamento de Imagem Online
Site muito bom eu recomendo
Site muito bom eu recomendo
Este trabalho, esta sendo baseado, no treinamento realizado por mim, e adaptado, através do curso que estou fazendo:
https://www.udemy.com/course/deteccao-de-objetos-com-python-e-opencv/
Segue explicação em vídeo:
Este projeto é uma continuação do trabalho colocado no github:
https://github.com/marcelomaurin/hemacias
No programa teste03.py, apresento como capturar a imagem e fiz alguns tratamentos de fundo, usando opencv.
Neste artigo, irei preparar imagens para gerar o reconhecimento da hemácia.
Para tanto fiz a captura da hemácia, através da microscopia. Utilizando um microscópio com lente de ampliação de 20x, com uma câmera USB de 2Mb pixels.
Pegando a figura abaixo:
Irei tratar a imagem abaixo, para tentar reconhecer e contar as hemácias.
Para tanto o primeiro trabalho, é trabalhar com a imagem, fazendo duas etapas:
Retirar fundo da imagem da hemácia, e incluí-la em um banco de imagens de fundo.
Neste artigo, irei tratar cada uma destas atividades.
Agora que tenho a imagem, usarei o site
https://www.remove.bg/
Para retirar o fundo da imagem. O procedimento é bem simples, faz-se o upload da imagem já recortada, para o site, e lá retira-se o fundo, com o auxilio de ferramentas do próprio site.
O site é bem intuitivo e pode ser usado livremente.
Ao final criamos a imagem sem o fundo, que iremos utilizar.
A imagem positiva é a imagem que deve possuir a hemácia.
Neste primeiro momento eu preciso de uma base de imagens.
Para isso preciso baixar um grande volume de imagens para gerar tanto imagens positivas como negativas.
Eu peguei as imagem recortada, com os fundos apresentados no aplicativo, e fui recortando montando um banco de imagens coloridos.
Para as imagens de teste, eu peguei imagens de internet e recortei.
Conforme apresentado a baixo:
Para ter sucesso, precisarei refazer esse teste, com pelo menos uma dúzia de hemácias, produzindo pelo menos 1000 imagens.
Este trabalho é longo e demorará vários dias.
No próximo artigo iremos processar a imagens de treino, criando uma base real de treinamento.
Até agora, sempre que apresentei um projeto em OpenCV o fiz no linux.
Para aqueles que perderam as referencias dos meus projetos em OpenCV, segue uma lista bem resumida:
Agora irei faze-lo no Windows usando o Visual Studio.
Isso se dá porque geralmente eu prefiro o Linux ao Windows para desenvolvimento. A escolha é pessoal, e foi um hábito adquirido, no passar dos anos, pois o Linux, em minha opinião, oferece uma oportunidade maior de crescimento profissional. No que tange aprendizado de baixo nível.
Porem sem querer entrar nas questões de plataforma, há também necessidade, vez ou outra, usar o windows para desenvolvimento.
E para ser sincero, muitas vezes me sinto desconfortável, até pela falta de prática do uso desta plataforma.
Porem para chegar nesse ponto, irei apresentar alguns artigos, que devem ser necessários para este fim.
O primeiro é a instalação do OpenCV e sua respectiva configuração no ambiente windows.
Primeiramente vamos baixar o opencv no site:
Baixe a ultima versão desta lib.
De forma geral ao tentar instalar, ele compacta na pasta: C:\Users\marce\Downloads
Eu costumo mover ele para o raiz do D:\ , no caso, caso não use um segundo disco, faça em seu c:\
Pronto a instalação do OpenCV foi realizada.
Agora vou criar uma pasta VS, dentro do meu D:\opencv\
O C precisa de duas coisas para funcionar, se tratando de bibliotecas, includes e libs.
Copiando a pasta include, já marcada acima, dentro do VS.
No caminho D:\opencv\build\x64\vc16 ou equivalente, pois o build contem os arquivos pré compilados, onde no meu caso irei utilizar a plataforma win 64 bits, por isso o X64. Copiarei as pastas bin e lib da pasta, para o VS, conforme mostrado a seguir:
Agora precisamos incluir o caminho completo do bin, nas variáveis de ambiente:
Agora vamos dar inicio a criação do projeto no visual studio.
Entre no Visual Studio e crie um projeto.
Agora, selecionamos o tipo de projeto:
Como o visual studio tem muitos templates, é mais fácil pesquisar c++ na aba de pesquisa, e selecionar Projeto Vazio, conforme figura acima.
Digite o nome Hello World no Nome do projeto, conforme apresentado, e o local, indique a sua pasta de projeto. Por fim click no botão CRIAR.
Va na aba de gerenciador de Soluções, e click com botão direito no nome do projeto. Selecione NEW > Novo Item.
Mude para main.cpp e pressione adicionar.
Agora, iremos mudar o projeto, para incluir os locais que criamos no opencv.
Em PROJETO > Pagina de Propriedades, conforme figura abaixo:
Abra a aba C/C++, localize Diretórios de Inclusão Adicionais, incluindo o seguinte item:
Inclua a pasta do include.
Agora vamos adicionar a lib.
Em GERAL > Vinculador , Diretórios de Biblioteca Adicionais
Inclua o a pasta D:\opencv\VS\lib
Agora iremos mostrar qual a lib que será adicionada.
A lib que iremos usar para debug, é opencv_world480d.lib.
Para isso vamos em Propriendades de Configuração > Vinculador > Entrada > Dependências Adicionais.
Pronto agora vamos ao código.
Inclusão do fonte:
Iremos usar o fonte que apontamos no artigo anterior, com uma pequena modificação.
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main(int, char**)
{
Mat frame;
//--- INITIALIZE VIDEOCAPTURE
VideoCapture cap;
// open the default camera using default API
//cap.open(0);
// OR advance usage: select any API backend
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID, apiID);
// check if we succeeded
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
return -1;
}
//--- GRAB AND WRITE LOOP
cout << "Start grabbing" << endl
<< "Press any key to terminate" << endl;
for (;;)
{
// wait for a new frame from camera and store it into 'frame'
cap.read(frame);
// check if we succeeded
if (frame.empty()) {
cerr << "ERROR! blank frame grabbed\n";
break;
}
// show live and wait for a key with timeout long enough to show images
imshow("Live", frame);
if (waitKey(5) >= 0)
break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Salve o programa, e como de praxe para o windows, reinicie o visual studio, para validar as modificações do ambiente.
Agora é só rodar o OpenCV e pronto.
Por fim para aqueles que quiserem, segue o github:
Neste estudo darei um exemplo de aplicação prática usando o OPENCV.
Este artigo faz parte do trabalho de pós graduação apresentado na disciplina de OpenCV, da UNINOVE.
Para realizar este estudo comprei o VEIN DISPLAY INSTRUMENT ZY-500.
Caracteristicas:
Ele é basicamente uma webcam USB 2.0, com resolução de 1080 pixel.
Este equipamento emite uma luz infra vermelha, que parcialmente penetra na pele (derme), e é refletida.
Porem em áreas onde existe muito sangue, a luz infra vermelha é absorvida.
Sabendo disso, fica facil identificar as veias proximas da pele.
Abaixo vemos um vídeo onde demonstro a visualização da camera sem nenhum tratamento.
Aqui apresentaremos detalhes do funcionamento da camera.
Podemos ver em uma câmera normal, que as veias não se destacam.
Porem podemos ver exatamente as veias na camera infravermelha.
Nesta imagem, sem filtros, podemos ver as veias claramente.
A imagem acima foi obtida, através do processamento do seguinte script PYTHON.
Iremos aplicar as técnicas aprendidas no curso, para avaliar a viabilidade destas na aplicação da solução. Lembrando que como qualquer processo cientifico, a experimentação empírica faz parte do processo.
E nem todas as técnicas serão utilizadas no projeto final.
import cv2
device = 5
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
cv2.imshow("Camera Detector Veia", frame)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
A máquina em questão possui diversos devices (Cameras) acopladas, porem o número pode subir pois scripts em python tem o estranho habito de travar, e as vezes é necessário desligar o dispositivo, e religalo, o que causa um incremento no numero do device devido ao travamento do recurso.
Este travamento é temporario.
Separando a banda RED e verificando a melhora.
No fragmento de código abaixo, seleciono apenas a banda RED do RGB, onde analiso se há mudança significativa.
import cv2
device = 5
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
(B, G, R) = cv2.split(frame)
cv2.imshow('RED',R)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Sobre o meu ponto de vista, pegar apenas a banda R não melhorou, mas piorou um pouco a imagem.
Isolei tambem a Banda G (green)
A banda B já piorou ainda mais
Conforme a explicação do site abaixo:
https://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_Changing_ColorSpaces_RGB_HSV_HLS.php
Pudemos realizar a conversão das bandas em outros padrões.
import cv2
from PIL import Image
import numpy as np
device = 5
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',gray)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Pude perceber uma pequena melhora, neste padrão.
HSV analisaremos a cor por suas caracteristicas de COR (H), S é a saturação, V é o brilho.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 16:00:05 2022
@author: mmm
"""
import cv2
from PIL import Image
import numpy as np
device = 5
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
#low_red = np.array([161, 155, 84])
#high_red = np.array([179, 255, 255])
#low_green = np.array([25, 52, 72])
#high_green = np.array([102, 255, 255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_blue , upper_blue )
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Analisando a cor Blue, percebemos que muito pouco podemos aproveitar desta analise.
Agora iremos analisar a imagem baseada no seu contorno.
https://pyimagesearch.com/2021/04/28/opencv-color-spaces-cv2-cvtcolor/
No fragmento abaixo, tentamos aplicar o filtro gaussiano , conforme apresentado a seguir.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 16:00:05 2022
@author: mmm
"""
import cv2
#from PIL import Image
import numpy as np
import imutils
device = 2
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
cv2.imshow("Camera Detector Veia", frame)
(B, G, R) = cv2.split(frame)
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray1 = cv2.GaussianBlur(frame, (2, 2), 0)
edged = cv2.Canny(frame, 30, 70)
cv2.imshow('gray',gray)
cv2.imshow('gray1',gray1)
cv2.imshow('edged',edged)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Podemos ver que não conseguimos ver os detalhes da veia, porem os contornos ficam aparentes.
Na forma que foi realizado, o contorno não se aplica de forma prática. Porem poderia ser aproveitado, na determinação do espaço do braço.
Nesta técnica irei retirar o fundo para isolar o braço.
Usarei a limiarização da imagem para determinar o espaço do braço.
Podemos ver detalhes dessa técnica no artigo:
https://acervolima.com/python-tecnicas-de-limiarizacao-usando-opencv-conjunto-1-limiar-simples/
O nosso código, já possui a técnica contendo o resultado final empregado.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 16:00:05 2022
@author: mmm
"""
import cv2
#from PIL import Image
import numpy as np
import imutils
import pip
import importlib, os
from matplotlib import pyplot as plt
#import Image
from PIL import Image, ImageChops
global fundo
global frame
global gray1
global edged
global ret
device = 2
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
cv2.imshow("Camera Detector Veia", frame)
(B, G, R) = cv2.split(frame)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
num_lim = frame.shape[0]
num_col = frame.shape[1]
num_bandas = frame.shape[2]
gray2= np.zeros((num_lim , num_col), dtype="uint8")
gray2= B+G+R//3
#[num_lim, num_col, num_bandas] = frame.shape
dimensions = frame.shape
print('Image Dimension:',dimensions)
print('Image Height :',num_lim)
print('Image width:',num_col)
print('Image Channels:',num_bandas)
thresh = 135
fundo2 = cv2.threshold(gray,thresh,255,cv2.THRESH_BINARY)[1] #imagem limiralizada
#[thresh, fundo2] = cv2.threshold(gray, thresh, 255, cv2.THRESH_OTSU)
cv2.imshow("fundo2",fundo2)
img_filtro= np.zeros((num_lim , num_col, num_bandas), dtype="uint8")
for l in range(num_lim):
for c in range(num_col):
img_filtro[l,c] = ((fundo2[l,c]) & (frame[l,c] ^ fundo2[l,c]))
#img_filtro[l,c] = (frame[l,c] ^ fundo2[l,c])
#img_filtro = ImageChops.difference(fundo, frame)
cv2.imshow("filtrado", img_filtro)
while(1):
#gaus = cv2.GaussianBlur(img_filtro, (3, 3), 0)
#edged = cv2.Canny(img_filtro, 40, 103)
#janela = np.ones((3,3),np.float32)*-1
#palta = cv2.filter2D(img_filtro,-6,janela)
#gaus=cv2.GaussianBlur(img_filtro,(0,0),5)
#palta2=cv2.Scharr(img_filtro, ddepth=-1, dx=1, dy=0, scale=1, borderType=cv2.BORDER_DEFAULT)
#filtro = ImageChops.difference(fundo,gray)
#filtro = ImageChops.logical_xor(fundo,gray)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
RGB = cv2.cvtColor(img_filtro, cv2.COLOR_BGR2RGB)
grayold = gray
gray = cv2.cvtColor(RGB, cv2.COLOR_RGB2GRAY)
#gray = grayold
while(1):
cv2.imshow('gray',gray)
#http://www.lps.usp.br/hae/apostila/filtconv-ead.pdf
#Calculo de gradiente usando Scharr
schar=cv2.Scharr(gray, ddepth=-1, dx=0, dy=1, scale=1, borderType=cv2.BORDER_DEFAULT)
#cv2.imshow("gaus", gaus)
#cv2.imshow("Canny", edged)
cv2.imshow("Scharr", schar)
sobel=cv2.Sobel(schar,-2,1,1)
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(gray,kernel,iterations = 1)
maurin= np.zeros((num_lim , num_col), dtype="uint8")
for l in range(num_lim):
for c in range(num_col):
if(dilation[l,c]>=74 and dilation[l,c]<=76):
maurin[l,c] = 0
else:
maurin[l,c] = dilation[l,c]
thresh = 80
binimg=np.zeros((num_lim,num_col), dtype="uint8")
binimg=cv2.threshold(gray2, thresh, 255, cv2.THRESH_TOZERO)[1]
#cv2.imshow('gaus',gaus)
#cv2.imshow('edged',edged)
cv2.imshow('sobel',sobel)
cv2.imshow('dilation',dilation)
cv2.imshow('maurin:',maurin)
cv2.imshow('bin',binimg)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Neste ultimo fragmento, iremos retirar o fundo do braço, e trabalhar com a imagem para dar destaque.
O resultado final é o que se apresenta.
Na imagem acima, podemos perceber que retiramos o braço dos demais objetos da imagem.
Tambem tratamos a imagem em tons de cinza, que permite posteriormente um trato mais simples da imagem.
Qual a vantagem da imagem acima da original. Primeiramente, a imagem original apesar de ser bem visivel a veia para nós, não conseguimos determinar um tom unico, para apresentar como veias. Na imagem processada, o tom da veia, esta mais distinto da imagem.
Inicialmente capturamos a camera, através de um device.
Em seguida armazenamos a imagem na variavel frame.
Convertemos a imagem em cinza, através do comando:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Agora, feita a primeira conversão, iremos pegar as caracteristicas da imagem, através da propriedade shape.
As propriedades de Altura (Height), Width( Largura) e channel (numero de bandas).
Agora iremos separar o braço do fundo, através da Limiarização:
thresh = 127
#fundo2 = cv2.threshold(gray,thresh,255,cv2.THRESH_BINARY)[1] #imagem limiraizada
[thresh, fundo2] = cv2.threshold(gray, thresh, 255, cv2.THRESH_OTSU)
O processamento da limiarização foi armazenado em fundo2.
O fundo é comparado bit a bit, fazendo um processamento, onde deixamos apenas com a imagem o braço.
img_filtro[l,c] = ((fundo2[l,c]) & (frame[l,c] ^ fundo2[l,c]))
No exemplo acima, aplicamos um xor entre a imagem e o fundo,
Extraída e processada da imagem original.
O resultado desta pesquisa bit a bit, resultou de uma imagem copia da original.
Servindo apenas para uso futuro.
É um filtro que gera um gradiente 3D em imagens 2D, dando aspecto de relevo.
Podemos perceber que o filtro melhorou bastante a impressão da veia.
A chamada do scharr, fica conforme fragmento abaixo:
schar=cv2.Scharr(gray, ddepth=-1, dx=0, dy=1, scale=1, borderType=cv2.BORDER_DEFAULT)
O Filtro de dilatação, torna as marcas das veias mais marcantes.
Sua sintaxe é conforme apresentada.
Dando um incremento a visão da veia.
dilation = cv2.dilate(gray,kernel,iterations = 1)
Por fim apresentamos o vídeo final.
Este estudo demonstra que através de técnicas de manipulação de imagem, sem o uso de redes neurais conseguimos trabalhar com imagens, realçando e separando partes que desejamos trabalhar.
Outra parte importante, é a associação de operações:
img_filtro[l,c] = ((fundo2[l,c]) & (frame[l,c] ^ fundo2[l,c]))
Onde associamos o fundo da imagem com a imagem, a fim da extração do fundo e aplicação do formato RGB, desassociado ao fundo.
Concomitante com o uso do Dilate (filtro de dilatação) associado ao Scharr, apresentou ótimos resultados, conforme apresentado a seguir.
Tendo como resultado final o código gerado:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 16:00:05 2022
@author: mmm
"""
import cv2
#from PIL import Image
import numpy as np
import imutils
import pip
import importlib, os
from matplotlib import pyplot as plt
#import Image
from PIL import Image, ImageChops
global fundo
global frame
global gray1
global edged
global ret
device = 2
captura = cv2.VideoCapture(device)
while(1):
ret, frame = captura.read()
cv2.imshow("Camera Detector Veia", frame)
(B, G, R) = cv2.split(frame)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
num_lim = frame.shape[0]
num_col = frame.shape[1]
num_bandas = frame.shape[2]
gray2= np.zeros((num_lim , num_col), dtype="uint8")
gray2= B+G+R//3
#[num_lim, num_col, num_bandas] = frame.shape
dimensions = frame.shape
print('Image Dimension:',dimensions)
print('Image Height :',num_lim)
print('Image width:',num_col)
print('Image Channels:',num_bandas)
thresh = 135
fundo2 = cv2.threshold(gray,thresh,255,cv2.THRESH_BINARY)[1] #imagem limiralizada
#[thresh, fundo2] = cv2.threshold(gray, thresh, 255, cv2.THRESH_OTSU)
cv2.imshow("fundo2",fundo2)
img_filtro= np.zeros((num_lim , num_col, num_bandas), dtype="uint8")
for l in range(num_lim):
for c in range(num_col):
img_filtro[l,c] = ((fundo2[l,c]) & (frame[l,c] ^ fundo2[l,c]))
#img_filtro[l,c] = (frame[l,c] ^ fundo2[l,c])
#img_filtro = ImageChops.difference(fundo, frame)
cv2.imshow("filtrado", img_filtro)
while(1):
#gaus = cv2.GaussianBlur(img_filtro, (3, 3), 0)
#edged = cv2.Canny(img_filtro, 40, 103)
#janela = np.ones((3,3),np.float32)*-1
#palta = cv2.filter2D(img_filtro,-6,janela)
#gaus=cv2.GaussianBlur(img_filtro,(0,0),5)
#palta2=cv2.Scharr(img_filtro, ddepth=-1, dx=1, dy=0, scale=1, borderType=cv2.BORDER_DEFAULT)
#filtro = ImageChops.difference(fundo,gray)
#filtro = ImageChops.logical_xor(fundo,gray)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
RGB = cv2.cvtColor(img_filtro, cv2.COLOR_BGR2RGB)
grayold = gray
gray = cv2.cvtColor(RGB, cv2.COLOR_RGB2GRAY)
#gray = grayold
while(1):
cv2.imshow('gray',gray)
#http://www.lps.usp.br/hae/apostila/filtconv-ead.pdf
#Calculo de gradiente usando Scharr
schar=cv2.Scharr(gray, ddepth=-1, dx=0, dy=1, scale=1, borderType=cv2.BORDER_DEFAULT)
#cv2.imshow("gaus", gaus)
#cv2.imshow("Canny", edged)
cv2.imshow("Scharr", schar)
sobel=cv2.Sobel(schar,-2,1,1)
kernel = np.ones((5,5),np.uint8)
#dilation = cv2.dilate(gray,kernel,iterations = 1)
dilation = cv2.dilate(schar,kernel,iterations = 1)
maurin= np.zeros((num_lim , num_col), dtype="uint8")
for l in range(num_lim):
for c in range(num_col):
if(dilation[l,c]>=74 and dilation[l,c]<=76):
maurin[l,c] = 0
else:
maurin[l,c] = dilation[l,c]
thresh = 80
binimg=np.zeros((num_lim,num_col), dtype="uint8")
binimg=cv2.threshold(gray2, thresh, 255, cv2.THRESH_TOZERO)[1]
#cv2.imshow('gaus',gaus)
#cv2.imshow('edged',edged)
cv2.imshow('sobel',sobel)
cv2.imshow('dilation',dilation)
cv2.imshow('maurin:',maurin)
cv2.imshow('bin',binimg)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
captura.release()
cv2.destroyAllWindows()
Neste trabalho, podemos verificar que ainda é longo e árduo o trabalho que separa o pré processamento da imagem, bem como não se trata de um trabalho acabado. Há muitas técnicas aqui não empregadas, que poderiam ser ajustadas.
Porem a analise que foi feita em várias das técnicas apresentadas durante o curso, tiveram resultados significativos na identificação e destaque das veias.
Agradecimento especial ao Professor Sidnei Alves de Araujo, da UNINOVE, que incentivou e permitiu a execução de trabalho especial.
Em um artigo anterior fiz um exemplo de opencv em Python.
Neste artigo irei apresentar um exemplo de código de opencv em C++.
Irei comentar traçando referencias entre o código do C e o código do python.
O Exemplo utililizado será fornecido pela própria biblioteca em python.
Para traçar um paralelo usaremos os códigos do opencv, o programa chamado video_v4l2.py
Conforme apresentado abaixo:
#!/usr/bin/env python
'''
VideoCapture sample showcasing some features of the Video4Linux2 backend
Sample shows how VideoCapture class can be used to control parameters
of a webcam such as focus or framerate.
Also the sample provides an example how to access raw images delivered
by the hardware to get a grayscale image in a very efficient fashion.
Keys:
ESC - exit
g - toggle optimized grayscale conversion
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
def main():
def decode_fourcc(v):
v = int(v)
return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)])
font = cv.FONT_HERSHEY_SIMPLEX
color = (0, 255, 0)
cap = cv.VideoCapture(0)
cap.set(cv.CAP_PROP_AUTOFOCUS, 0) # Known bug: https://github.com/opencv/opencv/pull/5474
cv.namedWindow("Video")
convert_rgb = True
fps = int(cap.get(cv.CAP_PROP_FPS))
focus = int(min(cap.get(cv.CAP_PROP_FOCUS) * 100, 2**31-1)) # ceil focus to C_LONG as Python3 int can go to +inf
cv.createTrackbar("FPS", "Video", fps, 30, lambda v: cap.set(cv.CAP_PROP_FPS, v))
cv.createTrackbar("Focus", "Video", focus, 100, lambda v: cap.set(cv.CAP_PROP_FOCUS, v / 100))
while True:
_status, img = cap.read()
fourcc = decode_fourcc(cap.get(cv.CAP_PROP_FOURCC))
fps = cap.get(cv.CAP_PROP_FPS)
if not bool(cap.get(cv.CAP_PROP_CONVERT_RGB)):
if fourcc == "MJPG":
img = cv.imdecode(img, cv.IMREAD_GRAYSCALE)
elif fourcc == "YUYV":
img = cv.cvtColor(img, cv.COLOR_YUV2GRAY_YUYV)
else:
print("unsupported format")
break
cv.putText(img, "Mode: {}".format(fourcc), (15, 40), font, 1.0, color)
cv.putText(img, "FPS: {}".format(fps), (15, 80), font, 1.0, color)
cv.imshow("Video", img)
k = cv.waitKey(1)
if k == 27:
break
elif k == ord('g'):
convert_rgb = not convert_rgb
cap.set(cv.CAP_PROP_CONVERT_RGB, 1 if convert_rgb else 0)
print('Done')
if __name__ == '__main__':
print(__doc__)
main()
cv.destroyAllWindows()
A primeira informação importante é a carga das bibliotecas do opencv em python.
import cv2 as cvimport cv2 as cv
carga da lib em python
O proximo ponto importante é onde capturamos o vídeo.
cap = cv.VideoCapture(0)
Captura do vídeo
O Parametro 0, indica que o device de vídeo é o padrão do sistema.
O ponto importante no código é o uso do cap, no código abaixo:
_status, img = cap.read()
captura do frame
Ao chamar a função read, dois parametros são retornados, _status (retorno de sucesso) e img, a imagem capturada.
Por fim, uma janela é montada com a visualização da imagem capturada:
cv.imshow(“Video”, img)
janela é montada
Agora iremos analisar o mesmo código em C.
Agora mostraremos o código em C, o exemplo é o videocapture_basic.cpp:
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int, char**)
{
Mat frame;
//--- INITIALIZE VIDEOCAPTURE
VideoCapture cap;
// open the default camera using default API
// cap.open(0);
// OR advance usage: select any API backend
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID, apiID);
// check if we succeeded
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
return -1;
}
//--- GRAB AND WRITE LOOP
cout << "Start grabbing" << endl
<< "Press any key to terminate" << endl;
for (;;)
{
// wait for a new frame from camera and store it into 'frame'
cap.read(frame);
// check if we succeeded
if (frame.empty()) {
cerr << "ERROR! blank frame grabbed\n";
break;
}
// show live and wait for a key with timeout long enough to show images
imshow("Live", frame);
if (waitKey(5) >= 0)
break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
O primeiro ponto assim como no código em python, e a chamada da biblioteca em c.
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
Sem esses includes não teriamos acessos aos tipos do C, como o que segue:
VideoCapture cap;
O tipo VideoCapture é o tipo associado a captura de vídeo da câmera.
Onde usaremos, conforme fragmento abaixo:
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID, apiID);
Aqui, definimos o deviceID como 0, ou seja, o valor padrão, veja a semelhança do uso do python.
E apiID, passando o escopo (variavel) CAP_ANY, que tem por valor 0.
Chamamos o método open da classe VideoCapture, indicando o deviceID, e o apiID.
Agora iremos ler a imagem da camera, que podemos fazer, através da seguinte função:
cap.read(frame);
Neste fragmento de código, passamos o parametro frame, que é do tipo Mat.
O frame receberá a imagem capturada.
E por fim, no código abaixo a janela que irá mostrar a imagem na interface gráfica.
imshow("Live", frame);
Apesar das diferenças de linguagem, podemos ver o pontos em comum, e a sutileza da semelhança.
É lógico que os códigos foram escolhidos a dedo. Justamente por conta da semelhança e simplicidade.
O opencv é uma biblioteca rica, cheia de opções e dificuldades, este tutorial, bem como o autor, esta apenas adentrando neste mundo para mim misterioso.
Espero que tenham gostado deste artigo. 😉
Este programa permite detectar faces em um sistema de CFTV, permitindo a o posterior reconhecimento.
Roda em linux e Windows
import sys
import numpy as np
import cv2
# Pega o nome do arquivo a ser analisado
Arquivo = sys.argv[1]
load an color image in grayscale
img = cv2.imread(Arquivo)
print("Carregado:%s",Arquivo)
classificador = cv2.CascadeClassifier("/projetos/python/cv/face.xml")
imagemCinza = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
facesDetectadas = classificador.detectMultiScale(imagemCinza, scaleFactor=1.5, minSize=(100,100))
for (x,y,l, a ) in facesDetectadas:
print("Face:",x,y)
cv2.destroyAllWindows()
print("Finalizou")
Este exemplo simples é utilizado no sistema de identificação de CFTV de minha casa.
Informações pertinentes ao processamento de imagem
import sys import numpy as np
import cv2 import
MySQLdb def conexao():
Banco="banco"
User="usuario"
Passwrd="senha"
Host="ip"
resultado = 0
try:
resultado = MySQLdb.connect(db=Banco,user=User, passwd=Passwrd, host=Host)
except:
print("Erro ao conectar no Banco de dados")
resultado = -1
return resultado
def GravaReg(arquivo,x,y,a,h):
con = conexao()
cursor = con.cursor()
sql= "insert into eventoCam (arquivo,x,y,a,h) values ('%s',%d,%d,%d,%d)" %(arquivo,x,y,a,h)
print(sql)
try:
cursor.execute(sql)
con.commit()
print("Registro Gravado")
except MySQLdb as erro: print("Erro ao Executar SQL", erro)
#Pega o nome do arquivo a ser analisado
Arquivo = sys.argv[1]
# load an color image in grayscale
img = cv2.imread(Arquivo)
print("Carregado:%s",Arquivo)
classificador = cv2.CascadeClassifier("/projetos/python/cv/face.xml")
imagemCinza = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
facesDetectadas = classificador.detectMultiScale(imagemCinza, scaleFactor=1.5, minSize=(100,100)) for (x,y,l, a ) in facesDetectadas:
print("Face:",x,y)
GravaReg(Arquivo,x,y,l,a)
cv2.destroyAllWindows()
print("Finalizou")
Arquivo de script do Motion, bash para processamento de imagem
!/bin/bash#!/bin/bash
quebrar() {
local filepath="$1" local filename=$(basename "$filepath")
local ext=$(echo "$filename"| awk -F '.' '{ if (NF==2) {print $NF} else if ( NF>2) {print $(NF-1)"."$NF} }')
local dir=$(echo "$filepath" | awk -F '/' '{ print substr($0, 0 , length($0)-length($NF)-1) }')
echo -e "$dir""\t""$filename""\t""$ext"
}
ret="$(quebrar "$1")"
echo "$diretorio: " "$(echo "$ret" | cut -f1)"
diretorio="$(echo "$ret"|cut -f1)"
filename="$(echo "$ret"| cut -f2)"
somentefilename="$(echo "$filename"| cut -d. -f1)"
extensao="$(echo "$filename"| cut -d. -f2)"
novoarquivo="$(echo "$1"| cut -d. -f1)"
novoarquivo="$(echo "$novoarquivo"".mp4")"
echo "Desmembramento do arquivo"
echo $diretorio
echo $somentefilename
echo $extensao
echo $filenameecho $novoarquivo
ffmpeg -i $1 -c:v libx264 -preset ultrafast $novoarquivo
python /projetos/python/cv/load.py $novoarquivo
rm -f $1
Este link é uma adaptação de um artigo traduzido do Seguinte post:
Neste post, forneceremos instruções passo a passo para instalar o OpenCV 3 (C ++ e Python) no Ubuntu.
sudo apto-get update sudo apto-get upgrade
Remova qualquer instalação anterior da biblioteca x264
sudo apt-get remove x264 libx264-dev Nos iremos instalar as dependências agora!
sudo apt-get install build-essential checkinstall cmake pkg-config yasm sudo apt-get install git gfortran
sudo apt-get install libjpeg8-dev libjasper-dev libpng12-dev
# Se você esta usando o Ubuntu 14.04
sudo apt-get install libtiff5-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get install libxine2-dev libv4l-dev
#sudo apt-get install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get install libgstreamer*
sudo apt-get install qt5-default libgtk2.0-dev libtbb-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install libvorbis-dev libxvidcore-dev
sudo apt-get install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install x264 v4l-utils
# Dependências opcionais
sudo apt-get install libprotobuf-dev protobuf-compiler
sudo apt-get install libgoogle-glog-dev libgflags-dev
sudo apt-get install libgphoto2-dev libeigen3-dev libhdf5-dev doxygen julia
sudo apt-get install python-dev pip python-pip python3-dev python3-pip
pip install numpy
pip2 install numpy
pip3 install numpy
Nós iremos baixar os pacotes opencv e opencv_contrib de seus repositórios do GitHub.
apt install git
git clone https://github.com/opencv/opencv.git
cd opencv
cd..
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
cd..
cd opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D WITH_TBB=ON \
-D WITH_V4L=ON \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
-D BUILD_EXAMPLES=ON ..
# Encontre o numero de núcleos do seu computador
nproc
# Substitua o 4 pelo resultado obtido em nproc
make -j4
sudo make install
sudo sh -c 'echo "/usr/local/lib" >> /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
Vamos testar um aplicativo de remoção de olhos vermelhos escrito em OpenCV para testar nossas instalações em C ++ e Python.
Faça o download do RedEyeRemover.zip e extraia-o em uma pasta. ankara escort çankaya escort ankara escort çankaya escort escort ankara çankaya escort escort bayan çankaya istanbul rus escort eryaman escort escort bayan ankara ankara escort kızılay escort istanbul escort ankara escort ankara rus escort escort çankaya ankara escort bayan istanbul rus Escort atasehir Escort beylikduzu Escort Ankara Escort malatya Escort kuşadası Escort gaziantep Escort izmir Escort
Vá na pasta sample, compile e execute.
cd opencv/sample/cpp
cmake .
make
Os binários compilados irão estar disponíveis após a compilação.
Abra o vim, e edite o seguinte código:
vim ipython
# open ipython (execute esta linha no console) ipython
# import cv2 and print version (run following commands in ipython) importcv2
print cv2.__version__
# Se o OpenCV3 estiver instalado corretamente,
# na linha de comando aparecerá a saída 3.3.1
# Pressione CTRL+D para sair do ipython
Para executar o removedor de olhos vermelhos
python removeRedEyes.py
Sempre que você estiver executando scripts Python que usam o OpenCV, você deve ativar o ambiente virtual que criamos, usando o comando workon.
Este artigo é uma adaptação a partir do artigo original, contendo várias modificações, em caso de problemas, envie-nos um email