파이썬 Python 기반에 Deep Learning(D/L) 활용 시 GPU 및 CUDA 환경 설정에 대한 설명입니다. 환경 설정에 방향은 두 가지 정도로 나뉠 수 있습니다. 개인적인 활용에서는 GPU 환경에 맞춰 CUDA 및 Pytorch 최신 환경으로 구성할 수 있고, 업무 환경 상 Pytorch 특정 버전에 맞춰 환경을 구성해야 될 수도 있겠습니다.

 

환경 설정에서는 GPU 드라이버, CUDA, cuDNN, Pytorch 버전이 호환되어야 정상 활용 가능하므로 개인적인 환경에 따라 다를 수 있겠지만 상황에 따라 재설치 및 Rollback 시간이 상당하므로 가능하면 환경설정에 시간 소모를 줄이고 개발에 집중하는 것이 좋다고 생각합니다.

 

현 블로그에서는 기본적으로 GPU 환경 조건이 충분하다는 상황에서 Pytorch 1.13 기준에서 환경 설정 과정을 설명합니다.

 

1. GPU 환경 확인: cmd 실행 후 ‘nvidia-smi’ 확인, 드라이버 업데이트

CUDA 버전과 드라이버 버전 확인 합니다. cmd 창에 출력되는 CUDA 버전은 지원 가능한 버전이므로 이하 버전들도 적용 가능합니다. 23년 12월 기준 RTX 30 시리즈 드라이버 최신 업데이트 시 CUDA 12.x와 드라이버 5xx.xx 입니다. 아래 주소 확인 후 최신 업데이트 합니다.

 

NVIDIA Driver: docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions

 

 

 

2. Pytorch 1.13 기준 CUDA 버전 확인

파이토치 설치 방법은 conda와 pip으로 구분되어 있으며 개인 환경에 맞춰 CUDA 환경 구성 후 설치하면 됩니다. 현 시점에서는 CUDA 버전만 확인합니다. 파이토치 1.13은 CUDA 11.6x와 11.7x와 연동되는 것을 확인 할 수 있습니다.

 

pytorch.org/get-started/previous-versions/

 

 

3. GPU 환경에 따른 Capability

추가로 본인 GPU 환경에 따른 Capability를 확인해야 됩니다. RTX 3050/30603070/3080/3090의 경우 Capability 8.6 이며, 이는 CUDA 11.1 이상에서 활용 가능함을 확인 할 수 있습니다.

 

GPU Capability: en.wikipedia.org/wiki/CUDA

 

 

 

4. CUDA 환경 구축 및 Pytorch 설치

파이토치 1.13 호환성 기준으로 Capability 고려하여 CUDA 11.7.x 설치 후 cuDNN 11.x 설치하면 됩니다. cuDNN의 경우 압축 해제 후 파일들을 CUDA 설치된 폴더에 복사/붙여넣기하여 환경 구성을 완료합니다. 이후 앞에서 확인한 파이토치 1.13을 pip 또는 conda로 최종 설치합니다.

 

CUDA: developer.nvidia.com/cuda-toolkit-archive

cuDNN: developer.nvidia.com/rdp/cudnn-archive

 

 

 

5. 환경 구성 및 동작 확인: nvcc - -version

cmd 창에서 ‘nvcc –V’ 또는 ‘nvcc –version’으로 설치 확인 할 수 있습니다. 아래 코드를 통해 GPU 사용 및 할당 가능한지 확인할 수 있습니다.

 

import torch

print(torch.cuda.is_available()) # True면 활용 가능

 

추가로 실무에서 아래 코드로 디바이스 자동 지정 할 수 있습니다.

device = torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu')

