더북(TheBook)

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 함수는 입력 영상 imgSrcamount 크기만큼의 소금&후추 잡음을 추가하고, 그 결과를 imgDst에 저장한다. amount는 소금&후추 잡음이 추가될 픽셀의 양을 제어하는 역할을 하며, 0부터 100 사이의 값을 전달하면 된다. IppNoiseSaltNPepper 함수의 전체 구현은 소스 8-13에 나타내었다.

소스 8-13 소금&후추 잡음 생성 함수(IppFilter.cpp)
void IppNoiseSaltNPepper(IppByteImage& imgSrc, IppByteImage& imgDst, int amount)
{
    int size = imgSrc.GetSize();

    imgDst = imgSrc;
    BYTE* pDst = imgDst.GetPixels();

    unsigned int seed = static_cast<unsigned int>(time(0));
    std::default_random_engine generator(seed);
    std::uniform_int_distribution<int> distribution(0, size - 1);

    int num = size * amount / 100;
    for (int i = 0; i < num; i++)
    {
        pDst[distribution(generator)] = (i & 0x01) * 255;
    }
}

소스 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)이다. 추가된 잡음의 그레이스케일 값이 원본 영상 픽셀의 값에 비해 차이가 크기 때문에 가우시안 잡음보다 더욱 지저분한 느낌의 결과 영상을 생성한 것을 볼 수 있다.

그림 8-25 소금&후추 잡음 추가
(a) 입력 영상
(b) amount = 5
(c) amount = 20
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.