라즈베리파이에서 Processing을 이용한 영상처리- 히스토그램 스트레칭

메카 2017-04-03 (월) 13:55 2년전 4464  

5.4 히스토그램 스트레칭

히스토그램 스트레칭도 히스토그램 평활화와 마찬가지로 입력 영상의 화소값들을 0에서 255 사이에 골고루 분포를 늘려주는 것이다. 다음 식에 의해 새로운 픽셀 값을 저장 할 수 있다.

02c7232450ce0f92271d32085c8e4707_1491195
 

여기서 I(x,y)는 입력 영상, I​'(x,y) 는 변환된 영상, min은 입력 영상의 픽셀 값 중 최솟값 그리고 max는 입력 영상의 픽셀 값 중 최댓값을 의미한다.

 

 

[실습5-7] 히스토그램 스트레칭

 

a) 소스코드 및 결과 영상

 size(1285, 980);

background(255);

 

PImage img = loadImage("darkImage.jpg");

PImage equal_img = createImage( img.width, img.height, RGB );

image(img, 0, 0);

 

int[] hist = new int[256];

int[] sum_hist = new int[256];

float factor=0;

int sum=0;

int pixel_minVal=255;

int pixel_maxVal=0;

 

for (int y = 0; y < img.height; y++) {

for (int x = 0; x < img.width; x++) {

int bright = int(brightness(get(x, y)));

if (bright>pixel_maxVal) pixel_maxVal=bright;

if (bright<pixel_minVal) pixel_minVal=bright;

hist[bright]++;

}

}

 

int histMax = max(hist);

 

for (int i = 0; i < img.width; i += 2) {

int which = int(map(i, 0, img.width, 0, 255));

int y = int(map(hist[which], 0, histMax, img.height, 0));

line(img.width+i, img.height, img.width+i, y);

}

 

factor=(255.0)/(pixel_maxVal-pixel_minVal);

img.loadPixels();

for (int y = 0; y < img.height; y++) {

for (int x = 0; x < img.width; x++) {

int pos = y*img.width+x;

color c = img.pixels[pos];

int val=int(brightness(c));

int new_val=(int)((val-pixel_minVal)*factor+0.5);

equal_img.pixels[pos] = color(new_val);

}

}

equal_img.updatePixels();

 

line(640, 479, 1280, 479);

line(640, 480, 1280, 480);

textSize(20);

fill(0, 0, 0);

text("0", 640, 500);

text("255", 1247, 500);

 

image(equal_img,0,500);

 

int[] new_hist = new int[256];

 

equal_img.loadPixels();

for (int y = 0; y < equal_img.height; y++) {

for (int x = 0; x < equal_img.width; x++) {

int pos = y*equal_img.width+x;

color c = equal_img.pixels[pos];

int bright=int(brightness(c));

new_hist[bright]++;

}

}

int new_histMax = max(new_hist);

 

for (int i = 0; i < equal_img.width; i += 2) {

int which = int(map(i, 0, equal_img.width, 0, 255));

int y = int(map(new_hist[which], 0, new_histMax, equal_img.height, 0));

line(equal_img.width+i, 500+equal_img.height, equal_img.width+i, y+500);

}

equal_img.loadPixels();

 

 02c7232450ce0f92271d32085c8e4707_1491195 

[그림 5-7] 히스토그램 스트레칭 코드 및 결과 영상; 위 영상 - 히스토그램 스트레칭 전 영상 및 히스토그램, 아래 영상- 히스토그램 스트레칭 후 영상 및 히스토그램

 

b) 코드 설명

히스토그램 평활화와 작업은 비슷한 과정을 가진다. 차이가 나는 부분에 대해 소스 코드에 음영 처리를 해 놓은 부분이다. 먼저 입력 영상으로부터 화소의 밝기값 최대와 최소를 구한다. 그리고 factor=(255.0)/(pixel_maxVal-pixel_minVal)을 계산한다. 그림 5-7의 아래 오른쪽 그림의 히스토그램으로부터 factor만큼의 간격이 벌어진 것을 알 수 있다. 제시된 식을 이용하여 나머지 부분을 계산하면 new_val=(int)((val-pixel_minVal)*factor+0.5)가 최종적으로 얻어진다. 결과 값 new_val값을 새로운 영상 equal_img.pixels[]에 저장하였으며, 그림 5-7의 결과처럼 원래의 영상보다 훨씬 명암 대비가 높아졌다는 것을 확인 할 수 있다. 평활화는 스트레칭에 비해 펼쳐진 효과가 크며, 스트레칭은 영상 내의 가장 밝은 픽셀 값과 가장 어두운 픽셀 값을 이용해 영상을 낮은 밝기와 높은 밝기로 당겨준 것이다. 

 

 

 

메카리워즈 Image Map


모바일 버전으로 보기