técnicas básicas para processamento de imagens e visão ... · técnicas básicas para...

18
Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação neste curso. Na primeira parte do curso, utilizaremos a linguagem C++ com bibliotecas OpenCV e Cekeikon. Cekeikon é uma biblioteca com as rotinas que eu implementei. Vocês não são obri - gados a utilizar Cekeikon. Porém, essa biblioteca contém várias funções que irão facilitar acompanhar este curso, assim como irá facilitar fazer “lição de casa” e “exercício programa”. Nesta parte do curso, vocês podem fazer “lições de casa” e “exercício programa” em C+ +/OpenCV/Cekeikon, C++/OpenCV ou Python/OpenCV. Na segunda parte, utilizaremos a linguagem Python com várias bibliotecas, entre elas Tensor - flow e Keras. 1. Programa mostra Instale a última versão da biblioteca Cekeikon para Windows ou Linux (Mint ou Ubuntu), conforme descrito em http://www.lps.usp.br/hae/software/index.html . Cekeikon para Win - dows contém dentro dela um compilador C++ e as bibliotecas OpenCV versões 2 e 3. Cekeikon para Linux contém dentro dela as bibliotecas OpenCV versões 2 e 3 (utiliza o com - pilador C++ do sistema). É importante que vocês acompanhem este curso testando os exem - plos no computador de vocês. Noto que Cekeikon (principalmente a versão para Windows) foi testada durante vários anos por muitos e muitos alunos. É improvável que contenha algum bug grave. Para testar o primeiro programa, abra um terminal (prompt de comando), vá para algum dire - tório (cd diretorio), e descompacte neste diretório as imagens do arquivo “basico.zip”. Depois, dê copy-paste do programa abaixo em algum editor de texto, salve o programa no diretório com o nome “mostra.cpp”. Para compilar “mostra.cpp”, execute um dos comandos abaixo: >compila mostra -cek >compila mostra -c Significa compile mostra.cpp e linke com bibliotecas OpenCV e Cekeikon. 1 2 3 4 5 6 7 8 9 // mostra.cpp: Mostra a imagem lenna.jpg na tela. // Apertando espaço, aparece a lista de comandos disponíveis. // mostra.cpp -grad2015 #include <cekeikon.h> int main () { Mat_ < COR > a ; le ( a , "lenna.jpg" ); mostra ( a ); } O programa deve abrir uma janela e mostrar a imagem “lenna.jpg”. Se você clicar na janela e apertar ESPAÇO, aparece uma lista de comandos que você pode dar: + - 0: Aumenta, diminui e volta o fator de zoom para 100%. E S D X: Move imagem para cima, esquerda, direita e baixo pixel a pixel. ... ESC: Fecha janela e sai. Q: Mantém janela aberta e sai. 1

Upload: others

Post on 22-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Técnicas básicas para Processamento de Imagens e Visão Computacional

Utilizaremos dois ambientes de programação neste curso.

Na primeira parte do curso, utilizaremos a linguagem C++ com bibliotecas OpenCV eCekeikon. Cekeikon é uma biblioteca com as rotinas que eu implementei. Vocês não são obri-gados a utilizar Cekeikon. Porém, essa biblioteca contém várias funções que irão facilitaracompanhar este curso, assim como irá facilitar fazer “lição de casa” e “exercício programa”.Nesta parte do curso, vocês podem fazer “lições de casa” e “exercício programa” em C++/OpenCV/Cekeikon, C++/OpenCV ou Python/OpenCV.

Na segunda parte, utilizaremos a linguagem Python com várias bibliotecas, entre elas Tensor-flow e Keras.

1. Programa mostra

Instale a última versão da biblioteca Cekeikon para Windows ou Linux (Mint ou Ubuntu),conforme descrito em http://www.lps.usp.br/hae/software/index.html. Cekeikon para Win-dows contém dentro dela um compilador C++ e as bibliotecas OpenCV versões 2 e 3.Cekeikon para Linux contém dentro dela as bibliotecas OpenCV versões 2 e 3 (utiliza o com-pilador C++ do sistema). É importante que vocês acompanhem este curso testando os exem-plos no computador de vocês. Noto que Cekeikon (principalmente a versão para Windows)foi testada durante vários anos por muitos e muitos alunos. É improvável que contenha algumbug grave.

