Você está na página 1de 125

Engenharia

Análise e Processamento de Imagens de Rochas


Imagens, Pré-Processamento/Filtros,
Segmentação/Binarização,
Caracterização/Autocorrelação/Porosidade

Prof. André Duarte Bueno


<andreduartebueno@gmail.com>

11 de junho de 2018
Colocação do Problema:
• A produção de óleo de um reservatório de petróleo só é economicamente viável se a quantidade
de óleo disponível a produção for grande o suficiente para cobrir as despesas e garantir um
lucro mínimo a companhia. Em muitos casos a quantidade de óleo é grande, mas as carac-
terísticas do reservatório tornam a produção muito custosa; entre estes casos podemos citar
reservatórios com óleos muito pesados, reservatórios com baixa porosidade, reservatórios com
baixa permeabilidade. Para avaliar a capacidade de produção são necessários estudos sobre o
reservatório. Esta caracterização pode ser feita de diversas formas, como exemplo, testes de
pressão, perfilagem, sísmica, etc. Mas a mais efetiva e direta é a análise em laboratório de
amostras do reservatório.

• Sendo assim, para uma melhor caracterização das rochas reservatório, são furados poços e
obtidas amostras que são levadas para os laboratórios do CENPES (e ou do LENEP). Estas
amostras costumam ser cilíndricas (de alto custo) ou amostras de calha (amostras de baixo
custo obtidas durante a perfuração).
• Além dos tradicionais ensaios de laboratório (porosidade, permeabilidade,...), são preparadas
lâminas de amostras, que serão processadas usando um “Laboratório Virtual de Petrofísica”
(um software como o Imago, o SAIL o LVP).

• A ideia é usar o software para estimar a porosidade, a função distrituição de tamanho de


poros, a função autocorrelação, permeabilidade, entre outras características/propriedades das
rochas.

• Uma grande vantagem do laboratório virtual é que uma imagem pode ser usada em milhares
de análises, enquanto alguns ensaios (como porosimetria a mercúrio) são destrutivos. Outra
vantagem é poder visualizar detalhes internos dos poros (sua física). Veremos a seguir a
sequência desta metodologia.
Figura 1: Sequência do processamento de imagens de rochas reservatório
Figura 2: Sequência do processamento de imagens de rochas reservatório - comentada
Figura 3: Sequência do processamento de imagens de rochas reservatório - preparação amostras
Figura 4: Sequência do processamento de imagens de rochas reservatório - corte de amostras 1
Figura 5: Sequência do processamento de imagens de rochas reservatório - corte de amostras 2
Figura 6: Sequência do processamento de imagens de rochas reservatório - corte de amostras 3
Figura 7: Sequência do processamento de imagens de rochas reservatório - corte de amostras 4
Figura 8: Sequência do processamento de imagens de rochas reservatório - amostras cenpes
Figura 9: Sequência do processamento de imagens de rochas reservatório - Politriz
Figura 10: Sequência do processamento de imagens de rochas reservatório - corte amostras e
preparação lâminas para polimento
Figura 12: Sequência do processamento de imagens de rochas reservatório - corte amostras e
preparação bolachas para polimento
Figura 13: Sequência do processamento de imagens de rochas reservatório - equipamentos para
polimento de amostras
Figura 14: Sequência do processamento de imagens de rochas reservatório - Lâmina e Amostra do
tipo bolacha já polidas com politriz
Figura 15: Sequência do processamento de imagens de rochas reservatório - Laboratório Petrografia
usado para adquirir imagens das amostras usando microscópio ótico
Figura 16: Sequência do processamento de imagens de rochas reservatório - Imagem de rocha Berea
Figura 17: Sequência do processamento de imagens de rochas reservatório - Pré-processamento
usando filtros do software livre Gimp
Figura 18: Sequência do processamento de imagens de rochas reservatório - Segmentação, separação
dos poros e sítios usando Gimp
Figura 19: Sequência do processamento de imagens de rochas reservatório - Imagens 3D Recon-
struídas, prontas para simulação
Figura 20: Sequência do processamento de imagens de rochas reservatório - microtomografo do
CENPES, obtem imagem em 3D
Figura 21: Sequência do processamento de imagens de rochas reservatório - Amostras simu-
ladas(saturações, configurações equilíbrio, água "azul escuro" e óleo "verde")
Figura 22: Sequência do processamento de imagens de rochas reservatório - Software ANAIMP
Figura 23: Sequência do processamento de imagens de rochas reservatório - Software Imago
Figura 24: Sequência do processamento de imagens de rochas reservatório - Software SAIL
Figura 25: Sequência do processamento de imagens de rochas reservatório - Software LVP
Figura 26: Saídas geradas pelo programa cujo código em C++ esta apresentado a seguir
Figura 27: Saídas geradas pelo programa: Imagem original a esquerda, filtrada com passa baixa a
direita e binarizada no centro. Histograma de cores e função autocorrelação.
Especificação do Software
• Desenvolver um sistema de software que realize processamentos básicos de imagens de rochas
reservatório de petróleo.

• O sistema deve ser multiplataforma (Windows, GNU/Linux), deve ter como base bibliotecas
GPL, usar a linguagem C++ e ter interface simplificada - em modo texto.

• Os gráficos devem ser gerados utilizando programas externos como


gnuplot , scilab ou octave.

• As imagens devem ser visualizadas em programas externos como o


display (ex: display nomeImagem.pgm).
O sistema deve poder trabalhar com conceitos como:

• Imagens bidimensionais.

• Determinação do histograma de uma imagem bidimensional em tons de cinza.

• Binarização de imagens, transformando imagens em tons de cinza em imagens preto-branco,


a partir de nível de corte definido pelo usuário.

• Caracterização de imagens (calculo da porosidade).

• Caracterização de imagens (calculo da função autocorrelação).


Uso de shared_ptr e make_shared
• Vimos o uso de ponteiros da forma:

– CImagem* imgFiltrada = nullptr;


– imgFiltrada= new CImagem(*imagemOriginal);
– imgFiltrada->MétodosDaClasse();
– CImagem* copiaimgFiltrada = imgFiltrada;
∗ daqui para frente posso usar imgFiltrada ou copiaimgFiltrada; o problema é que
se o objeto apontado é deletado os ponteiros apontam para algo que não existe mais.
∗ Na prática usamos algo como delete imgFiltrada; imgFiltrada = nullptr; //
ptrImagem esta ok
· o problema é que copiaimgFiltrada não sabe que o objeto foi destruído, e seu
uso gera um bug.
• C++11 adicionou um novo tipo de ponteiro, o mesmo pode ser compartilhado, ou seja, pode-
mos ter várias cópias dele. O uso de delete ptr; só irá realmente destruir o objeto se o
ponteiro que aponta para o objeto for o último; Ou seja, somente o último delete irá realmente
deletar o objeto. Elimina-se assim o problema descrito acima, o que facilita o gerenciamento
de ponteiros. Veja a seguir a forma de uso:

• // cria ponteiro para CImagem

– std::shared_ptr < CImagem > imgFiltrada;

• // cria uma imagem e retorna ponteiro para ela do tipo shared_ptr

– make_shared < CImagem >(*imagemOriginal) ;

• Abaixo cria o ponteiro imgFiltrada que aponta para a imagem criada com make_shared.

– shared_ptr <CImagem> imgFiltrada = make_shared < CImagem >(*imagemOriginal);


Classe CImagem
• Em termos computacionais, uma imagem 2D é uma matriz 2D de números inteiros, com
dimensões nx X ny, sendo nx o número de píxeis na direção x e ny o número de píxeis na
direção y (Figura 28).

• Uma imagem também tem um atributo numeroCores. Se a imagem for binária os valores de
cor, armazenados na matriz, são 0 - preto e 1 - branco. Se a imagem for em tons de cinza
os valores de cor são 0 - preto e 255 - branco, valores entre 0 e 255 representam os diferentes
níveis de cinza.

• Uma classe de manipulação de imagens costuma incluir métodos para leitura/gravação de


imagens nos formatos pbm (preto/branco) e pgm (tons de cinza), veja Tabela 1.
Tabela 1: Formatos de arquivos pbm (imagem binária); pgm (imagem tons de cinza); e cor (autcor-
relação).
P1 P2
ny nx ny nx numeroCores
1 0 0 ... 250 220 100
0 0 1 ... 125 50 0

c[0] c[1] c[2] ... c[u-1]


Figura 28: Imagem tons de cinza (a), histograma(b) e binarizada (c)
Classe CHistograma
• O histograma de uma imagem digital com níveis de intensidade (i) no intervalo [0, L-1] é
uma função discreta (um vetor) dada por: histograma[i] = n, onde i é o valor de intensidade
(ou tom de cinza) e n é o número de pixeis da imagem com intensidade i (número de píxeis
com aquele tom de cinza), veja Figura 28.

