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; }