Para testar o primeiro programa, abra um terminal (prompt de comando), vá para algum dire-tório (cd diretorio), e descompacte neste diretório as imagens do arquivo “basico.zip”. Depois,dê copy-paste do programa abaixo em algum editor de texto, salve o programa no diretóriocom o nome “mostra.cpp”. Para compilar “mostra.cpp”, execute um dos comandos abaixo:

>compila mostra -cek>compila mostra -c

Significa compile mostra.cpp e linke com bibliotecas OpenCV e Cekeikon.

123456789

// mostra.cpp: Mostra a imagem lenna.jpg na tela.// Apertando espaço, aparece a lista de comandos disponíveis.// mostra.cpp -grad2015#include <cekeikon.h>int main() { Mat_<COR> a; le(a,"lenna.jpg"); mostra(a);}

O programa deve abrir uma janela e mostrar a imagem “lenna.jpg”. Se você clicar na janela eapertar ESPAÇO, aparece uma lista de comandos que você pode dar:

+ - 0: Aumenta, diminui e volta o fator de zoom para 100%. E S D X: Move imagem para cima, esquerda, direita e baixo pixel a pixel. ... ESC: Fecha janela e sai. Q: Mantém janela aberta e sai.

1

Page 2: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Para sair do programa, aperte ESC.

A linha 4 pede para incluir os cabeçalhos das funções da biblioteca Cekeikon, que por sua vezvai incluir automaticamente os cabeçalhos da biblioteca OpenCV e vários cabeçalhos da bibli-oteca padrão de C++.

