WPF OpenCV 프로젝트 #18: Normalize (정규화)


Normalize (정규화) 처리를 WPF OpenCV 프로젝트에 구현하도록 하겠습니다.
지난 포스팅(#17)에서는 영상의 밝기 분포를 확인하는 히스토그램(Histogram)을 구현했습니다. 히스토그램을 통해 “아, 이 사진은 픽셀들이 너무 어두운 곳에만 몰려있네?” “어라 ! 이 사진은 픽셀들이 너무 밝은 곳에만 몰려있네? “라는 걸 알았다면, 이제는 그걸 수정할 차례입니다.

바로 Normalize (정규화) 기능을 통해서 말이죠. 이번에는 정규화 라는 녀석의 개념을 제가 가능하다면 아주 쉽게 이해(?) 있도록 하고, 프로젝트에 적용해 보겠습니다.

Normalize (정규화)

정규화라는 말이 참 어렵게 들리지만, 사실 우리는 일상에서 자주 쓰고 있습니다. 쉬운 예로 ‘시험 성적’을 들어볼까요?

A 학생: 25문제 중 20문제 정답
B 학생: 20문제 중 19문제 정답

누가 공부를 더 잘했을까요? 단순히 맞힌 개수(20개 vs 19개)만 보면 A가 잘한 것 같지만, 문제 수가 다릅니다. 공정하게 비교하려면 ‘100점 만점’ 기준으로 환산해야겠죠?

  • A 학생: (20 / 25) * 100 = 80점
  • B 학생: (19 / 20) * 100 = 95점

이렇게 서로 다른 기준(25문제, 20문제)을 하나의 공통된 기준(100점 만점)으로 맞추는 과정, 이것이 바로 정규화(Normalize)입니다.

영상 처리에서도 마찬가지입니다. 픽셀 값이 100~150 사이에 옹기종기 모여 있어서 흐릿한 사진을, 0~255 전체 구간으로 쫙 펴주면(Stretch) 훨씬 선명한 사진이 됩니다. 이를 구간 정규화(MinMax Normalize)라고 부릅니다.

Normalize 구현

이번 구현의 핵심은 “정규화를 실행하고, 그 결과가 어떻게 변했는지 히스토그램 팝업으로 확인하는 것”입니다. 이를 위해 지난 시간에 만든 히스토그램 창을 재활용할 것입니다. 그래서 지난 포스팅 글의 마지막에 다음 포스팅은 더 쉬울 거라고 미리 언급했던 거죠.

  1. AlgorithmParameters.cs: NormalizeParams 클래스 추가 (Alpha, Beta, Type 설정)
  2. MainWindow.xaml: 정규화 파라미터 조절용 UI 추가
  3. OpenCVService.cs: Cv2.Normalize 적용 및 결과 히스토그램 재계산 로직 추가
  4. MainViewModel.cs: 메뉴 등록 및 팝업창 연결

Step 1: NormalizeParams 클래스 정의 (Model)

먼저 AlgorithmParameters.cs에 정규화 설정을 담을 클래스를 만듭니다. OpenCV의 Normalize 함수는 Alpha, Beta, NormType이라는 3가지 핵심 인자를 받습니다.

Step 2: ViewModel 연결

MainViewModel.cs에서 메뉴를 등록하고, 정규화 실행 시에도 히스토그램 팝업이 뜨도록 로직을 수정합니다. (Post #17에서 만든 팝업을 재 사용합니다!) 아래의 코드 부분에 각 함수별로 수정 및 추가해야 하는 부분만 적었습니다. MainViewModel 생성자 함수, CreateParametersForAlgorithm() 함수에서 NormalizeParams 클래스 객체를 생성하도록 하고, ApplyAlgorithm () 함수에서는 히스토그램 그래프가 생성되어 보여 지는 조건을 Normalize 에서도 가능하도록 수정하였습니다. (주석을 잘 참조하여 주세요)

Step 3: UI 구성 (View)

MainWindow.xaml<Window.Resource> </Window.Resource> 섹션에 NormalizeParams를 위한 UI DataTemplate을 만들고, AlphaBeta 값을 슬라이더로 조절할 수 있도록 아래의 코드를 추가합니다.

Step 4: OpenCVService : Normalize

가장 중요한 OpenCVService.cs입니다. 여기서는 두 가지 작업을 하도록 하죠.

  1. CalculateHistogramForPopup: 결과 이미지의 히스토그램을 다시 계산하는 도우미 함수 추가.
  2. ProcessImageAsync: 실제 Cv2.Normalize 실행.

실행 결과 및 분석

이제 빌드 후 실행해 보도록 하겠습니다. 흐릿한(명암 대비가 낮은) 이미지를 불러와 히스토그램을 실행하여 분석한 그래프는 아래와 같이 실행 결과를 보여줍니다.

아래의 이미지는 바로 위 원본 이미지를 Nomalize 처리를 한 이미지와 Nomaliize 처리된 이미지의 히스토그램 분석 그래프입니다. 이때 조절한 파라미터는 MinMAX Type, MIN: 60, MAX:180 을 적용하여 실행하였습니다. 전체적으로 약간 어두워진 것 같지 않나요? 아주 어두운 부분(60보다 작은 픽셀 값)은 밝아지고, 아주 밝은 부분(180보다 밝은 픽셀 값)은 어두워지게 처리가 된거니까요. (이해하시죠?) 이 포스팅을 보고 계신 분들께서 보유한 이미지 중 흐릿한 (명암 대비가 낮은) 이미지를 한번 분석해 보세요. 아마도 음~ 이런 거구나 할 겁니다.
다음에는 이와 비슷하지만 조금 다른, 평탄화(Equalize)에 대해 다뤄보겠습니다.


참고 자료

[Post #17] 히스토그램: [WPF OpenCV Project #17] – 히스토그램 분석 및 그래프 그리기
Cv2.Normalize: OpenCV 공식 문서 (Normalize) – 수학적 수식과 파라미터 상세 설명
NormTypes: OpenCVSharp API – 정규화 타입 열거형 설명

댓글 남기기