칼라 분석 처리 목적에 따라 RGB 공간에서 다른 공간으로 변환할 있습니다. OpenCV에서 cvtColor 함수를 사용할 있으며 RGB 공간에서 변환할 경우에는 채널의 순서를 명시적으로 지정해야 합니다. OpenCV 기본 형식은 RGB라고 하는 경우가 많지만 실제로는 BGR입니다. 24비트 이미지의 번째 바이트는 8비트 Blue 성분이고 번째 바이트는 Green, 번째 바이트는 Red 됩니다.

 

아래는 C언어와 Python 활용 따른 예이며 src는 원본, dst는 결과입니다. cvtColor 함수를 활용하면 간단히 색 공간변환을 할 수 있습니다.

 

(C언어): cvtColor(src, dst, cv::COLOR_RGB2GRAY);

(Python): dst = cv.cvtColor(src, cv.COLOR_RGB2GRAY)

 

Luv 같은 비선형 변환은 입력 RGB 영상을 적절한 범위로 정규화하여 처리해야 합니다. 예를 들어 8비트 영상에서 직접 변환된 32비트 부동소수점 영상이 있으면 함수에서 가정하는 0.1 아니라 0.255 범위를 갖게 됩니다. 따라서 cvtColor 호출하기 전에 아래 예와 같이 먼저 영상을 축소해야 합니다.

 

src *= 1./255;

cvtColor(src, dst, COLOR_BGR2Luv);

 

아래는 RGB 공간에서 수식적 변환 관계(Gray, HSV, HLS, Lab)이며  cvtColor의 변환 코드 선택으로 간편히 변환할 수 있습니다. cv::COLOR_RGB2HSV (또는 cv::COLOR_BGR2HSV) 등.

RGB to GRAY 변환

RGB to Gray: Y = 0.299⋅R+0.587⋅G+0.114⋅B

 

RGB to HSV 변환 (Hue, Saturation, Value)

R, G, B 부동 소수점 형식으로 변환하여 [0~1] 범위에 맞게 스케일링 계산 적용합니다.

 

RGB to HLS 변환 (Hue, Luminance, Saturation)

R, G, B 부동 소수점 형식으로 변환하여 [0~1] 범위에 맞게 스케일링  계산 적용합니다.

 

RGB to Lab 변환

R, G, B 부동 소수점 형식으로 변환하여 [0~1] 범위에 맞게 스케일링  계산 적용합니다.

(docs.opencv.org 참조)

인간의 시각 시스템 The Human Visual System은 가시광선(400nm~700nm) 영역에서 수십만 가지의 색상을 구별 할 수 있지만 회색 음영 변화의 경우 약 100가지 정도를 구별할 수 있습니다. 색상 정보 Color Information도 이미지에 다양하게 포함 될 수 있기 때문에 색상 정보에 기반하여 객체 식별 및 추출 등과 같은 이미지 분석에 활용할 수 있습니다.

 

그레이 이미지 Gray Image는 무채색으로 레벨의 크기 Intensity로 표현되므로 에너지에 의한 물리적 양으로 볼 수 있습니다. 반면 밝기 Brightness 와 휘도 Luminance는 색의 인식적 지각에 의해 결정되므로 심리적 특성에 가깝습니다. 예를 들어 파란색과 초록색이 동일하게 강렬한 경우 파란색은 초록색보다 훨씬 더 어둡게 인식됩니다. 색상은 주로 물체의 반사율 특성에 따라 달라지며 빨간색과 초록색을 모두 반사하는 물체는 녹색이지만 빛을 비추는 빨간색이 없을 때 초록색으로 보이고 반대로 녹색이 없을 때는 빨간색으로 보입니다.

 

색상 모델 Color Model은 3D 좌표계로 표현되며 특정 모델 내에서 구성 가능한 모든 색상을 정의하고 특정 색상을 지정할 수 있도록 합니다. 이미지 분석과 처리를 위한 색상 모델들에는 RGB, CMY, HSI, YIQ, HSV, Lab 등 다양합니다. 현 블로그에서는 일반적인 RGB 외 몇 모델을 살펴 보겠습니다. OpenCV 활용 부분에 색상 모델 좌표 변환 설명을 추가하니 참고해 보면 좋겠습니다.

 