A linha 6 declara uma matriz onde cada elemento é capaz de armazenar uma COR, isto é 3bytes formado pelas bandas B, G e R. COR é o mesmo que estrutura Vec3b ou Vec<uchar, 3>do OpenCV (acho que fica mais fácil decorar COR do que Vec3b. Assim, Mat_<COR> con-segue armazenar dentro dele uma imagem colorida.

Na linha 7, a função “le” lê a imagem “lenna.jpg” e armazena na matriz a. A linha 8 mostra amatriz colorida a na tela.

O mesmo programa em versão OpenCV puro (sem usar Cekeikon):

123456789

//mostra_cv.cpp#include <opencv2/opencv.hpp>using namespace std;using namespace cv;int main() { Mat a=imread("lenna.jpg",1); imshow("janela",a); waitKey(0);}

Para compilar mostra_cv.cpp em Cekeikon, execute:>compila mostra_cv -ocv

Maioria dos programas em OpenCV puro trabalha com matriz sem tipo (linha 6). Como nãose conhece o tipo de matriz (se é colorida ou em níveis de cinzas), é necessário especificar du-rante a leitura em imread que se deseja ler a imagem “lenna.jpg” como uma matriz colorida(número 1).

A linha 7 mostra a matriz a numa janela chamada “janela” usando comando “imshow”. Apósimshow, é necessário pedir para mostrar a imagem até que tecle algo (waitKey(0)). Sem estecomando, nada será mostrado na tela.

2

Page 3: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

2. Programa inverte

Agora, vamos ler uma imagem binária, calcular a sua imagem negativa (onde preto e brancosão trocados) e imprimi-la. Usando biblioteca Cekeikon fica:

1234567891011

// inv_cek.cpp grad2015#include <cekeikon.h>int main(){ Mat_<GRY> a; le(a,"mickey_reduz.bmp"); for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) if (a(l,c)==0) a(l,c)=255; else a(l,c)=0; imp(a,"inv_cek.pgm");}

Compile este programa com:>compila inv_cek -cek

Na linha 4, Mat_<GRY> é uma matriz capaz de armazenar uma imagem em níveis de cinza(ou binária). Estou chamando de GRY uma variável 8 bits sem sinal, que outras bibliotecaschamam de uint8_t (C++), unsigned char (C), uchar (OpenCV), e BYTE (Microsoft).OpenCV não possui estrutura própria para armazenar imagens binárias. Estamos usando ima-gem em níveis de cinzas para armazenar imagem binária, onde preto é 0 e branco é 255.

Após a leitura da imagem na linha 5, a matriz a fica preenchida com os valores da imagemmickey_reduz.bmp: 0 representando preto e 255 representando branco.

A matriz a tem a.rows linhas e a.cols colunas. A numeração das linhas da imagem a vai de 0até a.rows-1, de cima para baixo. A numeração das colunas vai de 0 até a.cols-1, da esquerdapara direita.

mickey_reduz.bmp inv_cek.pgm

Figura 1: Calcular imagem negativa de uma imagem binária.

3

Page 4: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

É possível programar OpenCV/C++ “puro” com ou sem programação por template. Pareceque o mais comum é programar sem usar template. O mesmo programa, sem usar Cekeikon,mas usando programação por template, fica praticamente igual a programa Cekeikon.

//inv_ocv.cpp - usando template#include <opencv2/opencv.hpp>using namespace std;using namespace cv;int main(){ Mat_<unsigned char> a; a=imread("mickey_reduz.bmp",0); for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) if (a(l,c)==0) a(l,c)=255; else a(l,c)=0; imwrite("inv_ocv.pgm",a);}

Compile com o comando:>compila inv_ocv -ocv

O mesmo programa em OpenCV “puro”, sem usar “template”:

//inv_ocv2.cpp#include <opencv2/opencv.hpp>using namespace std;using namespace cv;int main(){ Mat a; a=imread("mickey_reduz.bmp",0); for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) if (a.at<uchar>(l,c)==0) a.at<uchar>(l,c)=255; else a.at<uchar>(l,c)=0; imwrite("inv_ocv.pgm",a);}

Como o compilador não conhece o tipo de matriz a, deve informar na leitura sequer ler a imagem como imagem em níveis de cinzas (0) ou colorida (1) (em ama-relo). De forma semelhante, é necessário informar o tipo de matriz a toda vez quea acessa (em amarelo).

4

Page 5: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

O programa abaixo é a solução em Python desse mesmo problema. Repare como a sintaxe épraticamente idêntica.

123456789101112

# inverte.pyimport cv2a = cv2.imread('mickey_reduz.bmp',0)

for l in range(a.shape[0]): for c in range(a.shape[1]): if a[l,c]==0: a[l,c]=255 else: a[l,c]=0 cv2.imwrite('inv_cek_py.png',a)

Para rodar este programa:windows> python inverte.pylinux$ python3 inverte.py

Uma outra solução para este problema é acessar a matriz a usando um único índice (em vezde linha e coluna). Aumentando o índice, a imagem é percorrida em ordem “raster”, isto é, daesquerda para direita e de cima para baixo.

12345678910

//inv_1d2.cpp: Usando indice unidimensional#include <cekeikon.h>int main(){ Mat_<GRY> a; le(a,"mickey_reduz.bmp"); for (unsigned i=0; i<a.total(); i++) if (a(i)==0) a(i)=255; else a(i)=0; imp(a,"inv_1d.bmp");}

Na linha 6, a.total() indica o número total de elementos da matriz.

Para ilustrar o acesso aos pixels, escrevemos explicitamente o cálculo da imagem inversa den-tro de um ou dois loops. Porém, na verdade, todos os comandos dentro dos loops podem sersubstituídos por um único comando que subtrai de 255 cada um dos elementos da matriz:

a = 255 - a;

5

Page 6: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Lição de casa: Escreva um programa que elimina o ruído branco nas regiões pretas da ima-gem mickey.bmp.

mickey.bmp eliminaruido.bmpFigura 2: Elimina ruído.

3. Programa borda

Agora, vamos escrever um programa que detecta as bordas da imagem mickey_reduz.bmp(imagem obtida eliminando ruído e diminuindo resolução de “mickey.bmp”). Para detectar asbordas, podemos usar a lógica mostrada na figura 3b: Pixel A é borda se A≠B ou A≠C.

(a) borda.bmp

A CB

(b) Pixel A é borda seA≠B ou A≠C

Figura 3: Detecta bordas.

6

Page 7: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

A solução está no programa abaixo:

1234567891011121314

//borda.cpp#include <cekeikon.h>int main() { Mat_<GRY> a; le(a,"mickey_reduz.bmp"); Mat_<GRY> b(a.rows,a.cols); for (int l=0; l<a.rows-1; l++) for (int c=0; c<a.cols-1; c++) if (a(l,c)!=a(l,c+1) || a(l,c)!=a(l+1,c)) b(l,c)=0; else b(l,c)=255; imp(b,"borda.bmp");}

Aqui, precisamos trabalhar com duas imagens: uma imagem de entrada a e uma imagem desaída b. A linha 6 cria a imagem b com mesmas dimensões da imagem a. Note que se escre-vêssemos:

Mat_<GRY> b; //cria imagem b nula (0 linhas e 0 colunas)

estaríamos criando uma matriz b vazia, com 0 linhas e 0 colunas. É possível alocar espaçopara matriz vazia b usando depois o comando:

b.resize(rows,cols);

Isto alocaria rows*cols elementos para a matriz b. Também é possível criar a matriz e alocarespaço ao mesmo tempo:

Mat_<GRY> b(rows,cols); //cria imagem b com rows*cols pixels

Uma terceira possibilidade é criar a matriz, alocar espaço e preencher todos os elementos comum determinado valor:

Mat_<GRY> b(rows,cols,255); //cria imagem b com rows*cols pixels //e preenche com 255.

Isto funciona sempre, exceto quando quer preencer a matriz com zeros, pois “0” tem signifi-cado especial (apontador nulo) em C++:

Mat_<GRY> b(rows,cols,0); //Dá erro. Não sabe se 0 é número ou endereço.

Para contornar isto, é possível escrever:

Mat_<GRY> b(rows,cols,GRY(0)); //cria imagem b com rows*cols pixels //e preenche com 0.

7

Page 8: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

4. Inverter uma imagem colorida

Agora, vamos escrever um programa que inverte as cores de uma imagem colorida, para mos-trar como acessar os pixels de uma imagem colorida.

12345678910111213

//invertec.cpp#include <cekeikon.h>int main() { Mat_<COR> a; le(a,"lenna.jpg"); for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) { //BGR a(l,c)[0] = 255-a(l,c)[0]; // blue a(l,c)[1] = 255-a(l,c)[1]; // green a(l,c)[2] = 255-a(l,c)[2]; // red } imp(a,"invertec.jpg");}

As linhas 8-10 mostram como acessar cada uma das bandas de um pixel (l,c) da matriz a.OpenCV armazena as cores na ordem BGR, contrária à grande maioria das outras bibliotecasque trabalham com ordem RGB.

Figura 4: Entrada e saída do programa invertec.cpp.

Como antes, este programa acessa explicitamente os pixels da imagem só para servir deexemplo. Todos os comandos entre as linhas 6-11 poderiam ser substituídos por um único co-mando:

a = 255 - a;

8

Page 9: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

5. Detectar pixels com coloração amarela

Agora, vamos escrever um programa que detecta os pixels com coloração amarela e pinta-osde branco. Aqui, não podemos comparar o valor do pixel com um único valor. Em vez disso,precisamos delimitar um região que representa pixels com coloração amarela no cubo de co-res RGB. O programa abaixo define (20,200,200) como a cor amarela típica e delimita umaesfera em torno desse ponto. Pinta de branco todos os pixels dentro dessa esfera (cuja distân-cia euclidiana à cor típica é menor que 70).

123456789

10111213141516

//elefante_am.cpp grad-2018#include <cekeikon.h>

int main() { Mat_<COR> a; le(a,"elefante.jpg"); Mat_<COR> b; COR amarelo(20,200,200); //b=a; // Esta errado. b e a sao dois nomes para mesma imagem. b=a.clone(); // OU a.copyTo(b); Aqui temos duas imagens diferentes. for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) if (distancia(amarelo,a(l,c))<70) b(l,c)=COR(255,255,255); imp(b,"elefante_am.png");}

Preste atenção nas linhas 9 e 10. O comando:b=a;

não copia a matriz a para b, mas cria dois nomes para a mesma matriz.

Se quiser criar duas cópias independentes de matriz, deve-se dar comando:b=a.clone(); OUa.copyTo(b);

Isto é assim tanto em C++ como em Python.

9

a

bmatriz

a

bmatriz

matriz

Page 10: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

A função distância na linha 13 calcula a distância euclidiana entre duas cores. Essa funçãoestá incluída na biblioteca Cekeikon. Se fosse escrevê-la, seria:

//A funcao abaixo ja esta incluida na biblioteca Cekeikonint distancia(COR a, COR b) { return cvRound( sqrt( double(elev2(a[0]-b[0])+ elev2(a[1]-b[1])+ elev2(a[2]-b[2])) ) );}

A saída do programa está na figura 5.

elefante.jpg elefante_am.png

Figura 5: Detecção de pixels de coloração amarela.

O programa “kcek projcor” projeta as cores de uma imagem nos planos RG, RB e GB.>kcek projcor elefante.jpg rg.png rb.png gb.png

Fazendo isso, obtém as imagens da figura 6. Tanto na imagem RB como na imagem GB, ficaclaro que pixels com coloração amarela podem ser identificadas facilmente, pois estão separa-das das demais cores.

rg.png rb.png gb.png

Figura 6: Projeção das cores de elefante.jpg nos planos RG, RB e GB.

10

Page 11: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Lição de casa: Quebre uma imagem colorida em componentes RGB, como mostra a figura 7.

Figura 7: Quebra da imagem “flor.jpg” nas componentes R, G e B.

11

Page 12: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

6. Conversão de imagem colorida para níveis de cinzas

Como converter uma imagem colorida para níveis de cinza? A primeira ideia é tirar média dasbandas RGB:

1) Y = (R+G+B)/3;

Só que o olho humano é mais sensível à banda verde e menos sensível à banda azul. Ajustan-do os pesos para corresponder à percepção humana, temos:

2) Y = 0.299*R + 0.587*G + 0.114*B;

