Vision – 영상 처리 입문 II

그래픽 출력 함수

  1. 직선 그리기

cv2.line함수를 이용하면 직선을 그릴 수 있습니다.
이 때 LineType은 다음과 같이 세 가지가 있습니다.

  • 4-connected line
    현재 픽셀을 기준으로 상하좌우를 채우는 방식으로 직선을 그립니다.
  • 8-connected line
    현재 픽셀을 기준으로 상하좌우, 대각선을 채우는 방식으로 직선을 그립니다.
arXiv:1906.03366v2 [cs.GR] 17 Jun 2019
  • AA (안티 앨리언싱)
    애일리어스(영상을 확대할 때 나타나는 계단 형태)를 없애면서 직선을 그립니다.
안티 앨리어싱 (Anti-Aliasing)


2. 도형 그리기

사각형을 그릴 때는 Rectangle 함수를 이용합니다.

사각형과 직선과의 교차점을 찾을 때는 ClipLine 함수를 이용합니다.

타원을 그릴 때는 Ellispe 함수를 이용합니다.
이 때, Bounding Box안에 꽉 찬 원을 만드는 방식으로도 그릴 수 있습니다.

직선을 이용해서 타원을 그릴 때는 Ellipse2Poly 함수를 이용합니다.

다각형을 그릴 때는 Polylines 함수를 이용합니다.

채워진 블록 다각형을 그릴 때는 FillConvexPoly 함수를 이용합니다.
이 때는 점을 이용해서 다각형을 그립니다.

일반적으로 채워진 다각형을 그릴 때는 FillPoly 함수를 이용합니다.

볼록하게 채워진 다각형을 그릴 때는 FillConvexPoly 함수를 이용합니다.


3. 문자열 출력

문자열 출력 크기를 반환할 때는 GetTextSize 함수를 이용합니다.

문자열을 출력할 때는 PutText 함수를 이용합니다.
이 때 파라미터로 ‘org’를 제공하는 출력 문자의 시작 위치가 저장됩니다.
이 시작 위치는 문자열을 출력했을 때 좌측 하단 위치라고 생각하면 됩니다.
ex) org=(50,100)


그래픽 출력에 대한 파이썬 코드를 제공합니다.


이벤트 처리

이벤트는 ‘어떤 일이 발생하였음을 알리는 신호’입니다.
이 때, ‘어떤 일’이란 (사용자의 키 입력, 마우스 이동 따위의 행동[액션] 등)을 의미합니다.

키보드 이벤트를 처리할 때는 waitKey 함수를 이용합니다.
키보드 이벤트가 발생하면 입력한 1바이트 만큼의 문자열을 가져 옵니다.
2바이트 만큼의 문자열을 가져오려면 waitKeyEx 함수를 이용하면 됩니다.

마우스 이벤트를 처리할 때는 setMouseCallback 함수를 이용합니다.

openCV는 트랙바 이벤트도 처리할 수 있습니다.
트랙바는 아래 그림에서 bar 모양에 해당하는 객체를 의미합니다.

Trackbar — gramman 0.1 documentation

먼저 CreateTrackbar 함수로 트랙바 객체를 생성합니다.
이후 setTrackbarPos 함수로 트랙바 위치를 설정할 수 있습니다.
getTrackbarPos 함수를 이용하면 트랙바의 현재 위치를 반환합니다.


영상 접근법

OpenCV의 자료형은 아래 그림과 같습니다.


컬러 접근 및 설정은 아래와 같이 시행합니다.

컬러 영상의 한 픽셀은 R.G.B 세 성분의 밝기 값을 담고 있습니다.
하지만 OpenCV에서는 B.G.R로 처리하는 특성이 있습니다.

따라서 한 픽셀로부터 (b,g,r)을 얻어 오거나, 어떤 한 픽셀에 (b,g,r)값을 넣을 수도 있습니다.
이처럼 픽셀 조작도 자유롭게 할 수 있습니다.

마우스를 이용해서 특정 영역을 지정/접근하고 싶으면 selectROI 함수를 이용합니다.



