본문 바로가기
카테고리 없음

C# OpenCvSharp FFT(푸리에 변환) 이해 및 활용

by tasiklee 2025. 2. 27.

1. 푸리에 변환(FFT) 개요

푸리에 변환(Fourier Transform, FT)은 신호나 이미지를 주파수 도메인으로 변환하는 수학적 방법입니다. 이를 통해 공간(시간) 도메인에서 복잡하게 보이는 신호를 주파수 성분으로 분석할 수 있습니다.

이산 푸리에 변환(DFT, Discrete Fourier Transform)은 다음과 같은 수식으로 정의됩니다.

여기서,

반대로, 주파수 도메인에서 원본으로 되돌리는 역 푸리에 변환(IDFT, Inverse DFT)은 다음과 같이 정의됩니다.

FFT(Fast Fourier Transform)는 DFT를 빠르게 계산하는 알고리즘입니다.

2. OpenCvSharp에서 FFT 적용하기

OpenCvSharp은 OpenCV를 C#에서 사용할 수 있도록 래핑한 라이브러리로, FFT를 이용한 이미지 처리 기능을 제공합니다.

(1) FFT 수행 코드 예제

using OpenCvSharp;

class Program
{
    static void Main()
    {
        // 이미지 로드 (흑백 변환)
        Mat img = Cv2.ImRead("input.jpg", ImreadModes.Grayscale);
        img.ConvertTo(img, MatType.CV_32F);
        
        // FFT 수행을 위한 채널 분리
        Mat[] planes = { img, Mat.Zeros(img.Size(), MatType.CV_32F) };
        Mat complexImg = new Mat();
        Cv2.Merge(planes, complexImg);
        
        // 푸리에 변환 수행
        Cv2.Dft(complexImg, complexImg);
        
        // 스펙트럼 시각화
        Mat[] fftPlanes;
        Cv2.Split(complexImg, out fftPlanes);
        Mat magnitude = new Mat();
        Cv2.Magnitude(fftPlanes[0], fftPlanes[1], magnitude);
        
        // 로그 변환으로 가시화
        magnitude += Scalar.All(1);
        Cv2.Log(magnitude, magnitude);
        
        // 중앙 이동 (시각화 개선)
        ShiftDFT(magnitude);
        
        // 결과 출력
        Cv2.Normalize(magnitude, magnitude, 0, 255, NormTypes.MinMax);
        magnitude.ConvertTo(magnitude, MatType.CV_8U);
        Cv2.ImWrite("fft_output.jpg", magnitude);
    }

    static void ShiftDFT(Mat mag)
    {
        int cx = mag.Cols / 2;
        int cy = mag.Rows / 2;
        
        Mat q0 = new Mat(mag, new Rect(0, 0, cx, cy));
        Mat q1 = new Mat(mag, new Rect(cx, 0, cx, cy));
        Mat q2 = new Mat(mag, new Rect(0, cy, cx, cy));
        Mat q3 = new Mat(mag, new Rect(cx, cy, cx, cy));
        
        Mat tmp = new Mat();
        q0.CopyTo(tmp);
        q3.CopyTo(q0);
        tmp.CopyTo(q3);
        
        q1.CopyTo(tmp);
        q2.CopyTo(q1);
        tmp.CopyTo(q2);
    }
}

(2) 코드 설명

  1. 이미지 로드 및 변환: FFT 연산을 위해 이미지를 float 타입으로 변환
  2. 채널 분리: OpenCV에서 푸리에 변환은 복소수를 사용하므로 새로운 Mat 배열 생성
  3. Dft() 함수 적용: Cv2.Dft()를 통해 푸리에 변환
  4. 스펙트럼 분석: 주파수 정보를 보기 위해 Magnitude()를 사용하여 크기 계산
  5. 로그 변환: FFT 결과는 대부분 큰 값을 가지므로 Cv2.Log()로 조정
  6. 중앙 이동: FFT 결과의 원점을 중앙으로 이동하여 시각화
  7. 정규화 및 저장: 결과를 0~255 범위로 정규화하여 이미지로 저장

3. 활용 예시

(1) 노이즈 제거

고주파 성분을 제거하면 노이즈를 줄일 수 있습니다. 특정 주파수 대역을 제거한 후 역 FFT(IDFT)를 적용하여 이미지를 복원합니다.

(2) 엣지 검출

고주파 영역을 강조하면 이미지의 엣지(경계선)를 추출하는 효과를 얻을 수 있습니다.

(3) 패턴 분석

주파수 도메인에서 특정 패턴이 존재하는지 분석할 때 활용됩니다.

4. 프로세스 시각화

FFT 과정은 다음과 같이 요약할 수 있습니다.

  1. 입력 이미지 (공간 도메인)
  2. FFT 변환 (주파수 도메인)
  3. 스펙트럼 시각화
  4. 필터링 (예: 저주파 통과 필터, 고주파 통과 필터)
  5. 역 FFT 변환 (공간 도메인 복원)

5. 결론

C#의 OpenCvSharp을 활용하면 FFT를 통해 주파수 분석, 노이즈 제거, 엣지 검출과 같은 다양한 이미지 처리가 가능합니다. 본문에서 다룬 코드와 과정을 활용하여 보다 효율적인 영상 처리를 수행할 수 있습니다.