O programa abaixo testa se há alguma diferença entre usar a fórmula (1) e (2).

123456789

1011121314151617

// rgb2y.cpp - 2016#include <cekeikon.h>int main() { Mat_<COR> a; le(a,"mandrill.jpg"); Mat_<GRY> gcorreto(a.size()); Mat_<GRY> gmedia(a.size()); Mat_<GRY> gopencv; for (unsigned i=0; i<a.total(); i++) { gcorreto(i) = round( 0.299*a(i)[2] + 0.587*a(i)[1] + 0.114*a(i)[0] ); gmedia(i) = round( (a(i)[0]+a(i)[1]+a(i)[2])/3.0 ); } cvtColor(a,gopencv,CV_BGR2GRAY); imp(gcorreto,"gcorreto.pgm"); imp(gmedia,"gmedia.pgm"); imp(gopencv,"gopencv.pgm");}

A imagem colorida mandrill.jpg é convertida para níveis de cinza usando 3 métodos:1) gmedia usa a fórmula (1).2) gcorreto usa a fórmula (2).3) gopencv usa a função cvtColor com opção CV_BGR2GRAY para fazer a conversão.

As imagens obtidas pelas fórmulas (1) e (2) estão na figura 8. É difícil enxergar alguma dife-rença entre elas.

