더북(TheBook)

그러면 이제 가우시안 필터링을 수행하는 함수를 작성해보자. 함수의 이름은 IppFilterGaussian을 사용하기로 하고, IppFilter.h 파일에 아래와 같이 함수 선언을 추가하자.

void IppFilterGaussian(IppByteImage& imgSrc, IppFloatImage& imgDst, float sigma);

IppFilterGaussian 함수는 입력 영상 imgSrc에 대해 표준 편차가 sigma인 가우시안 필터링을 수행하고, 그 결과를 imgDst에 저장한다. 이때 결과 영상 imgDst의 자료형이 IppFloatImage인 것에 주목하기 바란다. 가우시안 필터링은 내부적으로 정교한 실수 연산을 수행하기 때문에 결과 영상 또한 실수형으로 저장하도록 설정하였다. IppFilterGaussian 함수의 전체 구현은 소스 8-4에 나타내었다.

소스 8-4 가우시안 필터 구현 함수(IppFilter.cpp)
const float PI_F = 3.14159265358979323846f;

void IppFilterGaussian(IppByteImage& imgSrc, IppFloatImage& imgDst, float sigma)
{
    register int i, j, k, x;

    int w = imgSrc.GetWidth();
    int h = imgSrc.GetHeight();

    imgDst.CreateImage(w, h);

    BYTE** pSrc = imgSrc.GetPixels2D();
    float** pDst = imgDst.GetPixels2D();

    //-------------------------------------------------------------------------
    // 1차원 가우시안 마스크 & 실수 연산을 위한 버퍼 이미지 생성
    //-------------------------------------------------------------------------

    int dim = static_cast<int>(2 * 4 * sigma + 1.0);
    if (dim < 3) dim = 3;
    if (dim % 2 == 0) dim++;
    int dim2 = dim / 2;

    IppFloatImage imgMask(dim, 1);
    float* pMask = imgMask.GetPixels();

    for (i = 0; i < dim; i++)
    {
        x = i - dim2;
        pMask[i] = exp(-(x * x) / (2 * sigma * sigma)) / (sqrt(2 * PI_F) * sigma);
    }

    IppFloatImage imgBuf(w, h);
    float** pBuf = imgBuf.GetPixels2D();

    //-------------------------------------------------------------------------
    // 세로 방향 마스크 연산
    //-------------------------------------------------------------------------

    float sum1, sum2;
    for (i = 0; i < w; i++)
    for (j = 0; j < h; j++)
    {
        sum1 = sum2 = 0.f;

        for (k = 0; k < dim; k++)
        {
            x = k - dim2 + j;

            if (x >= 0 && x < h)
            {
                sum1 += pMask[k];
                sum2 += (pMask[k] * pSrc[x][i]);
            }
        }

        pBuf[j][i] = sum2 / sum1;
    }

    //-------------------------------------------------------------------------
    // 가로 방향 마스크 연산
    //-------------------------------------------------------------------------

    for (j = 0; j < h; j++)
    for (i = 0; i < w; i++)
    {
        sum1 = sum2 = 0.f;

        for (k = 0; k < dim; k++)
        {
            x = k - dim2 + i;

            if (x >= 0 && x < w)
            {
                sum1 += pMask[k];
                sum2 += (pMask[k] * pBuf[j][x]);
            }
        }

        pDst[j][i] = sum2 / sum1;
    }
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.