STUDY_SEONMIN

DAY49 - 이미지 데이터 다루기2 본문

EDUCATION/DSS Online 6기

DAY49 - 이미지 데이터 다루기2

Kululu_ 2021. 3. 25. 14:07

이번 글에서는 이미지의 경계선 정보를 나타내는 "컨투어"와 이미지 변환에 대해 다뤄보겠습니다.

 

컨투어

- 동일한 색 또는 동일한 픽셀값을 가진 영역의 경계선 정보

- opencv로 컨투어 정보를 뽑아내면, 컨투어라인에 대한 정보와 컨투어끼리의 상하구조를 알 수 있습니다.

 

컨투어 추정에 활용할 예제 이미지 데이터

여기서 "컨투어"를 찾게 되면 흰색으로 이루어진 영역의 경계선 정보(말의 윤곽선)를 얻어낼 수 있을 것입니다.

실제로 컨투어를 뽑아봤더니 2개가 발견

이렇게 컨투어가 여러 개가 발견된 경우에는 hierachy정보를 통해서 가장 상위에 있는 컨투어가 보통 우리가 찾고자 하는 경계선이 됩니다.

 

컨투어들의 상하구조를 살펴볼 때 3번째 컬럼과 4번째 컬럼을 관심 있게 살펴보는 게 좋습니다.

3번째 컬럼이 -1의 값을 가지면 가장 하위의 컨투어임을 나타내고, 4번째 컬럼이 -1의 값을 가지면 가장 상위의 컨투어임을 나타냅니다.

 

위의 상하구조에서는 0번 인덱스의 컨투어가 가장 상위의 컨투어라는 것을 보여주고 있습니다.

실제로 0번 인덱스에 해당하는 컨투어를 그려보면 말의 경계선이 나오게 됩니다.

plt.imshow()는 좌상단 시작 plt.plot()은 좌하단이 시작이므로 같은 방향으로 보기 위해서 -y0를 취해주었습니다.

 

동차좌표와 어파인 변환

1) 동차좌표

- 동차좌표는 2차원 상의 점의 위치를 2차원 벡터가 아닌 3차원 벡터로 표현하는 방법입니다.

- 이러한 방법을 사용하는 이유는 이미지 변환에서 평행이동에 해당하는 부분을 한 번에 나타내기 위해서 입니다.

$$ \begin{bmatrix} x \\ y \end{bmatrix} \rightarrow \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} $$

 

원래는 벡터를 선형변환하고 평행이동 시키는 과정을 다음과 같이 표현해야 하는데

$$ \begin{bmatrix} x^{'} \\ y^{'} \end{bmatrix} = A \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} t_x \\ t_y \end{bmatrix} $$

 

동차좌표를 사용하면 행렬과 벡터의 곱 한 번으로 표현할 수 있습니다.

$$ \begin{bmatrix} x^{'} \\ y^{'} \\ 1 \end{bmatrix} = \begin{bmatrix} A & t \\ \mathbf{0} & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} $$

$$ t = \begin{bmatrix} t_x \\ t_y \end{bmatrix} $$

$$ \mathbf{0} = \begin{bmatrix} 0 & 0 \end{bmatrix} $$

$$ H = \begin{bmatrix} A & t \\ \mathbf{0} & 1 \end{bmatrix} $$

$$ \begin{bmatrix} x^{'} \\ y^{'} \\ 1 \end{bmatrix} = H \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} $$

 

 

2) 강체변환

- 벡터의 회전과 평행이동만을 나타내는 변환

$$ H = \begin{bmatrix} \cos\theta & \sin\theta & t_x \\ -\sin\theta & \cos\theta & t_y \\ 0 & 0 & 1 \end{bmatrix} $$

 

 

3) 유사변환

- 벡터의 회전, 평행이동, 스케일 변환까지 표현하는 변환

$$ H = \begin{bmatrix} s\cos\theta & s\sin\theta & t_x \\ -s\sin\theta & s\cos\theta & t_y \\ 0 & 0 & 1 \end{bmatrix} $$

 

유사변환을 표현하는 행렬 $H$에서 $ s=1$ 이면 스케일변환을 하지 않는다는 의미이므로 강체변환과 동일해집니다.

 

이미지의 어파인 변환은 이미지를 구성하고 있는 픽셀들을 위치를 일정한 기준을 가지고 이동시키는 과정이라고 볼 수 있습니다.

 

픽셀들의 위치는 2차원 벡터로 표현되기 때문에 벡터를 회전시키고 이동시키고 스케일 변환하는 등의 "유사변환"을 이미지에 적용하면 우리가 원하는 형태로 이미지를 변환시킬 수 있는 것입니다.

 

파이썬에서는 cv2.getRotationMatrix2D를 통해서 우리가 원하는 변환을 나타내는 변환행렬 H를 얻어낼 수 있습니다.

이 때 회전은 시계반대방향으로의 회전을 의미합니다.

 

얻어진 H 행렬이 위에서의 설명과 달리 2 x 3 행렬인 이유는 3번째 행은 변환된 벡터를 동차좌표로 표현하기 위해 필요한 부분이지 벡터를 변화시키는 데에는 필요한 부분이 아니기 때문입니다.

 

이렇게 얻어진 H 행렬은 warpAffine이라는 함수에 사용하게 되면 우리가 원하는 형태로 변환된 이미지를 얻어낼 수 있습니다.

 

만약 평행이동을 추가하고 싶다면 얻어진 H 행렬의 마지막 컬럼에 원하는 만큼의 평행이동을 추가해주면 됩니다.

 

3점 어파인 변환

3점 어파인 변환은 지정한 3개의 점을 원하는 위치로 이동시키는 변환행렬을 찾아냄으로써 이미지의 회전, 확대/축소, 평행이동을 표현하는 방식입니다.

- getRotationMatrix2D는 변환 후의 기저벡터끼리도 직교하게끔 변환행렬을 만들기 때문에 이미지의 형태(직사각형)가 그대로 유지되는 반면 3점 어파인 변환은 기저벡터가 직교하지 않아도 되게끔 변환행렬을 만들기 때문에 이미지의 형태가 달라져서 보일 수도 있습니다.

pts1에 있는 3개의 점을 pts2에 있는 3개의 점으로 이동시키는 변환행렬 H를 얻어냅니다.

 

얻어낸 변환행렬을 실제로 이미지에 적용시켜보면 이미지가 평행사변형으로 바뀐 것을 볼 수 있습니다.

 

 

원근변환

- 어파인변환에서는 어떻게 변화를 하던 테두리 선끼리는 평행성을 유지했지만, 원근변환은 평행성을 유지하지 않아도 상관이 없습니다.

- 이러한 이유로 원근변환은 마치 3차원 공간상에서 이미지라고 하는 평면을 변화시키는 작업이라고 생각할 수 있습니다.

- 원근변환은 4개의 점을 선택해서 원하는 위치로 변환시키는 변환행렬을 구하는 방법으로 할 수 있습니다.

 

Comments