RGB Model

그림에서 같이 직각 좌표계로 표현되는 RGB 모델은 Red, Green, Blue의 3개의 축으로 구성됩니다. 회색 Gray은 검정색 Black과 흰색 White을 잇는 선으로 Spectrum이 표현됩니다. RGB 모델은 실생활에 많이 활용되며 칼라 모니터와 대부분의 비디오 카메라에 사용됩니다.

CMY Model

CMY 모델은 Cyan, Magenta, Yellow를 축으로 하는 색상 모델로, RGB 모델의 경우 특정 색상을 얻기 위해 검정색에 무엇을 추가하는 가산 혼합 Additive Model인 반면 CMY는 흰색에서 무엇을 빼는 Subtractive Model 입니다. 주로 칼라 프린터 및 인쇄물에 사용됩니다. 아래 그림은 색상 인식에 대한 Tristimulus Theory로 좌측은 RGB, 우측은 CMY Model을 나타냅니다.

 

HSI Model

HSI 모델은 Hue 색상, Saturation 채도, 크기(세기) Intensity의 3가지 축에 의해 색상을 정의할 수 있습니다. 그림은 HSI의 색상 입체 공간을 나타내며, Red/Green/Blue는 [0,1]범위로 정규화 됩니다. Hue는 0~360도의 각도, Saturation은 0~1, Intensity는 0(Black)~1(White)로 설정할 수 있으며 RGB 모델 간 변환 관계는 아래와 같습니다.

(homepages.inf.ed.ac.uk 참조)

(docs.opencv.org 참조)

영상처리의 가장 기본이 되는 연산 중에는 픽셀 Pixel 연산과 마스크 Mask 연산이 있습니다. 현 블로그에서는 픽셀 간 산술 연산 Arithmetic Operation과 그 응용인 이미지 혼합 Image Blending을 간략히 다루겠습니다. 아래 예에서는 파이썬 코드로 설명하지만 당연히 C언어 함수로도 제공됩니다.

 

이미지 덧셈 Image Addition

덧셈 함수는 cv.add(input1, input2)로 사용할 수 있으며, input1과 input2는 모두 깊이 depth와 유형이 동일해야 하거나 input2는 스칼라 scalar 일 수 있습니다. 아래 예에서 같이 Numpy 연산으로도 이미지 덧셈 연산을 할 수 있습니다. 다만 결과에서 같이 OpenCV 연산은 포화 Saturation 연산이며 Numpy는 modulo 연산이라는 점에 주의해야 합니다.

 

CV 연산과 Numpy 연산 예)

x = np.uint8([250])

y = np.uint8([10])

z1 = cv.add(x,y) # 250+10 = 260 => 255

z2 = x+y                # 250+10 = 260 % 256 = 4

 

이미지 뺄셈, 곱셈, 나눗셈도 각 cv.substract, cv.multiply, cv.divide로 제공되며 형식은 덧셈 연산과 동일합니다.

 

이미지 혼합 Image Blending

이미지 간 혼합감이나 투명감을 주기 위해 이미지 별 다른 가중치를 부여할 수 있습니다. 단순 연산에 응용으로 Result = (1−α)Image1 + αImage2 처럼 가중치를 다르게 적용하여 두 개의 이미지를 혼합 할 있습니다. OpenCV에서는 cv.addWeighted 함수로 제공되며 두 개의 가중치 α, β와 하나의 offset γ을 활용하여 처리할 수 있습니다. 두 개의 가중치의 합은 항상 1이 되어야 합니다. 그림에서는 로봇에 0.7의 가중치를 OpenCV 로고 이미지에 0.3의 가중치로 혼합한 결과 입니다.

 

result =α⋅img1+β⋅img2+γ