Agora, vamos medir a diferença entre essas imagens e a imagem obtida usando a função cvt-Color do OpenCV (linha 13 do código). O programa “kcek distg” do Cekeikon calcula a dife-rença entre duas imagens. MAE significa “mean absolute error”. A maior média da diferença absoluta entre duas imagens em níveis de cinza é 255 (diferença entre uma imagem completa-mente branca e outra completamente preta). Esta diferença foi dividida por 255 e expressa como porcentagem. Os resultados foram:

>kcek distg gopencv.pgm gcorreto.pgmMAE (max=100%)...................: 0.00%

>kcek distg gopencv.pgm gmedia.pgmMAE (max=100%)...................: 2.39%

12

Page 13: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Isto é, a função cvtColor do OpenCV usa exatamente a fórmula (2) para converter imagem colorida para níveis de cinzas.

a) Imagem colorida b) Usando cvtColor de OpenCV

(c) Calculando média (equação 1) (d) Usando pesos perceptuais (equação 2)Figura 8: Conversão de imagem colorida para níveis de cinzas usando diferentes métodos.

13

Page 14: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

7. Sistemas de cores

7.1 CMY

As cores podem ser representadas em diferentes sistemas de cores. Já vimos o sistema RGB,que é um sistema aditivo (representa soma de luzes de cores básicas). As luzes de cores R, Ge B vão se somando em diferentes proporções para formar diferentes cores. Se somar todas asluzes RGB resulta cor branca e se não colocar nenhuma luz resulta cor preta (figura 9).

Figura 9: Sistema RGB é aditivo (fonte: Wikipedia).