복사와 참조

원본과 동일한 형태의 영상을 조작하는데, 원본 영상을 유지하려면 ‘복사’를 이용합니다.
동일한 형태의 새로운 영상을 만든다고 생각하면 됩니다.

복사는 copy 함수를 이용합니다.
ex) src=영상, dst=src.copy()

원본과 동일한 형태의 영상을 조작하는데, 원본 영상도 조작하려면 ‘참조’를 이용합니다.
이 때는 원본 영상을 가리키는 레퍼런스 변수만 다른 것입니다.
결국 각 레퍼런스 변수가 가리키는 객체는 동일하기 때문에
레퍼런스 변수가 가리키는 객체를 수정하는 것은 원본을 수정하는 것과 같습니다.

참조는 단순히 ‘=’ 키워드를 이용합니다.
ex) src=영상, dst=src


컬러 공간

OpenCV에서 영상은 BGR, GRAY, HSV, YCrCb 공간으로 나타낼 수 있습니다.

BGR은 색(color)을 Red, Green, Blue의 3가지 성분의 조합으로 생각해서 영상을 표현한 것입니다.
GRAY는 색(color) 정보를 사용하지 않고 밝기 정보만으로 영상을 표현한 것입니다.
HSV는 Hue(색조), Saturation(채도), Value(명도)의 3가지 성분으로 영상을 표현한 것입니다.
YCrCb는 밝기성분(Y)과 색차정보(Cb, Cr)를 분리하여 영상을 표현한 것입니다.

컬러 영상을 처리할 때는 채널 분리(split)을 해서 영상 처리를 적용하고 다시 채널 병합(merge)를 하는 방식으로 합니다.


영상 접근법에 대한 파이썬 코드를 제공합니다.

픽셀 값 보기, 픽셀 수정

복사를 하였으니 원본 영상(src)은 수정이 안 됨

컬러 영상을 조작할 때는 [분리 -> 작업 -> 합병] 과정으로 진행함

다른 컬러 공간으로 변환해서 출력해볼 수 있음


기하 변환

영상을 스케일링(확대,축소)하거나 회전하는 것‘기하 변환’이라고 합니다.

확대,축소를 할 때는 resize 함수를 이용합니다.
90도 회전을 할 때는 rotate 함수를 이용합니다.
90도가 아닌 회전을 할 때는 imutils 모듈의 rotate 함수로 편하게 변환이 가능합니다.

기하 변환에 대한 파이썬 코드를 제공합니다.


기본 연산

OpenCV에서 제공하는 기본 연산은 아래와 같습니다.

가중치를 함께 더하는 연산을 원할 때는 addWeighted 함수 자료를 찾아서 이용하면 됩니다.


임계값 영상

임계값은 Threshold로 기준값이라고 생각하면 됩니다.

Segmentation을 할 때 자주 사용하는 값입니다.

예를 들어 임계값을 두고 입계값보다 큰 수치 혹은 작은 수치를 모두 0으로 조정하는 것입니다.

만약 어떤 ‘컵’ 영상에서 컵의 밝기 값은 128이고 나머지는 128보다 작을 때, segmentation을 하면
128을 기준으로 128보다 작은 픽셀은 모두 0으로 처리하는 방법으로 segmentation이 가능합니다.
그러면 컵 주위가 전부 검정색이 돼서 영상 분리를 성공적으로 할 수 있습니다.

임계치를 이용한 Segmentation 함수는 여러 종류가 있습니다.

  • cv2.THRESH_BINARY
    임계치보다 크면 max(1=255)로, 아니면 0으로 처리
  • cv2.THRESH_TRUC
    임계치보다 큰 부분은 임계치로 만들고 아니면 그대로 처리
  • cv2.THRESH_TOZERO
    임계치보다 큰 부분은 그대로, 아니면 0으로 처리