• Note que o histograma de uma imagem pode ser representado como um vetor com dimensão
numeroCores da imagem, e que armazena em cada posição i, o número total de píxeis da
intensidade (cor) i.
Classe CBinarizacao
• Binarização é um processo de segmentação que separa o objeto de interesse do fundo, consiste
na conversão de uma imagem em tons de cinza em uma imagem binária, onde os pixeis podem
assumir apenas dois valores, 0 ou 1 (preto ou branco). O valor do histograma que melhor
separa a imagem em objeto/fundo chama-se threshold (Th). A imagem binária é determinada
pela equação 1.
(
1, se Im[x][y] > Th 0 ≤ x < nx
Imbin[x][y] = (1)
0, se Im[x][y] ≤ Th 0 ≤ y < ny

• Veja na imagem 28(c) uma imagem binarizada.


Classe CPorosidade
• Uma propriedade importante da rocha reservatório é sua porosidade, a mesma é dada pela
razão do volume de vazios, Vv pelo volume total da amostra
Vv
φ= (2)
Vt

• A porosidade pode ser calculada usando-se imagens binarizadas. Basta calcular a relação da
área de poros (píxeis pretos) pela área total da imagem (nx.ny).
Classe CAutocorrelacao
• Outra propriedade importante de uma imagem Im[x][y] é sua função autocorrelação c[u],
dada pela equação abaixo.

• Note que, para cada valor de u (deslocamento da imagem), determina-se se Im[x][y] ≡ Im[x+
u][y]. Caso verdadeiro, acrescenta-se 1 ao valor de c[u].

( AutoCorrelacao[u] = c[u] =
Pnx Pny 1, se Im[x][y] ≡ Im[x + u][y] 0 ≤ x < nx (3)
x=0 y=0
0, se Im[x][y] 6= Im[x + u][y] 0 ≤ y < ny

• Note que para deslocamento u = 0, o valor de autocorrelação é a porosidade.

• Veja exemplo de função autocorrelação na Figura 29.


Figura 29: Função autocorrelação
Classe CMascara
• Uma máscara é uma representação, uma amostragem, do núcleo de um filtro. Pode ser visto
como uma pequena sub-imagem. Apresenta-se na Figura 30, uma máscara 3x3 com seus
respectivos pesos.

• Máscara é uma matriz discreta com os elementos do kernel ou núcleo de um filtro.

• O tamanho da mascara é a dimensão da matriz, se for 3 a matriz gerada é 3x3; É sempre


ímpar!

• O peso é o somatório dos elementos da máscara. Se o somatório for 0 o peso é 1.

• Os raios da máscara são dados por: RaioX = (nx − 1)/2 e RaioY = (ny − 1)/2.
Classe CFEspacial
• Go(img) e o operator(img) implementam o cálculo do filtro espacial em sí; Ou seja, realizam a
convolução do núcleo ou kernel do filtro G(x,y) com a imagem I(x,y). No cálculo da convolução
o novo valor de intensidade do pixel I(x,y) é função da intensidade de seus vizinhos e dos valores
do kernel G(x,y); no mundo discreto o kernel é representado por uma máscara(CMascara). Ou
seja, o novo valor do pixel central é calculado multiplicando-se os elementos da máscara pelos
píxeis da imagem, elemento a elemento; soma-se o produto e dividi-se pelo peso da máscara.
Para cada píxel [i][j] da imagem e píxel [k][l] da máscara realiza-se a operação:
P P
img[i][j] = k l masc[k][l] • img[i + k − RaioX][j + l − RaioY ]

• As classes herdeiras de CFEspacial preenchem os dados da máscara, com os elementos definidos


abaixo.
Figura 30: Procedimento filtragem
• ( ) CFEPassaBaixa, máscara do filtro passa baixa G(x,y)= (peso = 9)

+1 +1 +1
+1 +1 +1
+1 +1 +1

• • ( ) CFEPassaAlta, máscara do filtro passa alta G(x,y)= (peso = 1)

-1 -1 -1
-1 +9 -1
-1 -1 -1

• ( ) CFELaplaciano, máscara do filtro laplaciano G(x,y)= (peso = 1)

+0 -1 +0
-1 +4 -1
+0 -1 +0
1 − x²−y²
• ( ) CFEGaussiano, máscara do filtro gaussiano G(x, y) = 2πσ e
2σ² (peso = somatório valores)
Figura 31: Filtro gaussiano
Questões:
Questão 1 (peso 2):
• A porosidade de uma rocha reservatório é dada pela razão do volume de vazios, Vv pelo volume
total da amostra Vt, φ = VVvt . Você precisa implementar o cálculo da porosidade.
Questão 2 (peso 4):
• Monte uma classe CImagem, completa.

• Uma classe de manipulação de imagens costuma incluir métodos para leitura/gravação de


imagens nos formatos pbm (preto/branco) e pgm (tons de cinza), veja Tabela 1 e Figura 28. O
método Visualizar() deve mostrar a imagem na tela usando o programa externo display.

Questão 2 (peso 4):


• Monte uma classe CHistograma, completa. A mesma deve ter uma sobrecarga para o oper-
ador(), da forma vector<double> operator(....); que recebe como parâmetro, por pon-
teiro uma CImagem, e a seguir determina e retorna o histograma da imagem.

• PONTO EXTRA: Criar, dentro da classe CHistograma, um método Visualizar() que


possibilite a visualização do histograma utilizando programa externo (como o gnuplot). Con-
sidere que a classe CGnuplot esta disponível, e que um gráfico linear pode ser construído
utilizando-se CGnuplot("lines"), e um gráfico de um <vector> pode ser plotado com o
método PlotVector(vector<double> v,string titulo).

Questão 2 (peso 4):


• Monte uma classe CBinarizacao, completa, inclui um método Binarizar. O mesmo deve
receber uma imagem e o valor de threshold (valor de corte - constante). A seguir, dentro de
Binarizar, você deve usar o threshold fornecido para obter e retornar a imagem binária.

Questão 2 (peso 4):


• Considerando o escopo e especificação do problema, criar classe CAutoCorrelacao, completa.

• Contrutores (default, sobrecarregado, de cópia) e destrutor.

• Definição e leitura do valor máximo de deslocamento u.

• Implementar sobrecarga operador[]. Dado u retorna c[u].

• Implementar sobrecarga operador(). Recebe uma imagem e calcula sua função autocorrelação.
• Implementar método visualizar. Vizualiza o gráfico de autocorrelação usando o gnuplot.

• Sobrecarregar os operadores <‌< e >‌> para ler e salvar dados vetor autocorrelação em disco.

Questão 3 (peso 4):


• Monte uma função main() que realiza os seguintes processamentos:

1. abre a imagem da rocha reservatório do disco.

2. determina o histograma da imagem e mostra na tela.

3. pede para o usuário o nível de corte (threshold).

4. realiza a binarização da imagem (criar CBinarizacao usando ponteiro).

5. salva imagem e mostra na tela a imagem original e binarizada.

6. determina e mostra para o usuário a porosidade da imagem.


7. calcula a função autocorrelação (usar ponteiro para CAutocorrelacao).

8. plotar a função autocorrelação.

9. extra: usa filtros.


Solução - Análise
Considere que este sistema tem como base o diagrama de classes ilustrado na Figura 32.
Figura 32: Diagrama de classes sem filtros
Figura 33: Diagrama de classes incluindo primeiros filtros
Solução - Algoritmos e Programas

Figura 34: Diagrama da classe CBinarizacao


Listing 1: CBinarizacao.h.
1
2 # ifndef CBINARIZACAO_H
3 # define CBINARIZACAO_H
4
5 # include < iostream >
6 # include < memory >
7
8 class CImagem ; // Usa imagem , preciso informar que existe
9
10 /* *@brief Classe utilizada para binarização de imagens . */
11 class CBinarizacao
12 {
13 private :
14 int th = 0; // < Valor de corte , thresholding ou th .
15
16 public :
17 CBinarizacao () = default ; // < Construtor default .
18 ~ CBinarizacao () = default ; // < Destrutor default .
19 // / Realiza binarizacao da imagem .
20 std :: shared_ptr < CImagem >& Binarizar ( std :: shared_ptr < CImagem >& img , const int _th ) ;
21 // / Sobrecarga operador () , realiza binarização da imagem .
22 std :: shared_ptr < CImagem >& operator () ( std :: shared_ptr < CImagem >& img ) { return Binarizar ( img ,
th ) ; };
23
24 void Th ( int _th ) { th = _th ; } // < Seta th .
25 int Th () const { return th ; } // < Le th .
26
27 // / Mostra thresholding na tela ou salva em disco .
28 friend std :: ostream & operator < <( std :: ostream & os , const CBinarizacao & obj ) {
29 return os << obj . th ;
30 }
31 // / Lê thresholding de istream ( cin ) ou de arquivo em disco .
32 friend std :: istream & operator > >( std :: istream & in , CBinarizacao & obj ) {
33 return in >> obj . th ;
34 }
35 };
36 # endif
Listing 2: CBinarizacao.cpp.
1 # include " CBinarizacao . h "
2 # include " CImagem . h "
3
4 using namespace std ;
5
6 // Realiza a binarização usando valor de corte
7 shared_ptr < CImagem >& CBinarizacao :: Binarizar ( shared_ptr < CImagem >& img , const int _th ) {
8 if ( img - > Binarizada () ) // Se já é binaria sai .
9 return img ;
10
11 th = _th ; // Percorre imagem
12 for ( int i = 0; i < img - > nx ; i ++)
13 for ( int j = 0; j < img - > ny ; j ++) {
14 if ( img - > pm [ i ][ j ] <= th ) // Se menor ou igual a th
15 img - > pm [ i ][ j ] = 1; // pixel i , j assume valor 1
16 else
17 img - > pm [ i ][ j ] = 0; // senao , i , j assume valor 0
18 }
19 img - > Formato ( EFormatoImagem :: pbm ) ; // informa que foi binarizada
20 return img ;
21 }
Figura 35: Diagrama da classe CHistograma
Listing 3: CHistograma.h.
1 # ifndef CHISTOGRAMA_H
2 # define CHISTOGRAMA_H
3
4 # include < vector >
5 # include < string >
6 # include < memory >
7
8 # include " CGnuplot . h "
9
10 class CImagem ;
11
12 /* *@brief Classe utilizada para cálculo do histograma de imagens em tons de cinza . */
13 // Para imagens pgm a cor máxima é NCores , ex : 0 - >255 NCores =255
14 class CHistograma
15 {
16 std :: vector < double > hist ; // < Vetor com valores do histograma .
17 bool normalizado = false ; // < Indica se foi ou não normalizado ( area =1) .
18 std :: unique_ptr < CGnuplot > gnuplot ; // < Gráfico do histograma .
19
20 public :
21 CHistograma () = default ; // < Construtor default .
22 // / Construtor de copia .
23 CHistograma ( const CHistograma & obj ) : hist ( obj . hist ) , normalizado ( obj . normalizado ) { };
24 ~ CHistograma () = default ; // < Destrutor default .
25 void Visualizar () ; // < Mostra o histograma usando classe CGnuplot .
26 void Normalizar () ; // < Normaliza o histograma .
27 inline void Acumular () ; // < Calcula histograma acumulado .
28 bool Salvar ( const std :: string nomeArquivo ) const ; // < Salva histograma em disco
29 bool Normalizado () { return normalizado ; } // < retorna informação se esta normalizado
30 // / Calcula o histograma da imagem .
31 std :: vector < double > CalcularHistograma ( std :: shared_ptr < CImagem >& img ) { return (* this ) ( img )
; };
32 // Sobrecarga operadores
33 // / Mostra histograma na tela ou salva em disco
34 friend std :: ostream & operator < <( std :: ostream & os , const CHistograma & obj ) ;
35 // / Lê histograma de istream ( cin ) ou de arquivo em disco
36 friend std :: istream & operator > >( std :: istream & in , CHistograma & obj ) ;
37 // / Sobrecarga operador () , realiza calculo do histograma da imagem . A classe se comporta
como uma funcao .
38 std :: vector < double > operator () ( std :: shared_ptr < CImagem >& img ) ;
39 // / Sobrecarga operador [] , a classe se comporta como um vetor .
40 double & operator []( const int u ) { return hist [ u ]; }
41 // / Operador de conversao , converte para um vector < double >.
42 operator std :: vector < double >() { return hist ; };
43 };
44 # endif
Listing 4: CHistograma.cpp.
1 # include < vector >
2 # include < iostream >
3 # include < fstream >
4 # include < memory >
5 # include < string >
6
7 # include " CGnuplot . h "
8
9 # include " CImagem . h "
10 # include " CHistograma . h "
11
12 using namespace std ;
13
14 // Imagem tons de cinza tem cores variando entre 0 -255; NCores =255
15 // logo preciso somar +1
16 vector < double > CHistograma :: operator () ( shared_ptr < CImagem >& img ) {
17 hist . resize ( img - > NCores () +1) ; // Redimensiona
18 for ( int i = 0; i < hist . size () ; i ++) // Zera
19 hist [ i ] = 0;
20 for ( int i = 0; i < img - > Nx () ; i ++) // Calcula o histograna
21 for ( int j = 0; j < img - > Ny () ; j ++) // acumulando em hist [ cor ]
22 hist [ img - > pm [ i ][ j ] ]++; // a cor de pm [ i ][ j ]
23 return hist ;
24 }
25 bool CHistograma :: Salvar ( const string nomeArquivo ) const {
26 ofstream fout ( nomeArquivo . c_str () ) ;
27 if ( fout ) {
28 for ( int i = 0; i < hist . size () ; i ++)
29 fout << hist [ i ] << endl ;
30 fout . close () ;
31 return 1;
32 }
33 return 0;
34 }
35 void CHistograma :: Acumular () {
36 for ( int i = 1; i < hist . size () ; i ++)
37 hist [ i ] = hist [ i - 1 ] + hist [ i ] ;
38 }
39 void CHistograma :: Visualizar () {
40 if ( gnuplot == nullptr ) // se não foi criado , cria o gráfico
41 gnuplot = make_unique < CGnuplot >( " lines " ) ;
42
43 if ( gnuplot ) // se existe um gráfico , plota
44 gnuplot - > PlotVector ( hist , " Histograma " ) ;
45 }
46 void CHistograma :: Normalizar () {
47 normalizado = 1 ;
48 double total = 0.0;
49 for ( int i = 0; i < hist . size () ; i ++)
50 total += hist [ i ];
51 for ( int i = 0; i < hist . size () ; i ++)
52 hist [ i ] = hist [ i ] / total ;
53 }
Figura 37: CImagem - classes herdeiras - gerado pelo doxygen
Listing 5: CImagem.h.
1 # ifndef CIMAGEM_H
2 # define CIMAGEM_H
3
4 # include < string >
5 # include < memory >
6
7 # include " CBinarizacao . h "
8
9 // /Enumeração para definir formato da imagem : pbm = preto e branco ; pgm = tons cinza .
10 // Note uso do novo formato de enumerações de C ++11 , agora definimos o tipo .
11 enum class EFormatoImagem : short int { pbm = 0 , pgm };
12
13 /* * @brief Classe que representa uma imagem bidimensional . */
14 class CImagem
15 {
16 protected : // Atributos da imagem .
17 int nx = 0; // < Dimensão x .
18 int ny = 0; // < Dimensão y .
19 int nCores = 255; // < Número de cores ( default =255 , de 0 - >255) .
20 EFormatoImagem formato = EFormatoImagem :: pgm ; // < Formato da imagem ( default = tons cinza ) .
21 std :: string nomeImagem {}; // < Nome da imagem ( sem extensão ) .
22 int ** pm = nullptr ; // < Ponteiro para matriz de dados .
23
24 public : // Construtor e destrutor
25 CImagem () = default ; // < Construtor default .
26 CImagem ( const CImagem & img ) ; // < Construtor de cópia .
27 CImagem ( int _nx , int _ny ) ; // < Construtor sobrecarregado .
28 ~ CImagem () ; // < Destrutor .
29
30 bool Ler ( std :: string nomeArquivo ) ; // < Le imagem do disco .
31 bool Salvar ( std :: string nomeArquivo ) ; // < Salva imagem no disco .
32 void Visualizar () ; // < Mostra imagem .
33 int Nx () const { return nx ; } // < Retorna nx .
34 int Ny () const { return ny ; } // < Retorna ny .
35 int NCores () const { return nCores ; } // < Retorna nCores .
36 void Formato ( EFormatoImagem _f ) { formato = _f ; } // < Seta formato imagem .
37 EFormatoImagem Formato () const { return formato ;} // < Retorna formato imagem .
38 std :: string NomeImagem () const { return nomeImagem ;} // < Retorna nome imagem .
39 void NomeImagem ( std :: string _nn ) { nomeImagem = _nn ;} // < Seta nome imagem .
40
41 static int ** Aloca ( int nx , int ny ) ; // < Aloca matriz
42 static void Desaloca ( int **& pm , int nx ) ; // < Desaloca matriz
43
44 bool Binarizada () { return formato == EFormatoImagem :: pbm ? 1:0; } // < Retorna verdadeiro se
for binarizada .
45
46 // Sobrecarga operadores
47 // / Mostra imagem na tela ou salva em disco . ex : fout << imagem ;
48 friend std :: ostream & operator < <( std :: ostream & fout , const CImagem & obj ) ;
49 // / Lê imagem de istream ( cin ) ou de arquivo em disco . ex : fin >> imagem ;
50 friend std :: istream & operator > >( std :: istream & fin , CImagem & obj ) ;
51 // / Permite uso de imagem [ i ][ j ] no lugar de imagem - > pm [ i ][ j ]. Se for ponteiro use : (* imagem )
[ i ][ j ].
52 inline int * operator []( int i ) { return pm [ i ]; }
53
54 // Declarações de amizade permitem as classes amigas acesso a atributos e métodos da Imagem .
55 friend std :: shared_ptr < CImagem >& CBinarizacao :: Binarizar ( std :: shared_ptr < CImagem >& img , int
_th ) ;
56 friend class CHistograma ;
57 friend class CPorosidade ;
58 friend class CAutoCorrelacao ;
59 friend class CFEspacial ;
60 };
61 # endif
Listing 6: CImagem.cpp.
1 # include < iostream >
2 # include < fstream >
3 # include < sstream >
4
5 # include " CImagem . h "
6
7 using namespace std ;
8
9 // Construtor de copia
10 CImagem :: CImagem ( const CImagem & img ) : nx { img . nx } , ny { img . ny } ,
11 nCores { img . nCores } , formato { img . formato } , nomeImagem { img . nomeImagem } {
12 pm = Aloca ( nx , ny ) ; // aloca matriz
13 for ( int i = 0; i < nx ; i ++) // seta dados
14 for ( int j = 0; j < ny ; j ++)
15 pm [ i ][ j ] = img . pm [ i ][ j ];
16 }
17
18 // Construtor sobrecarregado
19 CImagem :: CImagem ( int _nx , int _ny ) : nx { _nx } , ny { _ny } {
20 pm = Aloca ( nx , ny ) ; // aloca matriz
21 }
22
23 // Destrutor
24 CImagem ::~ CImagem () {
25 Desaloca ( pm , nx ) ;
26 }
27
28 // Lê imagem do disco
29 bool CImagem :: Ler ( string nomeArquivo ) {
30 ifstream fin ( nomeArquivo ) ; // abre arquivo
31 if ( fin ) {
32 nomeImagem = nomeArquivo . substr (0 , nomeArquivo . size () - 4) ; // desconsidera extensão
33 fin >> * this ; // chama operator > >
34 fin . close () ; // fecha arquivo .
35 return 1;
36 }
37 return 0;
38 }
39
40 // / Lê autocorrelacao de istream ( cin ) ou de arquivo em disco
41 istream & operator > >( istream & fin , CImagem & img ) {
42 string f ;
43 fin >> f ; // lê formato
44 img . formato = ( f == " P1 " ) ? EFormatoImagem :: pbm : EFormatoImagem :: pgm ; // seta formato
45 fin >> img . ny ;
46 fin >> img . nx ;
47 if ( img . formato == EFormatoImagem :: pgm ) // se for tons de cinza lê número nCores
48 fin >> img . nCores ;
49 img . pm = CImagem :: Aloca ( img . nx , img . ny ) ;
50 if ( img . pm == nullptr ) {
51 cerr << " \ nFalha ␣ alocação ␣ da ␣ imagem !\ n " ;
52 exit (0) ;
53 }
54 for ( int i = 0; i < img . nx ; i ++) // seta dados
55 for ( int j = 0; j < img . ny ; j ++)
56 fin >> img . pm [ i ][ j ];
57
58 return fin ;
59 }
60
61 bool CImagem :: Salvar ( string nomeArquivo ) { // Salva imagem no disco
62 ofstream fout ; // cria ofstream
63 if ( formato == EFormatoImagem :: pgm ) // verifica formato
64 fout . open ( nomeArquivo + " . pgm " ) ; // abre arquivo com extensão pgm
65 else
66 fout . open ( nomeArquivo + " . pbm " ) ; // abre arquivo com extensão pbm
67 if ( fout ) {
68 fout << * this ; // chama oprator < < ( salva em disco )
69 fout . close () ;
70 return 1;
71 }
72 return 0;
73 }
74
75 // /Mostra autocorrelacao na tela ou salva em disco
76 ostream & operator < <( ostream & fout , const CImagem & img ) {
77 if ( img . formato == EFormatoImagem :: pgm ) // verifica formato e salva cabeçalho
78 fout << " P2 \ n " << img . ny << ’␣ ’ << img . nx << ’␣ ’ << img . nCores << " \ n " ;
79 else
80 fout << " P1 \ n " << img . ny << ’␣ ’ << img . nx << " \ n " ;
81
82 for ( int i = 0; i < img . nx ; i ++) { // salva dados ( píxeis da imagem )
83 for ( int j = 0; j < img . ny ; j ++)
84 fout << img . pm [ i ][ j ] << ’␣ ’;
85 fout << " \ n " ;
86 }
87 return fout ;
88 }
89
90 // Dica : usar biblioteca magick ++ para ver imagem diretamente .
91 void CImagem :: Visualizar () { // Usa programa externo display para ver imagem
92 Salvar ( nomeImagem ) ; // salva imagem no disco
93 ostringstream os ; // cria comando usando ostringstream os
94 if ( formato == EFormatoImagem :: pgm )
95 os << " display ␣ " << nomeImagem << " . pgm ␣ & " ;
96 else
97 os << " display ␣ " << nomeImagem << " . pbm ␣ & " ;
98 system ( os . str () . c_str () ) ; // executa o comando display nomeImagem . pgm ou . pbm
99 }
100
101 int ** CImagem :: Aloca ( int _nx , int _ny ) { // Aloca matriz
102 int ** pm { nullptr };
103 pm = new int * [ _nx ]; // vetor de ponteiros
104 if ( pm )
105 for ( int i = 0; i < _nx ; i ++) // vetores de inteiros
106 pm [ i ] = new int [ _ny ];
107 return pm ;
108 }
109
110 void CImagem :: Desaloca ( int **& pm , int _nx ) {
111 if ( pm ) // Deleta a matriz pm
112 for ( int i = 0; i < _nx ; i ++)
113 delete [] pm [ i ] ;
114 delete [] pm ;
115 }
Figura 38: Diagrama da classe CAutocorrelacao
Figura 39: CAutocorrelacao - diagrama dependências gerado pelo doxygen
Listing 7: CAutoCorrelacao.h.
1 # ifndef CAUTOCORRELACAO_H
2 # define CAUTOCORRELACAO_H
3
4 # include < vector >
5 # include < iostream >
6 # include < fstream >
7 # include < memory >
8
9 # include " CGnuplot . h "
10
11 # include " CImagem . h "
12
13 /* * @brief Classe utilizada para determinacao da curva de auto - correlacao . */
14 class CAutoCorrelacao
15 {
16 std :: vector < double > c ; // < Vetor autocorrelacao . size () é o limite de
deslocamento - uMax .
17 std :: unique_ptr < CGnuplot > gnuplot ; // < Gráfico de autocorrelacao .
18
19 public :
20 CAutoCorrelacao () : c (320 ,0.0) { } // < Construtor default , 640/2.
21 CAutoCorrelacao ( const int _u ) : c ( _u ,0.0) { }; // < Construtor sobrecarregado .
22 CAutoCorrelacao ( const CAutoCorrelacao & obj ) : c ( obj . c ) { }; // < Construtor de copia .
23 ~ CAutoCorrelacao () = default ; // < Destrutor
24
25 void UMax ( const int _u ) { c . resize ( _u ) ; } // < Seta uMax , ou size de c .
26 int UMax () const { return c . size () ; } // < Le uMax , ou size de c .
27
28 // / Calcula autocorrelacao da imagem ; note que esta chamando o operator () .
29 std :: vector < double > CalcularAutocorrelacao ( std :: shared_ptr < CImagem >& img ) {
30 return (* this ) ( img ) ; };
31 bool Salvar ( std :: string nomeArquivo ) ; // < Salva autocorrelacao em disco .
32 void Visualizar () ; // < Mostra curva autocorrelacao usando gnuplot .
33 // / Sobrecarga operadores
34 // / Mostra autocorrelacao na tela ou salva em disco . ex : fout << autocorrelacao ;
35 friend std :: ostream & operator < <( std :: ostream & out , const CAutoCorrelacao & obj ) ;
36 // / Lê autocorrelacao de istream ( cin ) ou de arquivo em disco . ex : fin > autocorrelacao ;
37 friend std :: istream & operator > >( std :: istream & in , CAutoCorrelacao & obj ) ;
38 // / Sobrecarga operador () , realiza calculo da autocorrelacao . ex : autocorrelacao ( imagem ) ;
39 std :: vector < double > operator () ( std :: shared_ptr < CImagem >& img ) ;
40 // / Sobrecarga operador []. A classe se comporta como um vetor . ex : autocorrelacao [ i ];
41 double & operator []( const int u ) { return c [ u ]; }
42 // / Operador de conversao , converte para um vector < double >.
43 operator std :: vector < double >() { return c ; };
44 };
45 # endif
Listing 8: CAutoCorrelacao.cpp.
1 # include < iterator > // uso de ostream_iterator
2
3 # include " CImagem . h "
4 # include " CAutoCorrelacao . h "
5
6 using namespace std ;
7
8 // Sobrecarga operador saida de dados , uso : cout << obj ; fout << obj ;
9 ostream & operator < <( ostream & out , const CAutoCorrelacao & obj ) {
10 // Usando copy e ostream_iterator ( poderia ser um for )
11 copy ( obj . c . begin () , obj . c . end () , ostream_iterator < double >( out , " \ n " ) ) ;
12 return out ;
13 }
14
15 // Sobrecarga operador entrada de dados , uso : cin >> obj ; fin >> obj ;
16 // Usado para testes com funcoes autocorrelacao pre - definidas .
17 istream & operator > >( istream & in , CAutoCorrelacao & obj ) {
18 double t ;
19 obj . c . resize (0) ;
20 while ( in >> t )
21 obj . c . push_back ( t ) ;
22 return in ;
23 }
24
25 // Autocorrelacao em si , usa operator () . A classe se comporta como uma funcao .
26 vector < double > CAutoCorrelacao :: operator () ( shared_ptr < CImagem >& img ) {
27 for ( int u = 0; u < c . size () ; u ++ ) {
28 c [ u ] = 0.0; // zera valor de c [ u ]
29 for ( int x = 0; x < ( img - > nx - c . size () ) ; x ++ ) // Percorre a imagem , considerando limite de
u
30 for ( int y = 0; y < img - > ny ; y ++ ) {
31 // Verifica se o pixel esta ativo >0 , e , a seguir ,
32 // verifica se ocorre a intersecao entre os pixeis [ x ] e [ x + u ]
33 if ( img - > pm [ x ][ y ] > 0 and img - > pm [ x + u ][ y ] > 0 )
34 c [ u ]++; // acumula no vetor de autocorrelacao
35 }
36 c [ u ] /= ( ( img - > nx - c . size () ) * img - > ny ) ;
37 }
38 return c ; // Retorna copia do vetor
39 }
40
41 // Visualizar curva autocorrelacao .
42 void CAutoCorrelacao :: Visualizar () {
43 if ( gnuplot == nullptr ) // se não foi criado , cria o gráfico
44 gnuplot = std :: make_unique < CGnuplot >( " lines " ) ;
45 if ( gnuplot ) // se existe um gráfico , plota
46 gnuplot - > PlotVector (c , " AutoCorrelacao " ) ;
47 }
48
49 // Salva imagem em disco
50 bool CAutoCorrelacao :: Salvar ( std :: string nomeArquivo ) {
51 std :: ofstream fout ( nomeArquivo ) ;
52 if ( fout ) {
53 fout << * this ;
54 fout . close () ;
55 return 1;
56 }
57 return 0;
58 }
Listing 9: CPorosidade.h.
1 # ifndef CPOROSIDADE_H
2 # define CPOROSIDADE_H
3
4 class CImagem ;
5
6 /* *@brief Classe para calculo da porosidade de uma imagem . */
7 class CPorosidade
8{
9 double porosidade = 0.0; // < Porosidade calculada .
10 static int corPoro ; // < Cor do poro ( normalmente = 1 branco )
11
12 public :
13 double operator () ( std :: shared_ptr < CImagem >& img ) ; // < Calcula porosidade da imagem .
14
15 static int CorPoro () { return corPoro ; }; // < retorna cor do poro
16 static void CorPoro ( int _corPoro = 1) { corPoro = _corPoro ; }; // < seta cor do poro
17 };
18 # endif
Listing 10: CPorosidade.cpp.
1 # include " CImagem . h "
2 # include " CPorosidade . h "
3
4 int CPorosidade :: corPoro = 1;
5
6 // Calcula porosidade da imagem
7 double CPorosidade :: operator () ( std :: shared_ptr < CImagem >& img ) {
8 porosidade = 0.0;
9 for ( int i = 0; i < img - > Nx () ; i ++)
10 for ( int j = 0; j < img - > Ny () ; j ++)
11 if ( img - > pm [ i ][ j ] == corPoro ) // Se for poro acumula
12 porosidade ++;
13 porosidade = porosidade / ( img - > Nx () * img - > Ny () ) ;
14 return porosidade ;
15 }
Figura 40: Diagrama de classes mostrando diversos filtros
Figura 41: Procedimento filtragem
Listing 11: CMascara.h.
1 # ifndef CMascara_h
2 # define CMascara_h
3
4 # include " CImagem . h "
5
6 class CMascara : public CImagem {
7 protected :
8 double peso = 1.0; // / < Peso da mascara
9 double CalculaPeso () ; // / < Calcula o peso
10 // / Preenche a mascara com os valores adequados , deve ser redefinida nas classes filhas .
11 virtual void PreencheMascara () = 0;
12 public :
13 // / Construtor , recebe a dimensao da mascara
14 CMascara ( unsigned int tamanhoMascara ) ;
15 // / Destrutor
16 virtual ~ CMascara () ;
17 // / Raio da bola inclusa direcao x
18 inline unsigned int RaioX () const { return ( nx - 1) / 2; }
19 // / Raio da bola inclusa direcao y
20 inline unsigned int RaioY () const { return ( ny - 1) / 2; }
21 // / Retorna o peso da mascara
22 inline double Peso () const { return peso ; }
23 };
24 # endif
Listing 12: CMascara.cpp.
1 # include " CMascara . h "
2
3 CMascara :: CMascara ( unsigned int tamanhoMascara )
4 : CImagem ( tamanhoMascara , tamanhoMascara ) , peso (1.0) {}
5
6 CMascara ::~ CMascara () {}
7
8 double CMascara :: CalculaPeso () {
9 peso = 0;
10 for ( unsigned int i = 0; i < Nx () ; i ++) { // percorre a mascara
11 for ( unsigned int j = 0; j < Ny () ; j ++) {
12 peso += pm [ i ][ j ]; // calcula peso acumulado
13 }
14 }
15 if ( peso == 0)
16 peso = 1; // o peso é utilizado no filtro , numa divisao ,
17 return peso ; // e nao pode assumir o valor 0
18 }
Listing 13: CMPassaBaixa.h.
1 # ifndef CMPassaBaixa_h
2 # define CMPassaBaixa_h
3
4 # include " CMascara . h "
5
6 class CMPassaBaixa : public CMascara {
7 public :
8 CMPassaBaixa ( unsigned int tamanhoMascara ) : CMascara ( tamanhoMascara ) {
9 CMPassaBaixa :: PreencheMascara () ;
10 }
11 virtual ~ CMPassaBaixa () { }
12 protected :
13 virtual void PreencheMascara () ;
14 };
15 # endif
Listing 14: CMPassaBaixa.cpp.
1 # include " CMPassaBaixa . h "
2 /*
31 1 1
41 1 1
51 1 1
6 */
7 void CMPassaBaixa :: PreencheMascara () {
8 for ( unsigned int i = 0; i < Nx () ; i ++)
9 for ( unsigned int j = 0; j < Ny () ; j ++)
10 pm [ i ][ j ] = 1;
11 peso = Nx () * Ny () ; // armazena no atributo peso ; máscara 3 x3 peso =9
12 }
Listing 15: CMGaussiano.h.
1 # ifndef CMGaussiano_h
2 # define CMGaussiano_h
3
4 # include " CMascara . h "
5
6 class CMGaussiano : public CMascara {
7 public :
8 CMGaussiano ( unsigned int tamanhoMascara ) : CMascara ( tamanhoMascara ) {
9 CMGaussiano :: PreencheMascara () ;
10 }
11 virtual ~ CMGaussiano () { }
12 protected :
13 virtual void PreencheMascara () ;
14 };
15 # endif
Listing 16: CMGaussiano.cpp.
1 # include " CMGaussiano . h "
2
3 void CMGaussiano :: PreencheMascara () {
4 unsigned int i , j ;
5 double * fat = new double [ Nx () ]; // Cria vetor com valores de fatorias de i
6 double acumulado = 1;
7 fat [0] = 1.0;
8 for ( i = 1; i < Nx () ; i ++) { // Calcula os fatorias e armazena em fat [ i ]
9 acumulado *= i ;
10 fat [ i ] = acumulado ;
11 }
12 int * v = new int [ RaioX () + 1]; // metade da mascara (5 -1) /2=2 +1=3 0 ,1 ,2
13 // calcula fatores para primeira linha
14 double ftemp = fat [ Nx () - 1]; // Pega fatorial de nx -1 , pois a matriz comeca do zero
15 for ( i = 0; i < RaioX () + 1; i ++) // preenche vetor temporario v
16 v [ i ] = ftemp / ( fat [ i ] * fat [ Nx () -1 - i ]) ;
17 int t = Nx () - 1; // Para mascara 5*5 t =5 -1=4 pois começa do zero
18 for ( i = 0; i < RaioX () + 1; i ++) // calcula valores da mascara
19 for ( j = 0; j < RaioX () + 1; j ++) // RaioX = RaioY
20 pm [ i ][ j ] = pm [ i ][ t - j ] = pm [t - i ][ j ] = pm [t - i ][ t - j ] = v [ i ]* v [ j ];
21 delete [] v ; // apaga vetores temporarios
22 delete [] fat ;
23 CalculaPeso () ; // calcula o peso da mascara e armazena no atributo
peso
24 }
Listing 17: CFiltro.h.
1 # ifndef CFiltro_h
2 # define CFiltro_h
3
4 # include " CImagem . h "
5
6 class CFiltro {
7 protected :
8 CImagem * imagem { nullptr };
9
10 public :
11 CFiltro ( CImagem * & matriz ) : imagem ( matriz ) { }
12 virtual ~ CFiltro () { }
13 virtual CImagem * Go ( CImagem * & matriz , unsigned int _tamanhoMascara = 0) = 0;
14 CImagem * operator () ( CImagem * & matriz , unsigned int _tamanhoMascara = 0) {
15 return Go ( matriz , _tamanhoMascara ) ;
16 };
17 };
18 # endif
Listing 18: CFiltro.cpp.
1 # include " CFiltro . h "
Figura 42: CFEspacial - classes herdeiras - gerado pelo doxygen
Listing 19: CFEspacial.h.
1 # ifndef CFEspacial_h
2 # define CFEspacial_h
3
4 # include " CFiltro . h "
5 # include " CMascara . h "
6
7 class CFEspacial : public CFiltro { // Atributos
8 protected :
9 int tamanhoMascara = 3; // / < Tamanho da macara .
10
11 public :
12 CMascara * mask = nullptr ; // / < Ponteiro para mascara .
13
14 // / Construtor , recebe ponteiro para imagem e tamanho da mascara .
15 CFEspacial ( CImagem * & img , unsigned int _tamanhoMascara )
16 : CFiltro ( img ) , tamanhoMascara ( _tamanhoMascara ) {}
17 // / Destrutor .
18 ~ CFEspacial () { if ( mask ) delete mask ; }
19 // / Obtem tamanhoMascara .
20 virtual unsigned int TamanhoMascara () const { return tamanhoMascara ; }
21 // / Seta o tamanhoMascara .
22 virtual void TamanhoMascara ( unsigned int _tamanhoMascara )
23 { tamanhoMascara = _tamanhoMascara ; }
24 // / Realiza o processamento da filtragem .
25 virtual CImagem * Go ( CImagem * & img , unsigned int _tamanhoMascara = 0) ;
26
27 CImagem * operator () ( CImagem * & img , unsigned int _tamanhoMascara = 0) {
28 return Go ( img , _tamanhoMascara ) ;
29 }
30 protected :
31 // / Cria a mascara adequada .
32 virtual void CriaMascara ( unsigned int _tamanhoMascara ) ;
33 };
34 # endif
Listing 20: CFEspacial.cpp.
1 # include " CFEspacial . h "
2 # include " CMPassaBaixa . h "
3
4 void CFEspacial :: CriaMascara ( unsigned int _tamanhoMascara ) {
5 tamanhoMascara = _tamanhoMascara ;
6 if ( mask )
7 delete mask ;
8 mask = new CMPassaBaixa ( _tamanhoMascara ) ;
9}
10
11 CImagem * CFEspacial :: Go ( CImagem * & matriz , unsigned int _tamanhoMascara ) {
12 imagem = matriz ; // Seta imagem a ser processada
13 // Precisa criar nova máscara se :
14 if ( tamanhoMascara != _tamanhoMascara // mudou dimensão da máscara ou
15 or mask == nullptr ) // máscara ainda não foi criada
16 CriaMascara ( _tamanhoMascara ) ;
17
18 CImagem * imgAuxiliar = new CImagem (* imagem ) ; // imgAuxiliar é cópia da imagem original
19 int raioMascaraX = mask - > RaioX () ;
20 int raioMascaraY = mask - > RaioY () ;
21 int maiorValor = imagem - > NCores () ;
22 int menorValor = 0;
23 float soma ;
24
25 // Percorre a matriz imagem , exceto a borda
26 for ( int i = ( raioMascaraX ) ; i < ( imagem - > Nx () - raioMascaraX ) ; i ++) {
27 for ( int j = ( raioMascaraY ) ; j < ( imagem - > Ny () - raioMascaraY ) ; j ++) {
28 soma = 0.0;
29 for ( int k = 0; k < mask - > Nx () ; k ++) { // percorre a mascara
30 for ( int l = 0; l < mask - > Ny () ; l ++) { // realiza convolução da
mascara com a imagem
31 soma += mask - > pm [ k ][ l ] * imgAuxiliar - > pm [ i + k - raioMascaraX
][ j + l - raioMascaraY ];
32 }
33 }
34 imagem - > pm [ i ][ j ] = soma / mask - > Peso () ;
35 // devo garantir que não exceda o valor maximo
36 // e que nao seja valor negativo ( cor nao realizavel ) .
37 if ( imagem - > pm [ i ][ j ] > maiorValor )
38 imagem - > pm [ i ][ j ] = maiorValor ;
39 else if ( imagem - > pm [ i ][ j ] < menorValor )
40 imagem - > pm [ i ][ j ] = menorValor ;
41 }
42 }
43 delete imgAuxiliar ; // deleta objeto matriz auxiliar
44 return imagem ;
45 }
Listing 21: CFEPassaBaixa.h.
1 # ifndef CFEPassaBaixa_h
2 # define CFEPassaBaixa_h
3
4 # include " CFEspacial . h "
5 class CFEPassaBaixa : public CFEspacial {
6 public :
7 // / Construtor
8 CFEPassaBaixa ( CImagem * & matriz , unsigned int _tamanhoMascara )
9 : CFEspacial ( matriz , _tamanhoMascara ) {
10 }
11 // / Cria a mascara adequada
12 virtual void CriaMascara ( unsigned int _tamanhoMascara ) ;
13 };
14 # endif
Listing 22: CFEPassaBaixa.cpp.
1 # include " CFEPassaBaixa . h "
2 # include " CMPassaBaixa . h "
3
4 void CFEPassaBaixa :: CriaMascara ( unsigned int _tamanhoMascara ) {
5 this - > tamanhoMascara = _tamanhoMascara ;
6 if ( this - > mask )
7 delete this - > mask ;
8 this - > mask = new CMPassaBaixa ( _tamanhoMascara ) ;
9}
Listing 23: CFEPassaBaixa.h.
1 # ifndef CFEPassaBaixa_h
2 # define CFEPassaBaixa_h
3
4 # include " CFEspacial . h "
5 class CFEPassaBaixa : public CFEspacial {
6 public :
7 // / Construtor
8 CFEPassaBaixa ( CImagem * & matriz , unsigned int _tamanhoMascara )
9 : CFEspacial ( matriz , _tamanhoMascara ) {
10 }
11 // / Cria a mascara adequada
12 virtual void CriaMascara ( unsigned int _tamanhoMascara ) ;
13 };
14 # endif
Listing 24: CFEGaussiano.cpp.
1 # include " CFEGaussiano . h "
2 # include " CMGaussiano . h "
3
4 void CFEGaussiano :: CriaMascara ( unsigned int _tamanhoMascara ) {
5 tamanhoMascara = _tamanhoMascara ;
6 if ( mask )
7 delete mask ;
8 mask = new CMGaussiano ( _tamanhoMascara ) ;
9}
Listing 25: CFEGaussiano.h.
1 # ifndef CFEGaussiano_h
2 # define CFEGaussiano_h
3
4 # include " CFEspacial . h "
5
6 class CFEGaussiano : public CFEspacial {
7 public :
8 CFEGaussiano ( CImagem * & img , unsigned int _tamanhoMascara )
9 : CFEspacial ( img , _tamanhoMascara ) {
10 }
11 // / Destrutor
12 ~ CFEGaussiano () { }
13
14 // / Cria a mascara adequada
15 virtual void CriaMascara ( unsigned int _tamanhoMascara ) ;
16 };
17 # endif
Listing 26: CFEPassaBaixa.cpp.
1 # include " CFEPassaBaixa . h "
2 # include " CMPassaBaixa . h "
3
4 void CFEPassaBaixa :: CriaMascara ( unsigned int _tamanhoMascara ) {
5 this - > tamanhoMascara = _tamanhoMascara ;
6 if ( this - > mask )
7 delete this - > mask ;
8 this - > mask = new CMPassaBaixa ( _tamanhoMascara ) ;
9}
Solução - Teste
Veja na listagem 29 a função principal (main.cpp), e, na listagem 30, a saída gerada ao executar o
programa com a imagem da Figura 29.
Listing 27: main-TesteCImagemCHistogramaCAutoCorrelacaoCPorosidade.cpp.
1 # include < iostream >
2 # include < fstream >
3 # include < string >
4 # include < cmath > // Fij
5 # include < memory >
6
7 # include " CGnuplot . h "
8
9 # include " CImagem . h "
10 # include " CHistograma . h "
11 # include " CBinarizacao . h "
12 # include " CAutoCorrelacao . h "
13 # include " CPorosidade . h "
14
15 using namespace std ;
16
17 // Q4 : Funcao f (i , j ) cos (2. i ) sin ( j ) . sin ( j )
18 double f ( double i , double j ) {
19 return cos ( 2.0 * i ) * sin ( j ) * sin ( j ) ;
20 }
21
22 void PlotEquationFij () {
23 static CGnuplot gnuplot ;
24 gnuplot . XRange (0 , M_PI ) . YRange (0 ,2.* M_PI ) . PlotEquation3d ( " cos ( ␣ 2.0 ␣ * ␣ x ␣ ) ␣ * ␣ sin ␣ ( ␣ y ␣ ) * ␣ sin ␣ ( ␣ y ␣
)");
25 }
26
27 void Logomarca ( ostream & os ) {
28 os << " \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n "
29 << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n "
30 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
31 << " ================ ␣ ␣ ␣ E ␣ N ␣ G ␣ E ␣ N ␣ H ␣ A ␣ R ␣ I ␣ A ␣ ␣ ␣ D ␣ E ␣ ␣ ␣ P ␣ E ␣ T ␣ R ␣ Ó ␣ L ␣ E ␣ O ␣ ␣ ␣ ================\ n "
32 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
33 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
34 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ U ␣ E ␣ N ␣ F ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
35 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
36 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
37 << " ================ ␣ PROCESSAMENTO ␣ DE ␣ IMAGENS ␣ DE ␣ ROCHAS ␣ RESERVATÓRIO ␣ ================\ n "
38 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
39 << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n "
40 << " \ n " ;
41 }
42
43 // Usando ponteiros tradicionais
44 int main () {
45 Logomarca ( cout ) ;
46 CImagem * imagem = new CImagem ; // Cria imagem
47 string nomeArquivo ;
48 cout << " Entre ␣ com ␣ o ␣ nome ␣ do ␣ arquivo : ␣ " ;
49 getline ( cin , nomeArquivo ) ;
50 imagem - > Ler ( nomeArquivo ) ; // Le imagem do disco
51 imagem - > Visualizar () ; // Visualiza imagem em tons de cinza
52
53 CHistograma * histograma = new CHistograma ; // Cria histograma
54 histograma - > CalcularHistograma ( imagem ) ; // Calcula histograma e salva
55 histograma - > Salvar ( imagem - > NomeImagem () + " . hist " ) ;
56 histograma - > Visualizar () ; // Visualiza grafico do histograma
57
58 cout << " Entre ␣ com ␣ o ␣ nivel ␣ de ␣ corte ␣ th : ␣ " ;
59 int th ; cin >> th ; cin . get () ; // Usuario define nivel de corte
60
61 CImagem * imgBin = new CImagem ( * imagem ) ; // Cria copia da imagem
62 CBinarizacao * binarizador = new CBinarizacao ; // Cria binarizador e binariza imagem
63 binarizador - > Binarizar ( imgBin , th ) ; // Binariza a imagem
64 imgBin - > Salvar ( imgBin - > NomeImagem () ) ; // Salva em disco imagem binarizada
65 imgBin - > Visualizar () ; // Visualiza imagem binarizada
66 // Calcula e mostra a porosidade
67 CPorosidade porosidade ;
68 cout << " Porosidade ␣ do ␣ " << imgBin - > NomeImagem () << " ␣ = ␣ " << porosidade ( imgBin ) << endl ;
69
70 cout << " Calculando ␣ e ␣ gerando ␣ gráfico ␣ autocorrelacao ␣ " << endl ; // Calculando autocorrelacao
71 CAutoCorrelacao * autocorrelacao = new CAutoCorrelacao ;
72 autocorrelacao - > CalcularAutocorrelacao ( imgBin ) ; // Calcula autocorrelacao
73 autocorrelacao - > Salvar ( " autocorrelacao . dat " ) ;
74 autocorrelacao - > Visualizar () ;
75
76 cout << " Plotando ␣ equacao ␣ Fij ␣ " << endl ; // Calculando autocorrelacao
77 PlotEquationFij () ; // Plota a equacao Fij
78 cin . get () ;
79 delete imagem ; delete histograma ; // Deleta explicitamente objetos
80 delete imgBin ; delete autocorrelacao ; // criados com new
81 return 0;
82 }
Listing 28: main-teste.out.
1# Versão sem filtros
2 [ bueno@localhost saidaPrograma ] $ ./ a . out
3 Entre com o nome do arquivo : Berea500 . pgm
4 Entre com o nivel de corte th : 40000
5 Porosidade do Berea500 = 0.337035
6 Calculando e gerando gráfico autocorrelacao
7 Plotando equacao Fij
Listing 29: main.cpp.
1 // Para criar uma imagem com gradientes de cinza
2 // echo " P2 NY NX NCores .. dados .."
3 // Para redimensionar imagem
4 // convert - - scale 120 x20 - compress none origem . pgm destino . pgm
5 // echo " P2 6 1 5 0 1 2 3 4 5" | convert - - scale 120 x20 - compress none step_gradient . pgm
6
7 # include < iostream >
8 # include < fstream >
9 # include < string >
10 # include < cmath > // Fij
11 # include < memory >
12
13 # include " CGnuplot . h "
14
15 # include " CImagem . h " // Processamento básico de imagens de rochas
16 # include " CHistograma . h "
17 # include " CBinarizacao . h "
18 # include " CAutoCorrelacao . h "
19 # include " CPorosidade . h "
20
21 # include " CFiltro . h " // Biblioteca de filtros
22 # include " CFEspacial . h "
23 # include " CFEPassaBaixa . h "
24 # include " CFEPassaAlta . h "
25 # include " CFEPassaAlta2 . h "
26 # include " CFEGaussiano . h "
27 # include " CFELaplaciano . h "
28
29 using namespace std ;
30
31 void Logomarca ( ostream & os ) {
32 os << " \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n "
33 << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n "
34 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
35 << " ================ ␣ ␣ ␣ E ␣ N ␣ G ␣ E ␣ N ␣ H ␣ A ␣ R ␣ I ␣ A ␣ ␣ ␣ D ␣ E ␣ ␣ ␣ P ␣ E ␣ T ␣ R ␣ Ó ␣ L ␣ E ␣ O ␣ ␣ ␣ ================\ n "
36 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
37 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
38 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ U ␣ E ␣ N ␣ F ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
39 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
40 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
41 << " ================ ␣ PROCESSAMENTO ␣ DE ␣ IMAGENS ␣ DE ␣ ROCHAS ␣ RESERVATÓRIO ␣ ================\ n "
42 << " ================ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ================\ n "
43 << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n "
44 << " \ n " ;
45 }
46
47 // Usando unique_ptr e shared_ptr no lugar de ponteiro tradicional .
48 // Vantagem : não precisa do delete ! tem funções específicas da classe shared_ptr .
49 int main () {
50 Logomarca ( cout ) ;
51 CImagem * imagem = new CImagem ;
52 string nomeArquivo ;
53 cout << " \ nLista ␣ de ␣ imagens ␣ com ␣ extensão ␣ . pgm ␣ ou ␣ . pbm :\ n " ;
54 system ( " ls ␣ *. pgm ␣ *. pbm " ) ;
55 cout << " \ nEntre ␣ com ␣ o ␣ nome ␣ do ␣ arquivo ␣ ( inclua ␣ extensão ␣ . pgm ␣ ou ␣ . pbm ) : ␣ " ;
56 getline ( cin , nomeArquivo ) ;
57 imagem - > Ler ( nomeArquivo ) ; // Le imagem do disco
58 imagem - > Visualizar () ; // Visualiza imagem ( normalmente em tons de
cinza )
59 cout << " \ n : ␣ " ;
60
61 // Trabalhando com Filtros = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
62 int tamanhoMascara ; // Looping para filtragem de imagens
63 int tipoFiltro ;
64 CImagem * imgFiltrada = new CImagem (* imagem ) ; // Cópia da imagem
65 cout << " \ nCriou ␣ cópia ␣ da ␣ imagem ␣ : ␣ imgFiltrada . " << endl ;
66 do {
67 Logomarca ( cout ) ;
68 cout << " \ nQual ␣ filtro ␣ deseja ␣ criar ? "
69 << " \ nCFEPassaBaixa ............1 "
70 << " \ nCFEGaussiano .............2 "
71 << " \ nCFEPassaAlta .............3 "
72 << " \ nCFEPassaAlta2 ............4 "
73 << " \ nCFELaplaciano ............5: ␣ "
74 << " \ nEncerrar ␣ filtros .........0: ␣ " ;
75 cin >> tipoFiltro ; cin . get () ; // 0 é o número ( int ) ; já ’0 ’ é a letra ( char )
.
76 cout << " \ ntipoFiltro ␣ = ␣ " << tipoFiltro << endl ;
77 if ( tipoFiltro == 0 ) continue ; // Vai para final do do .. while
78 cout << " \ nEntre ␣ com ␣ tamanho ␣ da ␣ máscara ␣ para ␣ filtro ␣ ( número ␣ inteiro ␣ impar !) : ␣ " ;
79 cin >> tamanhoMascara ; cin . get () ;
80 if ( tamanhoMascara %2 == 0) { // Corrige se entrou com tamanho par !
81 tamanhoMascara ++;
82 cout << " \ nTamanho ␣ máscara ␣ corrigido , ␣ tamanhoMascara ␣ = ␣ " << tamanhoMascara ;
83 }
84 CFiltro * filtro { nullptr }; // ponteiro para filtro
85 switch ( tipoFiltro ) { // cria filtro selecionado
86 case 2: filtro = new CFEGaussiano ( imgFiltrada , tamanhoMascara ) ;
87 imgFiltrada - > NomeImagem ( imgFiltrada - > NomeImagem () + " . Gaussiano " ) ; break ;
88 case 3: filtro = new CFEPassaAlta ( imgFiltrada , tamanhoMascara ) ;
89 imgFiltrada - > NomeImagem ( imgFiltrada - > NomeImagem () + " . PassaAlta " ) ; break ;
90 case 4: filtro = new CFEPassaAlta2 ( imgFiltrada , tamanhoMascara ) ;
91 imgFiltrada - > NomeImagem ( imgFiltrada - > NomeImagem () + " . PassaAlta2 " ) ; break ;
92 case 5: filtro = new CFELaplaciano ( imgFiltrada , tamanhoMascara ) ;
93 imgFiltrada - > NomeImagem ( imgFiltrada - > NomeImagem () + " . Laplaciano " ) ; break ;
94 case 1:
95 default : filtro = new CFEPassaBaixa ( imgFiltrada , tamanhoMascara ) ;
96 imgFiltrada - > NomeImagem ( imgFiltrada - > NomeImagem () + " . PassaBaixa " ) ; break ;
97 }
98 if ( filtro == nullptr ) continue ;
99 cout << " \ nCriou ␣ Filtro . " << endl ;
100 filtro - > Go ( imgFiltrada , tamanhoMascara ) ; // Filtra imagem
101 cout << " \ nProcessou ␣ Filtro . " << endl ;
102 cout << " \ nVai ␣ visualizar ␣ e ␣ salvar ␣ imagem ␣ filtrada : " << imgFiltrada - > NomeImagem () << endl ;
103 imgFiltrada - > Visualizar () ; // Salva e visualiza imagem filtrada
104 } while ( cin . good () and tipoFiltro != 0) ;
105
106 cout << " \ nExecutando ␣ shared_ptr < CImagem > ␣ sp_imgFiltrada " << endl ;
107 shared_ptr < CImagem > sp_imgFiltrada = make_shared < CImagem >(* imgFiltrada ) ;
108 cout << " \ nExecutando ␣ auto ␣ histograma ␣ = ␣ make_unique < CHistograma >() ; ␣ " << endl ;
109 auto histograma = make_unique < CHistograma >() ; // Cria histograma
110 cout << " \ nExecutando ␣ histograma - > CalcularHistograma ( sp_imgFiltrada ) ; ␣ " << endl ;
111 histograma - > CalcularHistograma ( sp_imgFiltrada ) ; // Calcula histograma e salva
112 cout << " \ nExecutando ␣ ␣ histograma - > Salvar " << endl ;
113 histograma - > Salvar ( sp_imgFiltrada - > NomeImagem () + " . hist " ) ;
114 cout << " \ nExecutando ␣ Visualizando ␣ histograma - > Visualizar () " << endl ;
115 histograma - > Visualizar () ; // Visualiza grafico do histograma
116
117 cout << " Entre ␣ com ␣ o ␣ nivel ␣ de ␣ corte ␣ th : ␣ " ;
118 int th ; cin >> th ; cin . get () ; // Usuario define nivel de corte
119
120 cout << " \ nExecutando ␣ auto ␣ imgBin ␣ = ␣ make_shared < CImagem >(* sp_imgFiltrada ) ; " << endl ;
121 auto imgBin = make_shared < CImagem >(* sp_imgFiltrada ) ; // Cria copia da imagem filtrada
122 cout << " \ nExecutando ␣ auto ␣ binarizador ␣ = ␣ make_shared < CBinarizacao >() ; " << endl ;
123 auto binarizador = make_shared < CBinarizacao >() ; // Cria binarizador e binariza imagem
124 cout << " \ nExecutando ␣ binarizador - > Binarizar ␣ ( ␣ imgBin , ␣ th ␣ ) " << endl ;
125 binarizador - > Binarizar ( imgBin , th ) ; // Binariza a imagem
126 cout << " \ nExecutando ␣ imgBin - > NomeImagem ( ␣ imgBin - > NomeImagem () +. Binarizada ␣ ) " << endl ;
127 imgBin - > NomeImagem ( imgBin - > NomeImagem () + " . Binarizada " ) ; // Muda nome da imagem
128 cout << " \ nExecutando ␣ imgBin - > Visualizar () " << endl ;
129 imgBin - > Visualizar () ; // Salva em disco e visualiza imagem
binarizada
130 // Calcula e mostra a porosidade
131 CPorosidade porosidade ;
132 cout << " \ nPorosidade ␣ do ␣ " << imgBin - > NomeImagem () << " ␣ = ␣ " << porosidade ( imgBin ) << endl ;
133
134 cout << " Calculando ␣ e ␣ gerando ␣ gráfico ␣ autocorrelacao ␣ " << endl ; // Calculando autocorrelacao
135 cout << " \ nExecutando ␣ auto ␣ autocorrelacao ␣ = ␣ make_unique < CAutoCorrelacao >() " << endl ;
136 auto autocorrelacao = make_unique < CAutoCorrelacao >() ;
137 cout << " \ nExecutando ␣ autocorrelacao - > CalcularAutocorrelacao ( imgBin ) " << endl ;
138 autocorrelacao - > CalcularAutocorrelacao ( imgBin ) ; // Calcula autocorrelacao
139 cout << " \ nExecutando ␣ ␣ autocorrelacao - > Salvar ( imgBin - > NomeImagem () ␣ +. cor ) " << endl ;
140 autocorrelacao - > Salvar ( imgBin - > NomeImagem () + " . cor " ) ;
141 cout << " \ nExecutando ␣ ␣ autocorrelacao - > Visualizar () " << endl ;
142 autocorrelacao - > Visualizar () ;
143 cin . get () ;
144 return 0;
145 }
Listing 30: main.out.
1
2# Versão com filtros
3 [ bueno@localhost Solucao - C ++11 -3 - CImagem - CHistograma - CBinarizacao - CAutocorrelacao - CPorosidade -
CMascara - CFiltro ] $ cp Berea500 - original . pgm Berea500 . pgm
4 [ bueno@localhost Solucao - C ++11 -3 - CImagem - CHistograma - CBinarizacao - CAutocorrelacao - CPorosidade -
CMascara - CFiltro ] $ ./ a . out
5 Entre com o nome do arquivo : Berea500 . pgm
6 Entre com o nivel de corte th : 30000
7 Porosidade do Berea500 = 0.210023
8 Calculando e gerando gráfico autocorrelacao
9
10 Qual filtro deseja criar ?
11 CFEPassaBaixa ............1
12 CFEGaussiano .............2
13 CFEPassaAlta .............3
14 CFEPassaAlta2 ............4
15 CFELaplaciano ............5: 1
16 Entre com tamanho da mascara para filtro ( número inteiro impar !) : 7
17
18 Qual filtro deseja criar ?
19 CFEPassaBaixa ............1
20 CFEGaussiano .............2
21 CFEPassaAlta .............3
22 CFEPassaAlta2 ............4
23 CFELaplaciano ............5:
24 Entre com tamanho da mascara para filtro ( número inteiro impar !) :
25 Plotando equacao Fij
Figura 43: Saídas geradas pelo programa
Figura 44: Saídas geradas pelo programa
Figura 45: Comparação binarização imagem Berea sem filtro e com filtro passa-baixa (R=3)
Figura 46: Saídas geradas pelo programa, função Fij

Você também pode gostar