WPF OpenCV 프로젝트 #13: 이미지 위에 도형 그리기 (선, 원, 사각형) 및 UI 계층 구조 분석

Line, Circle, Rectangle 과 같이 이미지 위에 도형 그리기UI 계층 구조를 분석하여 WPF OpenCV 프로젝트에 추가하겠습니다. 지난 포스팅(#12)까지 우리는 ROI(관심 영역)를 사각형으로 그리고, 수정하고, 저장하는 기능까지 모두 구현했습니다. 사실상 ROI 기능은 그것으로 충분해 보입니다.

하지만 영상 처리를 진행하다 보면 단순히 네모난 영역만 자르는 게 아니라, 두 지점 사이의 거리를 측정(Line)하거나, 동그란 제품의 크기를 재거나(Circle), 특정 영역의 균일도(Uniformity)를 봐야 하는 경우가 빈번합니다.

그래서 이번에는 ROI 사각형을 넘어, 선(Line), 원(Circle), 사각형(Rectangle) 등 다양한 도형을 그리는 기능을 추가해 보겠습니다.

UI 계층 구조

본격적인 코딩에 앞서, 우리가 만든 UI 구조를 한번 짚고 넘어갑시다. 이 구조는 제가 “WPF 영상 처리 UI의 정석“이라고 감히 부르고 싶은 패턴입니다. 아래의 UI 이미지에 계층 구조를 표현했는데, 이미지와 아래의 계층 구조를 같이 참고해 주세요.

UI에서 이미지 뷰 영역의 계층 구조

계층 구조

ZoomBorder (최상위) └── ImgCanvas (무한 영역) ├── ImgView (원본 이미지) └── OverlayCanvas (투명 도화지)

왜 이렇게 복잡하게 만들었을까요? 다 이유가 있습니다.

  1. ZoomBorder (할아버지): 화면의 틀을 잡고 마우스 입력(휠, 클릭, 드래그)을 총괄합니다. 이미지가 10배 확대되어 화면 밖으로 튀어나가도 ClipToBounds="True" 속성 덕분에 UI가 깨지지 않게 막아줍니다.
  2. ImgCanvas (아버지): 자식들이 아무리 커져도(고화질 이미지) 군말 없이 받아주는 완충지대입니다. 이게 없으면 Fit to Screen 같은 기능을 구현할 때 좌표계가 꼬여버립니다.
  3. ImgView (형): 실제 이미지를 보여줍니다. 확대/축소(RenderTransform)의 주인공이죠.
  4. OverlayCanvas (동생): 여기가 핵심입니다! 이미지 위에 그림을 그리는 투명 필름입니다. 형(ImgView)과 바인딩(Binding ElementName=ImgView)되어 있어서, 형이 커지면 나도 커지고, 형이 움직이면 나도 따라 움직입니다.

덕분에 우리는 “이미지가 확대된 상태인가?”를 고민할 필요 없이, 그냥 이미지 좌표 기준으로 그리기만 하면 됩니다. 나머지는 WPF가 알아서 동기화해주니까요.

XAML :메뉴 추가

먼저 사용자가 어떤 도형을 그릴지 선택할 수 있게 메뉴를 추가합니다. MainWindow.xaml의 리소스(Resource) 영역에 아래 코드를 추가해 주세요.

그리기 로직 구현 (Code Behind)

이제 MainWindow.xaml.cs로 가서 실제 그리기 로직을 작성합니다.

변수 및 모드 설정

먼저 현재 그리기 모드와 임시 도형을 저장할 변수를 선언합니다.

MouseDown : 그리기 시작

사용자가 마우스를 클릭하면, 선택된 모드에 맞는 도형(Line, Ellipse, Rectangle)을 생성해서 OverlayCanvas에 올립니다. 아직 크기는 0입니다.

MouseMove : 그리기

마우스를 드래그할 때 실시간으로 도형의 크기를 업데이트합니다. 사각형이나 원을 그릴 때 마우스를 왼쪽이나 위로 드래그하는 경우(음수 좌표)까지 고려해야 하므로 Math.MinMath.Abs를 사용합니다.

MouseUp : 그리기 완료

마우스를 놓으면 그리기를 멈추고 임시 변수를 비웁니다.

실행 결과

이제 실행해 볼까요? 이미지를 불러오고 우클릭 메뉴에서 Draw Line, Draw Circle 등을 선택한 뒤 마음껏 드래그해 보세요. 이미지를 확대하거나 이동해도 그려둔 도형들이 이미지에 찰싹 붙어서 잘 따라다니는 것을 확인할 수 있습니다.

이제 UI 기능 구현은 얼추 마무리되었습니다. 다음 포스팅부터는 이렇게 그린 도형들을 활용해서 진짜 OpenCV 영상 처리를 어떻게 하는지 다뤄보도록 하겠습니다.

참고 자료

WPF Shapes: Line, Rectangle, Ellipse 등 WPF 기본 도형 클래스에 대한 설명입니다.
https://learn.microsoft.com/ko-kr/dotnet/desktop/wpf/graphics-multimedia/shapes-and-basic-drawing-in-wpf-overview
OverlayCanvas (Canvas Class): 절대 좌표를 사용하는 Canvas 패널의 특성을 이해하는 데 도움이 됩니다.
https://learn.microsoft.com/ko-kr/dotnet/api/system.windows.controls.canvas
ZIndex (Panel.ZIndex): 여러 도형이 겹칠 때 순서를 정하는 속성입니다. (이번엔 사용 안 했지만 알아두면 좋습니다.)
https://learn.microsoft.com/ko-kr/dotnet/api/system.windows.controls.panel.zindex

댓글 남기기