result = cv.addWeighted(img1, α, img2, β, γ)

 

 

이미지 논리 연산 Logical Operations

논리 연산자에는 AND, OR, XOR, NOT 가 있습니다. 논리 연산은 이진 Binary 이미지에 적용되며 픽셀 단위로 수행됩니다. 이진 이미지 처리 시 마스킹, 특정 처리, 형태 분석 등 활용될 수 있습니다. 그림에서 같이 AND의 경우 두 입력이 모두 1일 때 1이 되며, OR 연산은 두 입력 모두 또는 하나가 1일 때 1이 됩니다.

 

 

NOT 연산 cv. bitwise_not() 함수를 이용하며 Result = -Input과 같이 입력에 대한 반전과 같습니다. AND 연산은 아래와 같이 활용할 수 있으며 OR 및 XOR도 각 cv.bitwise_or(), cv.bitwise_xor()로 테스트 해 볼 수 있습니다. Input1과 Input2는 모두 동일한 배열이거나 또는 Input1은 배열, Input2는 Scalar가 될 수 있습니다.

                    

AND 연산 파이썬 예)

Result = cv.bitwise_and(Input1, Input2)

프로그래밍을 할 수 있는 언어는 크게 인터프리터 Interpreter와 컴파일 Complile 언어로 구분할 수 있습니다. 앞에서 설명한 C-언어가 컴파일 언어의 대표 예입니다. 인터프리터 언어에는 요즘 많이 활용 중인 파이썬 Python과 매트랩 Matlab 언어가 있습니다.

 

매트랩 Matlab은 수치 컴퓨팅, 데이터 분석 및 시각화에 활발히 사용 됩니다. 인터프리터 언어 특성상 사용하기 쉽고 다양한 소프트웨어 패키지를 이용하여 물리, 수학, 금융 및 제어 시스템을 포함한 다양한 과학 및 엔지니어링 분야에서 널리 사용됩니다. 그러나 파이썬은 무료에 반해 매트랩은 유료로 사용할 수 있습니다.

 

파이썬 Python의 경우 인공지능 분야 활용 확대로 활용성이 급격히 상승한 언어 중에 하나이며 다양한 응용 분야에서 활용되고 있습니다. 웹 Web 개발, Deep Learning(D/L), 네트웍, 서버, 게임, GUI 등등. 다만 무료 사용은 장점이지만 파이썬 버전에 따른 활용에 주의할 필요도 있습니다.

 

넘피 NumPy, 판다스 Pandas, Matplotlib, scikit-learn 등의 라이브러리는 다양한 데이터 분석에 활용 됩니다. 장고 Django와 플라스크 Flask와 같은 프레임워크는 확장 가능한 웹 응용 프로그램을 쉽게 개발할 수 있으며, 인공지능 Artificial Intelligence 과 자연어 처리  Natural Language Processing  분야에서는 텐서플로우 TensorFlow와 파이토치 PyTorch와 같은 프레임워크를 활용하여 훈련하는데 사용됩니다.

 

SciPy와 SymPy와 같은 라이브러리는 과학적 컴퓨팅, 수학적 문제 해결, 시뮬레이션 수행을 위한 도구들을 제공합니다. Pygame 라이브러리는 간단한 비디오 게임을 작성하기 위한 모듈을 제공합니다.

 

파이썬은 그래픽 사용자 인터페이스(GUI) 개발하는 데 사용될 수 있으며, Tkinter, PyQt 및 Kivy와 같은 라이브러리는 Desktop Application을 쉽게 구축할 수 있습니다.

(docs.opencv.org 참조)

 

