영상정보는 0에서 255까지의 값을 가지고 있어서 필요에 따라 영상의 값들을 조작하거나 변경하는 영상처리를 수행한다. 그러나 컴퓨터 시스템의 특성과 영상처리의 단순화를 위하여 이진화 하는 작업이 필요한 경우가 많이 존재한다. 영상 이진화는 0에서 255까지의 값을 0과 1의 값으로 변환하는 작업이다. 실제 영상에서는 0과 1 모두 검은 값으로 표시되기 때문에 1은 255로 변환하여 표시하여 준다. 다음 이미지는 영상의 평균 값을 구하여 평균보다 작은 값은 0으로, 평균 이상의 값들은 모두 255로 변환하여 출력한 결과이다.
위의 이미지는 lena 영상을 평균 값을 기준으로 이진화를 시킨 모습이다. 이미지의 평균값을 구하는 함수와 평균값을 기준으로 영상을 이진화하는 함수는 다음 코드와 같다.
doubleaverage(uchar** img, int Row, int Col)// 이미지의 전체 평균값을 구하는 함수 { double sum = 0, avg; int i, j;
for (i = 0; i < Row; i++) { for (j = 0; j < Col; j++) { sum += img[i][j]; } } avg = sum / ((double)Row * Col); printf("Average of Image %1f \n", avg); return avg;
}
voidmakeBinary(uchar** img, uchar** out, int Row, int Col, double avg)// 이미지 2진화 { int i, j; for (i = 0; i < Row; i++) { for (j = 0; j < Col; j++) { if (img[i][j] > avg) out[i][j] = 255; else out[i][j] = 0; // 평균보다 큰 값은 255, 작은 값은 0 대입
} } }
이진화 영상은 평균값 이외에도 특정한 threshold 값을 지정함으로써 원하는 형태의 이진화 영상을 구할 수 있다. 각각의 영상처리 역할과 분야에 따라 이진화 영상은 다양한 방법으로 사용될 수 있다.
int hopeAvg; printf("원하는 평균값 입력 : "); scanf_s("%d", &hopeAvg); // 원하는 평균값 구하기 if (msum < hopeAvg) { // 원본 이미지의 평균값이 원하는 평균값 보다 작은 경우 for (gamma = 1; gamma < 4; gamma += 0.005) { // 연산량을 줄이기 위해 gamma = 1(원본 이미지) 부터 시작 PowImg(img, outimg, Row, Col, gamma); msum = average(outimg, Row, Col); printf("gamma = %f\n", gamma);
if (msum >= hopeAvg) break; } } else// 원본 이미지의 평균값이 원하는 평균값 이상인 경우 { for (gamma = 1; gamma > 0; gamma -= 0.005) { // 연산량을 줄이기 위해 gamma = 1(원본 이미지) 부터 시작 PowImg(img, outimg, Row, Col, gamma); msum = average(outimg, Row, Col); printf("gamma = %f\n", gamma);
if (msum < hopeAvg) break;
} }
원하는 평균값을 입력받아 gamma값을 키우거나, 줄이며 원하는 평균값이 나오면 break로 반복문을 빠져나오면 된다. 이러한 방식으로 부르트 포스 알고리즘을 적용하여 해결할 수 있다. 부르트 포스 알고리즘이란, 모든 경우의 수를 다 해보며 원하는 값을 찾는 것인데 이러한 방식은 시간이 오래걸리므로 조금이라도 연산 시간을 줄이기 위해 gamma값을 1부터 시작하도록 하였다. 원영상의 gamma값은 1을 가지며 원하는 평균이 1보다 작다면 1부터 줄여가고, 1보다 크다면 1부터 키워가는 방식이다. 원하는 값에 도달하면 반복을 멈추고 이미지를 생성한다.