INF01046 –
Fundamentos de Processamento de Imagens
Prof. Manuel M. Oliveira
Aluno: Lucas Enrique Guaycochea
2º Trabalho de Implementação
OBJETIVO
O objetivo
deste trabalho é
familiariza-se com cálculo de histograma, transformações lineares sobre pixels
(ajuste de brilho e contraste e cálculo do negativo)
e equalização de histograma.
IMPLEMENTAÇÃO
Funções feitas pra o programa:
·
Cálculo do
histograma
int* calcula_histograma(unsigned
char* imagem, int height, int width, int channels)
{
int*
resultado=(int*)malloc(256*sizeof(int));
int
bytesFila=width*channels;
for(int
l=0;l<256;l++)
resultado[l]=0;
for(int
i=0;i<height;i++)
for(int
j=0;j<width;j++)
resultado[imagem[i*bytesFila+j*channels]]+=1;
return
resultado;
}
unsigned char*
dibujar_histograma(int* histograma){
unsigned
char* grafico=(unsigned char*)malloc(256*256*3*sizeof(unsigned char));
//para
escalar el grafico
int
max=0;
for(int
l=0;l<256;l++)
if
(histograma[l]>max) max=histograma[l];
for(l=0;l<256;l++)
histograma[l]=(int)(histograma[l]*255/max);
for(int
i=0;i<256;i++)
{
for(int
j=0;j<256;j++)
{
if((histograma[j])>0){
grafico[i*256*3+j*3+0]=0;
grafico[i*256*3+j*3+1]=0;
grafico[i*256*3+j*3+2]=0;
}
else
{
grafico[i*256*3+j*3+0]=255;
grafico[i*256*3+j*3+1]=255;
grafico[i*256*3+j*3+2]=255;
}
histograma[j]-=1;
}
}
return
grafico;
}
Como exemplo o calculo do histograma
da seguinte imagem:


·
Ajuste de brilho:
Pra o ajuste do brilho fiz esta
função:
void ajustar_brilho(int brilhoAsomar, unsigned char*
imagem, int height, int width, int channels)
{
int
bytesFila=width*channels;
for(int
i=0;i<height;i++)
for(int
j=0;j<width;j++)
for(int
k=0;k<channels;k++){
int
actual=imagem[i*bytesFila+j*channels+k];
int
resultado=actual+brilhoAsomar;
if
(resultado<0) resultado=0;
if
(resultado>255) resultado=255;
imagem[i*bytesFila+j*channels+k]=(unsigned
char)resultado;
}
}
Os resultados podem-se olhar aquí:



+20 Original -20
·
Ajuste de contraste:
A função pra ajustar o contraste é:
void ajustar_contraste(float escalar, unsigned char*
imagem, int height, int width, int channels)
{
int
bytesFila=width*channels;
for(int
i=0;i<height;i++)
for(int
j=0;j<width;j++)
for(int
k=0;k<channels;k++){
imagem[i*bytesFila+j*channels+k]=(unsigned
char)((int)imagem[i*bytesFila+j*channels+k]*escalar);
if
(imagem[i*bytesFila+j*channels+k]<0)
imagem[i*bytesFila+j*channels+k]=0;
if
(imagem[i*bytesFila+j*channels+k]>255)
imagem[i*bytesFila+j*channels+k]=255;
}
}
Distintos resultados podem-se ver a continuação:


Original
escalar = 1,5


Original escalar
= 0,5
·
Calculo do
negativo:
A função
utilizada é bem simples:
void
negative(unsigned char* pixels, int height, int widht, int channels){
int aux=0;
for(int i=0;i<widht;i++)
for(int
j=0;j<height;j++)
for(int
k=0;k<channels;k++){
pixels[aux]=255-pixels[aux];
aux++;
}
}
O
resultado pode-se ver:


·
Equalização:
Finalmente, a funçoes pra a
equalização e seus resultados:
unsigned char* equalizacao(unsigned
char* imagem, int height, int width, int channels)
{
int
totalbytes=height*width*channels;
int
bytesFila=width*channels;
unsigned
char* resultado=(unsigned char*)malloc(totalbytes*sizeof(unsigned char));
//primero
la paso a tons de cinza pra calcular o histograma
unsigned
char* aux=obter_tons_cinza(imagem, height, width, channels);
int*
histograma=calcula_histograma(aux, height, width, channels);
free(aux);
float
factor=(float)255/(float)(width*height);
int
histAcum[256];
histAcum[0]=histograma[0];
for(int
i=1;i<256;i++)
histAcum[i]=histAcum[i-1]+histograma[i];
free(histograma);
//normalizacion
for(i=0;i<256;i++)
histAcum[i]=(int)(histAcum[i]*factor);
for(i=0;i<height;i++)
for(int
j=0;j<width;j++)
for(int
k=0;k<channels;k++)
resultado[i*bytesFila+j*channels+k]=histAcum[imagem[i*bytesFila+j*channels+k]];
return
resultado;
}




Observaçao final: O programa só foi
modificado pra adicionar as novos funções na interfase do usuario. Pode-se ver
no trabalho 1.
26/9/2007
- Lucas Enrique Guaycochea