형태학적 변환 Morphological Transformation은 이미지 형태를 기반으로 한 몇 가지 단순한 연산이며, 보통 이진 Binary 이미지에서 수행됩니다. 한 단계 더 나아가 그레이 Gray 이미지에서도 가능합니다. 동작을 위해서는 원본 이미지와 변환의 특성을 결정하는 마스크 또는 커널을 활용합니다. 기본적인 형태학 연산자는 침식 Erosion과 팽창 Dilation입니다. 그리고 열림 Opening, 닫힘Closing, 기울기 Gradient 등과 같은 변형 연산도 수행할 수 있습니다. 현 블로그에서는 이진 이미지 기준으로 기본 변환을 설명합니다.

 

영상처리에서 형태학적 변환 연산은 관심영역 또는 물체의 크기를 재정의 하거나 잡음 Noise 제거에 빈번히 활용됩니다.

 

1.  침식 Erosion 연산

침식 Erosion은 흰색 영역을 전경이라고 했을 때 흰색 영역의 가장자리를 기준으로 감소시키는 역할을 합니다. 기본 동작은 원본 이미지 기준으로 커널 간 컨볼루션 Convolution 수행이며, 원본 이미지의 픽셀(1 또는 0)은 커널 아래의 모든 픽셀이 1일 때만 1로 간주되고, 그렇지 않으면 침식됩니다(0으로 만듭니다). 따라서 커널의 크기에 따라 경계 근처의 픽셀들이 모두 침식될 수 있으며, 전경 객체의 두께나 크기가 감소하거나 이미지에서 단순히 흰색 영역이 감소합니다. 작은 흰색 잡음을 제거하거나, 연결된 두 개의 객체를 분리하는 등에 유용합니다. Python 예에서 커널 kenel은 모든 element가 1인 5X5 매트릭스이며, Input_Img와 결과 이미지는 이진 Binary 이미지 입니다.

 

Python Example)

kernel = np.ones((5,5),np.uint8)

Erosion_Img = cv.erode(Input_Img, kernel, iterations = 1)

 

 

2. 팽창 Dilation 연산

팽창 연산은 침식과 반대의 효과를 내며, 커널 아래의 적어도 하나의 픽셀이 '1'이면 픽셀 요소는 '1'입니다. 따라서 이미지에서 흰색 영역이 커지거나 전경 물체의 크기가 커집니다. 침식은 배경에 잡음을 제거하는 효과가 있다면 팽창은 전경 내에 잡음 제거에 효과가 있습니다.

 

Dilation_Img = cv.dilate(Input_Img, kernel, iterations = 1)

 

 

3. 열림 Opening 연산

앞에 설명한 침식과 팽창이 연속 연산을 통해 또 다른 효과를 낼 수 있습니다. 열림 Opening 연산은 침식 연산 후에 팽창 연산을 의미합니다. 그림에서와 같이 침식 효과를 통해 배경 잡음을 제거하고 팽창을 통해 전경의 크기를 보전합니다.

 

Opening_Img = cv.morphologyEx(Input_mg, cv.MORPH_OPEN, kernel)

 

 

4. 닫힘 Closing 연산

닫힘 연산은 팽창 연산 침식 연산을 수행합니다. 그림에서 같이 팽창의 효과로 전경의 잡음을 제거하고 침식을 통해 전경의 크기를 보전합니다.

 

Closing_Img = cv.morphologyEx(Input_Img, cv.MORPH_CLOSE, kernel)

 

 

5. Morphological Gradient

그림에서 같이 팽창 연산 결과와 침식 연산 결과의 차(뺄셈) 연산을 통해 관심 영역인 전경의 에지 Edge를 추출할 수 있습니다.

 

Gradient_Img = cv.morphologyEx(Input_Img, cv.MORPH_GRADIENT, kernel)

 

 

6. 커널 Structuring Element

보통 커널의 형태는 직사각형 모양입니다. 그러나 경우에 따라 타원형 또는 원형 커널이 필요할 수 있습니다. 이를 위해 OpenCV에는 cv.getStructuringElement()라는 함수가 있으며, 커널의 모양과 크기를 전달하면 원하는 커널을 얻을 수 있습니다. 그림은 Python 활용 예입니다.

 

