728x90
728x90
2024.05.02 - [언어/C] - C언어 영상처리 Edge 구하기, threshold 구하기
[C언어 영상처리 Edge 구하기, threshold 구하기
edge는 명암, 휘도 등이 급격하게 변하는 곳 입니다.만약 물체가 동일한 색 이라면 경계의 색 차이가 크게 나지 않겠지요 ..그래도 색 차이가 큰 곳에서는 대부분 경계가 잘 드러납니다.x,y에 대한
yoonschallenge.tistory.com](https://yoonschallenge.tistory.com/480)
이전에 진행했던 내용이랑 비슷합니다.
x필터만 적용했을 때
y필터만 적용했을 때
x+y
threshold를 넘긴 부분만 표현했을 때
void sobelEdgeMap(double* y, int width, int height, BITMAPFILEHEADER bmpFile, BITMAPINFOHEADER bmpInfo, double* edgey) {
//padding
int padding = 2, pwidth = width + padding * 2, pheight = height + padding * 2, psize = pwidth * pheight;
double* py, * xy, * yy, * outy, sumf = 0;
py = (double*)calloc(pwidth * pheight, sizeof(double));
xy = (double*)calloc(width * height, sizeof(double));
yy = (double*)calloc(width * height, sizeof(double));
outy = (double*)calloc(width * height, sizeof(double));
int fsize = padding*2+1;
double* xfilter,* yfilter;
xfilter = (double*)calloc(fsize * fsize, sizeof(double));
yfilter = (double*)calloc(fsize * fsize, sizeof(double));
double xco, yco;
for (int i = 0; i < fsize; i++) {
for (int j = 0; j < fsize; j++) {
xco = (i - padding);
yco = (j - padding);
if (xco ==0 && yco == 0) {
xfilter[i * fsize + j] = 0;
yfilter[i * fsize + j] = 0;
}
else {
xfilter[i * fsize + j] = xco / (xco * xco + yco * yco);
yfilter[i * fsize + j] = yco / (xco * xco + yco * yco);
}
}
}
applyPaddingWithAverage(py, height, width, padding, y);
calFilter(xy, py, fsize, xfilter, height, width, pwidth);
calFilter(yy, py, fsize, yfilter, height, width, pwidth);
makeOutFile(bmpFile, bmpInfo, "xEdgeOut.bmp", xy);
makeOutFile(bmpFile, bmpInfo, "yEdgeOut.bmp", yy);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
outy[j * width + i] = sqrt(xy[j * width + i] * xy[j * width + i] + yy[j * width + i] * yy[j * width + i]);
}
}
CumulativeHisto(height, width, outy, bmpInfo.biSizeImage, (((bmpInfo.biBitCount / 8) * width) + 3) / 4 * 4, bmpFile, bmpInfo);
printf("threshold= %f\n", threshold);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
if (outy[j * width + i] > threshold) edgey[j * width + i] = 254;
}
}
makeOutFile(bmpFile, bmpInfo, "EdgeOut.bmp", outy);
makeOutFile(bmpFile, bmpInfo, "thresholdEdge.bmp", edgey);
free(py);
free(xy);
free(yy);
free(outy);
}
여러분의 Sobel edge filter 구현을 살펴보았습니다. 전반적으로 필터링 과정을 직접 구현하여 이미지의 에지를 감지하려는 시도는 인상적입니다. 다만, 몇 가지 개선점과 주의점을 지적하고 싶습니다:
- 필터 설계: 전형적인 Sobel 필터는 3x3 크기의 필터를 사용하며, 가로 및 세로 에지를 감지하기 위해 특정한 값이 설정되어 있습니다. 하지만 여기서는 필터 크기를 동적으로 생성하고 계산 방식이 전통적인 Sobel 필터와 다르게 보입니다. 각 점에 대해 가중치를 거리의 역수로 설정하여 필터를 적용하는 방식은 일반적인 Sobel 필터의 접근 방식과 다릅니다. Sobel 필터는 일반적으로 다음과 같은 형태를 취합니다:
Gx (수평 필터) Gy (수직 필터) [-1 0 1] [ 1 2 1] [-2 0 2] [ 0 0 0] [-1 0 1] [-1 -2 -1]
- 메모리 관리: 메모리를 동적으로 할당하고 해제하는 것은 좋은 접근 방식입니다. 그러나 프로그램의 복잡성과 크기가 커짐에 따라 메모리 누수가 발생할 수 있으므로 할당된 메모리가 모두 해제되었는지 확인하는 것이 중요합니다.
- 코드 최적화: 현재 코드에서는 여러 중첩 반복문을 사용하여 필터를 적용하고 있습니다. 이는 효율성을 떨어뜨릴 수 있습니다. 가능한 벡터화된 연산이나 효율적인 알고리즘을 사용하여 성능을 향상시킬 수 있습니다.
- 함수 분리:
sobelEdgeMap
함수는 매우 많은 작업을 수행하고 있습니다. 이 함수를 더 작은 기능별 함수로 분리하여 코드의 가독성과 유지보수성을 높이는 것이 좋습니다. - 에러 처리: 현재 코드에서는 입력 이미지의 유효성 검사나 함수 호출 결과에 대한 에러 처리가 부족합니다. 사용자가 예상치 못한 입력을 제공했을 때 이를 적절히 처리할 수 있는 로직을 추가하는 것이 중요합니다.
- 결과 검증: 코드가 의도대로 정확히 작동하는지 확인하기 위해, 몇 가지 테스트 이미지를 사용하여 결과를 검증하는 것이 좋습니다. 테스트 과정에서 필터의 파라미터를 조정하여 최적의 결과를 도출할 수 있습니다.
코드를 개선하고자 할 때는 이러한 지적 사항들을 참고하여 보다 효과적인 에지 감지 필터를 구현해 볼 수 있습니다. 필터의 특성을 잘 이해하고, 필요에 따라 조정하는 것이 중요합니다.
귀찮으니까 이정도만 보여주고 가겠습니다....
728x90
'언어 > C' 카테고리의 다른 글
C언어 영상처리 - data 파일에 넣은 사진 psnr 자동 계산하기 (0) | 2024.05.16 |
---|---|
C언어 영상처리 - 노이즈 제거, 업스케일링 기록용 (1) | 2024.05.16 |
C언어 영상처리 Edge 구하기, threshold 구하기 (2) | 2024.05.02 |
C언어 영상처리 - Rotation (0) | 2024.04.30 |
C언어 영상처리 최종 정리 - filter, padding, upsampling (1) | 2024.04.18 |