Já os sistemas CMY (cyan, magenta, yellow) e CMYK (CMY + black) são subtrativos, usadopara tintas. Se misturarmos todas as tintas CMY obtemos preto enquanto que se não jogarmosnenhuma tinta no papel temos branco (figura 10a). O sistema CMYK acrescenta a tinta preta,pois misturando tintas CMY normalmente não obtém preto perfeito e por que a tinta pretapermite economizar tintas coloridas.

(a) (b)Figura 10: (a) Sistema CMY e CMYK são subtrativos. (b) Cubo de cores RGB e CMY (fonte:Wikipedia).

Veja na figura 10b que qualquer cor dentro do cubo de cores pode ser especificada fornecendoas coordenadas RGB a partir do centro do sistema de coordenadas preto [0,0,0] ou fornecendoas coordenadas CMY a partir do centro do sistema de coordenadas branco [255,255,255]. Porexemplo, a cor RGB=[100, 0, 0] seria CMY=[155, 255, 255].

14

Page 15: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Exercício: Converta a cor RGB=[50,100,150] para sistema CMY.

7.2 HSI ou HSL

Existem muitos outros sistemas de cores. Sistema de cores HSL, HLS ou HSI representa umacor através dos atributos hue, saturation e lightness. Hue (coloração) é um ângulo, onde 0° re-presenta vermelho, 120° representa verde e 240° representa azul. Saturação indica se a cor épura (saturada, na borda do bicone da figura 11) ou tende para tonalidades de cinza (insatura-da, perto do bicone da figura 11). No eixo central do bicone da figura 11 temos as cores com-pletamente insaturadas, que correspondem às tonalidades de cinza. Por fim, lightness indicaaproximadamente a cor convertida para níveis de cinza.

Figura 11: Sistema de cores HSL.

15

Page 16: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

O programa abaixo a imagem colorida mandrill.jpg para sistema HSL e imprime as 3 bandasobtidas. A rotina cvtColor faz esta conversão, com a opção CV_BGR2HLS. Em OpenCV, abanda H vai de 0 a 180 (quando armazenada numa imagem 8 bits sem sinal), representando 0a 360 graus. Os componentes L e S vão de 0 a 255.

// separa pos-2012#include <cekeikon.h>int main(){ Mat_<COR> a; le(a,"mandrill.jpg"); cvtColor(a, a, CV_BGR2HLS); // a(l,c)[0] = hue // a(l,c)[1] = lightness // a(l,c)[2] = saturation Mat_<GRY> h(a.rows,a.cols); //entre 0 e 180 Mat_<GRY> s(a.rows,a.cols); Mat_<GRY> i(a.rows,a.cols); for (int l=0; l<a.rows; l++) for (int c=0; c<a.cols; c++) { h(l,c)=a(l,c)[0]; s(l,c)=a(l,c)[2]; i(l,c)=a(l,c)[1]; } imp(h,"hue.tga"); imp(s,"sat.tga"); imp(i,"int.tga");}

16

Page 17: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

mandrill.jpg man-hue.jpg

man-sat.jpg man-int.jpg

Figura 12: Imagem mandrill convertido para sistema HSI (ou HSL).

Veja que dentro do nariz do macaco, há transição súbita de preto para cinza claro. Isto aconte-ce pois hue é ângulo e vermelho é representado por 0° (valor 0) ou 360° (valor 180). Uma pe-quena mudança de tonalidade de vermelho pode fazer hue mudar de valor próximo de zeropara valor próximo de 180.

Na banda saturação, as cores puras (amarelo do olho, vermelho do nariz) estão representadasem cinza clara. As cores tendendo para branco, cinza ou preto (bochecha azul-celeste, peloverde-escuro e barba branca) são representadas em cinza escuro.

Por fim, intensidade é praticamente a imagem colorida convertida para níveis de cinzas.

17

Page 18: Técnicas básicas para Processamento de Imagens e Visão ... · Técnicas básicas para Processamento de Imagens e Visão Computacional Utilizaremos dois ambientes de programação

Exercício: Considere sistema HSI onde H pode ir de 0 a 180 (respectivamente representando0 graus e 360 graus como no OpenCV). Que cores representam as seguintes coordenadas HSI:

H=60 S=0 I=255 representa a cor ____________H=0 S=0 I=128 representa a cor ____________H=0 S=255 I=128 representa a cor ____________H=120 S=255 I=128 representa a cor ____________

18