(docs.opencv.org 참조)

 

히스토그램은 이미지의 픽셀 크기별 분포를 그래픽으로 나타낼 수 있습니다. 히스토그램의 X축은 픽셀의 크기(Gray Image: 0~255)를 나타내며 Y축은 영상의 픽셀 수를 나타냅니다. 픽셀 수가 많을수록 특정 밝기 레벨의 피크가 더 높습니다. 히스토그램 균등화(평활화) Histogram Equalization(HE)는 이미지의 대조를 향상시키는데 사용되는 이미지 처리 기술입니다. 이는 가장 빈번한 픽셀값을 효과적으로 펼침으로써, 이미지의 밝기 범위를 확장함으로써 개선 효과를 얻을 수 있습니다. 이를 통해 낮은 국소 대조도의 영역이 더 높은 대조도를 얻을 수 있습니다.

그림에서처럼 픽셀값이 특정 범위의 값으로만 제한되는 이미지를 생각해 있습니다. 예를 들어, 밝은 이미지는 모든 픽셀이 높은 값으로 제한됩니다. 그러나 좋은 이미지는 이미지의 모든 영역에서 픽셀값을 가질 것입니다. 따라서 히스토그램을 끝까지 늘려야 이미지의 대비를 향상시킵니다. 원리를 활용한 이미지 개선 방법이 히스토그램 평활화 기술입니다칼라 히스토그램 평활화는 이미지의 색상 균형에 극적인 변화를 초래하기 때문에 이미지의 빨간색, 녹색 및 파란색 성분에 별도로 적용할 수 없습니다. 그러나 이미지를 HSL/HSV 색 공간과 같은 다른 색 공간으로 먼저 변환 후, 이미지의 색상 및 채도를 변경하지 않고 휘도값에 적용할 수 있습니다.

 

Adaptive Histogram Equalization

적응적 히스토그램 평활화(Adaptive Histogram Equalization) 그대로 적응적, 국소적으로 이미지 밝기를 변환한다는 점에서 일반적인 히스토그램 평활화는 다르며, 로컬 대비를 개선하고 영상의 영역에서 에지의 정의를 강화하는데 적합합니다.

적응적 히스토그램 평활화의 한 방법으로 CLAHE(Contrast Limited Adaptive HE)가 있습니다. CLAHE의 경우, 이미지 대비 제한 과정은 국소적으로 영역을 분할하여 적용하며 일반적인 히스토그램 균등화가 야기할 수 있는 노이즈의 과증폭을 방지하기 위해 개발되었습니다. 아래 첫번째 이미지는 원본 이미지이며, 두번째 이미지는 일반적 히스토그램 균등화(Histogram Equalization) 결과, 세번째는 CLAHE 결과를 나타냅니다. 일반 히스토그램 균등화에서 발생할 수 있는 밝기 포화 Saturation를 CLAHE를 통해 개선할 수 있습니다. 

 

OpenCV에서 createCLAHE 함수로 제공 됩니다. 아래는 Python Code 예입니다.

 

import cv2 as cv

img = cv.imread('input_img.jpg', cv.IMREAD_GRAYSCALE)

clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))

cl1 = clahe.apply(img)

cv.imwrite('output_img.jpg',cl1)

(docs.opencv.org 참조)

 

이미지 개선의 가장 기본처리 방식으로 이미지 히스토그램을 활용합니다. 이미지 히스토그램 Image Histogram 이란 말 그대로 픽셀값의 분포를 나타냅니다. 이를 활용한 이미지 개선 방법 중 하나가 이미지 평활화 또는 균등화 Image Equalization이며 OpenCV 함수 EqualizeHist로 활용해 볼 수 있습니다.

 

 

