더북(TheBook)
소스 11-8 허프 변환을 이용한 직선 검출 함수(IppFeature.cpp)
void IppHoughLine(IppByteImage& img, std::vector<IppLineParam>& lines, int threshold)
{
    register int i, j;

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

    BYTE** ptr = img.GetPixels2D();
    int num_rho = static_cast<int>(sqrt((double)w*w + h*h) * 2);
    int num_ang = 360;

    //-------------------------------------------------------------------------
    // 0 ~ PI 각도에 해당하는 sin, cos 함수의 값을 룩업테이블에 저장
    //-------------------------------------------------------------------------



    float* sin_tbl = new float[num_ang];
    float* cos_tbl = new float[num_ang];

    for (i = 0; i < num_ang; i++)
    {
        sin_tbl[i] = sin(i * PI_F / num_ang);
        cos_tbl[i] = cos(i * PI_F / num_ang);
    }

    //-------------------------------------------------------------------------
    // 축적 배열(Accumulate array) 생성
    //-------------------------------------------------------------------------

    IppIntImage imgAcc(num_ang, num_rho);
    int** pAcc = imgAcc.GetPixels2D();

    int m, n;
    for (j = 0; j < h; j++)
    for (i = 0; i < w; i++)
    {
        if (ptr[j][i] > 128)
        {
            for (n = 0; n < num_ang; n++)
            {
                m = static_cast<int>(floor(i * sin_tbl[n] + j * cos_tbl[n] + 0.5f));
                m += (num_rho / 2);

                pAcc[m][n]++;
            }
        }
    }

    //-------------------------------------------------------------------------
    // 임계값보다 큰 국지적 최댓값최댓값을 찾아 직선 성분으로 결정
    //-------------------------------------------------------------------------

    lines.clear();
    int temp;
    for (m = 0; m < num_rho; m++)
    for (n = 0; n < num_ang; n++)

    {
        temp = pAcc[m][n];
        if (temp > threshold)
        {
            if (temp > pAcc[m - 1][n] && temp > pAcc[m - 1][n + 1] &&
                temp > pAcc[m][n + 1] && temp > pAcc[m + 1][n + 1] &&
                temp > pAcc[m + 1][n] && temp > pAcc[m + 1][n - 1] &&
                temp > pAcc[m][n - 1] && temp > pAcc[m - 1][n - 1])
            {
                lines.push_back(IppLineParam(m - (num_rho / 2), n * PI / num_ang, pAcc[m][n]));
            }
        }
    }


    //-------------------------------------------------------------------------
    // 동적 할당한 메모리 해제
    //-------------------------------------------------------------------------

    delete[] sin_tbl;
    delete[] cos_tbl;
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.