물론 임계값을 자동으로 계산해주는 함수도 존재합니다.

  • cv2.THRESH_TRIANGLE
    삼각 알고리즘을 이용해서 임계값을 계산함
  • cv2.THRESH_OTSU
    오츠 알고리즘을 이용해서 임계값을 계산함
    -> 모든 영상은 background와 foreground로 나눠진다고 생각하고 임계값을 계산함
    -> 밝기가 고르지 않는 영상에는 알고리즘 적용 시 문제가 발생함
    -> 영상을 분할해서 구역별로 임계값을 계산하고 처리하는 것으로 극복함
What is meant by Foreground, Midground & background plants? | Betta Fish  Forum

임계치 영상에 대한 파이썬 코드를 제공합니다.


히스토그램

히스토그램‘영상의 픽셀 값(밝기 값)의 분포를 그래프로 나타낸 것’입니다.

아래 그림을 참고해주세요.

픽셀 값이 0~7로 이루어진 영상이 있으면
빈이 8개인 히스토그램으로 만들 수 있습니다.

그러나 경우에 따라 빈의 개수를 줄여서 쓰기도 합니다.
가장 오른쪽 그림을 보시면 2개의 빈씩 묶어서 빈이 4개인 히스토그램으로 만든 것입니다.

이처럼 히스토그램은 정보량을 줄일 때 유용합니다.

또한 히스토그램은 ‘영상 분석‘에도 사용이 됩니다.

세 개의 레나(lena) 영상을 가져 왔습니다.

첫 번째 히스토그램은 픽셀들이 중간 값에 위치해 있으니 영상이 중간 밝기를 지닙니다.
두 번째 히스토그램은 픽셀들이 높은 값에 치우쳐 있느니 영상이 높은 밝기를 지닙니다.
세 번째 히스토그램은 픽셀들이 낮은 값에 치우쳐 있으니 영상이 낮은 밝기를 지닙니다.


이번에는 다른 레나 영상 두 개를 가져 왔습니다.

왼쪽 히스토그램은 픽셀들이 고르게 위치합니다. 따라서 영상의 어두운 부분과 밝은 부분의 차이가 심합니다.
이런 것을 명암비(대비)가 높다고 표현합니다.

오른쪽 히스토그램은 픽셀들이 뭉친 상태로 위치합니다. 따라서 영상의 어두운 부분과 밝은 부분의 차이가 적습니다.
이런 것을 명암비(대비)가 낮다고 표현합니다.

이렇게 명암비가 낮은 경우 히스토그램을 조작하면 대비를 크게 만들 수 있습니다.

즉 히스토그램을 조작해서 단조로운 영상을 단조롭지 않게 만들 수 있습니다.

이러한 작업을 ‘히스토그램 스트레칭’ 이라고 합니다.

히스토그램을 전 구간에 분포시키는 선형 변환 기법입니다.

이 때 함수는 calcHist를 이용합니다.

하지만 ‘히스토그램 스트레칭’에는 한계점이 존재합니다.

min과 max를 0~255로 바꿔서 정규화하는 것이 스트레칭인데, min,max가 애초에 0과 255와 비슷한 수치면 정규화 효과가 없다는 것입니다.

하지만 다행히 ‘히스토그램 평활화’라는 알고리즘이 존재합니다.

영상의 픽셀 값 분포가 전체 영역에서 균일하게 분포하도록 변경하는 알고리즘입니다.
이 알고리즘은 히스토그램 누적 함수 H(g)를 이용합니다.

dst가 입력 영상일 때 평활화 알고리즘을 적용하면 다음과 같습니다.

평활화 작업을 마치면, 기존에 밝기값이 0인 픽셀의 위치에 2가 들어가고, 1인 픽셀의 위치에 3이 들어가는 것을 확인할 수 있습니다.

결과론적으로 픽셀이 (2:2개, 3:1개, 4:3개, 4:1개, 7:2개)인 영상이므로 이전보다 단조롭지 않습니다.

평활화 작업 때 함수는 equalizeHist를 이용합니다.

히스토그램에 대한 파이썬 코드를 제공합니다.


Leave a Reply

Your email address will not be published. Required fields are marked *