히스토그램 평활화란 픽셀값 범위를 확장하여 이미지 대비를 개선하는 방법입니다. 그림에서처럼 원본 이미지의 픽셀값의 분포는 중간에 모여 있으며 이를 픽셀의 최소(0) 및 최대(255) 범위로 평활화 하게 되면 대비가 개선된 이미지를 얻을 수 있습니다. 조금 더 세부적으로 원본 이미지의 히스토그램의 누적분포함수(CDF)를 활용하여 픽셀값에 재맵핑 Remapping을 통해 균등화 할 수 있습니다. 수식은 생략하도록 하겠습니다.

 

활용 예)

(C/C++) equalizeHist( Input_Image, Result_Image);

(Python) Result_Image = cv.equalizeHist(Input_Image)

 

파라미터 Input_Image는 8-bit gray image로 결과 또한 8-bit gray 입니다. 

 

영상처리 알고리즘 Algorithm을 설계할 때 전처리 과정에 필수적으로 사용되는 것이 영상에 잡음 Noise을 제거하기 위한 함수 입니다. 몇 가지 명칭으로 사용되며 이미지 블러링 Image Blurring  또는 이미지 스무딩 Image Smoothing 등에  명칭으로 사용이 되는데 유사한 의미로 볼 수 있습니다. 신호처리에서 표현하는 저역통과 필터 Lowpass Filter로도 볼 수 있습니다. 평균 필터 Mean Filter, Averaging Filter에 명칭으로도 쓰이며 변형된 필터인 가우시안 필터 Gaussian Filter, 중간값 필터 Median Filter로도 응용될 수 있습니다. 원리로 보면 저역통과라는 단어에서 느껴지는 것처럼 고주파 신호를 제거하고 저주파 신호만 받아들이겠다는 의미이기도 합니다.

 

OpenCV에는 위에서 처럼 Smooth라는 함수로 구현이 되어 있습니다. Src는 원본영상, 그리고 Dst는 결과영상을 나타내고 기본적으로 8 bits 영상을 사용합니다. Size1Size2는 각 Aperture withheight를 나타내며, 다시 말해 적용하고자 하는 마스크 mask의 크기입니다. 예를 들어 3x3, 5x5, 7x7 등에 마스크 크기를 설정하면 되고, Smooth Type 중 가우시안 마스크 CV_GAUSSIANCV_BILATERAL을 이용 시에는 Sigma를 활용할 수도 있습니다. 마스크에 형태 Type CV_BLUR는 평균 필터, CV_MEDIAN은 중간값 필터를 의미합니다. 참고로 CV_BILATERALGaussian filter의 응용으로 Non-Linear한 특성과 경계선 보존 Edge-Preserving 특징을 가지는 필터로 영상처리기술에서 추가로 설명하도록 하겠습니다.

 

사용 예)

cvSmooth( Input_Image, Result_Image, CV_BLUR, 3, 3, 0, 0)

 

3x3 마스크 크기의 평균 필터를 적용하고자 할 때 위 예처럼 사용하면 됩니다. Smooth 함수는 알고리즘 개발에 전처리 과정에도 많이 사용되지만 그 자체 원리를 이용하여 디지털 카메라, 스마트폰 등에서 사진 블러효과 Blur Effect 로도 응용되고 실생활에서 자주 접할 수 있는 기능이기도 합니다.

윤곽선 검출 Edge Detection은 물체에 경계선을 추출하기 위한 기술 입니다. 우리가 알고자 하는 물체의 모양, 크기, 위치 등 정보를 확인하고자 할 때 사용되는 기술로 알고리즘의 전처리 과정에서 이용됩니다. 요즘 기술개발이 활발히 진행되고 있는 Machine Learning의 한 분야인 딥러닝 Deep Learning에서 영상의 특징점 Feature 을 정의하는데도 사용되는 전처리 기술 입니다.

