8.4.2 소금&후추 잡음 생성
영상에 추가되는 잡음 중에는 소금&후추 잡음salt&pepper noise라는 독특한 이름의 잡음도 존재한다. 이러한 이름이 붙은 이유는 잡음이 마치 소금과 후추처럼 흰색 또는 검정색으로 이루어지기 때문이다. 즉, 소금&후추 잡음은 입력 영상의 임의의 좌표 픽셀 값을 0 또는 255로 만드는 형태의 잡음이다. 이러한 소금&후추 잡음은 주로 카메라 센서 자체의 에러에 의해 발생하거나 또는 광학 신호를 전기적 신호로 변환하는 과정에서 다양한 원인에 의해 발생한다. 여기서는 소금&후추 잡음을 프로그램을 통해 생성하는 방법에 대해 알아볼 것이며, 이후 8.5절에서 소금&후추 형태의 잡음을 제거하는 방법에 대해 설명할 것이다.
앞서 설명한 가우시안 잡음은 영상 내의 모든 픽셀에 대해 잡음을 추가하는 형태로 코드를 구현하였다. 그러나 소금&후추 잡음은 영상 내의 임의의 픽셀에 대해서만 그 값을 0 또는 255로 설정하면 된다. 임의의 픽셀을 선택하기 위해 C/C++에서 제공하는 rand 함수를 이용할 수 있다. 그러나 앞서 가우시안 분포의 난수 발생을 위해 std::normal_distribution을 사용한 것과 유사하게 여기서는 std::uniform_int_distribution을 이용하여 소금&후추 잡음을 추가할 픽셀 위치를 구하려고 한다. 예를 들어 0부터 100 사이의 난수 10개를 발생시키려면 다음과 같은 형태로 코드를 작성하면 된다.
unsigned int seed = static_cast<unsigned int>(time(0)); std::default_random_engine generator(seed); std::uniform_int_distribution<int> distribution(0, 100); for (int i = 0; i < 10; i++) std::cout << distribution(generator) << std::endl;
그러면 실제로 영상에 소금&후추 잡음을 추가하는 함수를 작성해보자. 함수의 이름은 IppNoiseSaltNPepper를 사용하기로 하고, IppFilter.h 파일에 아래와 같이 함수 선언을 추가하자.
void IppNoiseSaltNPepper(IppByteImage& imgSrc, IppByteImage& imgDst, int amount);
IppNoiseSaltNPepper 함수는 입력 영상 imgSrc에 amount 크기만큼의 소금&후추 잡음을 추가하고, 그 결과를 imgDst에 저장한다. amount는 소금&후추 잡음이 추가될 픽셀의 양을 제어하는 역할을 하며, 0부터 100 사이의 값을 전달하면 된다. IppNoiseSaltNPepper 함수의 전체 구현은 소스 8-13에 나타내었다.
소스 8-13에서 size는 영상 전체 픽셀 개수, num은 잡음이 추가될 픽셀의 개수를 나타낸다. 만약 입력 영상이 100×100 크기의 영상이고, amount 값이 20이면 잡음이 추가될 픽셀의 개수는 100×100×(20/100) = 2000개이다. 입력 영상에서 잡음이 추가될 좌표는 distribution(generator) 코드를 사용하여 구하였다. distribution(generator)은 0부터 (size - 1) 사이의 균일한 난수를 발생시킨다. 그리고 (i & 0x01) * 255를 픽셀 값으로 대입하였는데, i가 짝수이면 0이고, i가 홀수이면 255가 대입된다.
그림 8-25는 실제 영상에 소금&후추 잡음을 추가한 예를 보여준다. 그림 8-25(a)는 입력 영상인 bookshelf.bmp 파일이다. 이 영상에 대해 amount = 5만큼의 소금&후추 잡음을 추가한 결과가 그림 8-25(b)이고, amount = 20 만큼의 잡음을 추가한 결과가 그림 8-25(C)이다. 추가된 잡음의 그레이스케일 값이 원본 영상 픽셀의 값에 비해 차이가 크기 때문에 가우시안 잡음보다 더욱 지저분한 느낌의 결과 영상을 생성한 것을 볼 수 있다.