Edge Detection 기술이 사용 된지는 오래됐으며 현재까지도 폭넓게 사용되고 있고, 수학적 접근방식에 따라 다양한 방법들이 존재합니다. 현 이야기에서는 OpenCV에서 제공되는 윤곽선 검출 도구 중 Sobel Edge Detection Canny Edge Detection 기술 사용법에 대한 설명입니다. Edge Detection에 앞에 붙어 있는 Sobel Canny는 개발자에 이름이며 WIKIPEDIA에 의하면Sobel Filter 1968년과 Canny Edge Detector 1986년에 개발되었습니다. 정말 오래된 기술 입니다만 현재도 상당히 많이 사용되고 있고, 이러한 윤곽선 검출 기술에 기본 원리는 미분 연산자 Differentiation Operator에 의한 밝기 변화 탐색 입니다. 다시 말해, 물체의 가장자리에서 밝기 변화가 크므로 Pixel 값에 차이를 통해 윤곽선 유무를 판단할 수 있다는 의미이기도 합니다.

위에서처럼 OpenCV에서 제공되는 Edge Detection 함수인 Sobel Canny를 볼 수 있습니다. 먼저 cvSobel 함수를 살펴보면 앞에서 설명한 기본 함수들에서처럼 입력영상인 “src”와 결과영상을 담기위한 “dst”가 보입니다. “aperture_size” Sobel Mask의 크기를 나타내고 “3”이면 3X3을 의미합니다. “xorder”“yorder” Sobel Mask 연산 시 결과값의 위치를 나타내는데 3X3의 경우 중심인 xorder = 1 yorder = 1 이 되며, Mask의 시작점은 (0, 0)이니 2가 아닌 1이 됩니다.

 

Sobel 사용 예)

cvSobel( Input_Image, Result_Image, 1, 1, 3)

cvConvertScaleAbs(Result_Image, Convert_Result_Image, 1, 0)

 

cvSobel 함수 사용은 위에 예처럼 사용하면 되는데 cvConvertScaleAbs()라는 함수가 더 있죠? cvSobel 함수 사용 시 주의할 점이 있습니다. 앞에서 언급했듯이 Edge Detection의 원리가 Pixel의 차이를 이용하기 때문에 결과에서는 마이너스 “-“ 값이 존재하고 Result_Image Depth는 보통 Input_Image Depthunsigned 8-bit 이니 signed 16-bit 으로 구성되어야 합니다. 따라서 최총 결과를 확인하기 위해서는 절대값을 이용하여 다시 unsigned 8-bit 으로 변환해 줘야 하고, 이때 사용되는 함수가 cvConvertScaleAbs() 입니다.

 

cvCanny 함수의 경우 입력영상인 “image”와 결과영상인 “edges”가 보이고 “apertureSize = 3” Sobel Mask   3X3을 의미합니다. 여기서 cvSobel 함수와 다르게 “threshold1”“threshold2”를 입력하게 되어 있는데, “threshold1” 이하는 외곽선이 아닌 영역으로 “threshold2” 이상은 외곽선인 영역, 그리고 “threshold1”“threshold2”의 사이는 Canny Procedure에 의해 외곽선 유무를 판단하게 됩니다.

 

Canny 사용 예)

cvCanny( Input_Image, Result_Image, 100, 200, 3 )

 

cvCanny 사용 예에서 threshold1threshold2 100 2000 ~ 255의 범위를 갖는 8-bit 영상 기준으로 설정된 값을 의미하고, Result_Image Input_Image와 동일한 속성으로 설정하면 됩니다. 앞에 설명과 그림 결과와 같이 8-bit Input_Image 기준으로 cvSobel 함수의 최종 Result_Image 8-bit 그레이 Gray 영상이며, cvCanny 함수의 경우 8-bit 바이너리 Binary 영상이니 이것만 주의해서 활용하면 됩니다. Sobel Canny의 수학적 또는 알고리즘 접근에 대해서는 영상처리기술에서 추가적으로 다뤄보도록 하겠습니다.

+ Recent posts