본문 바로가기
Project

[openCV][c++] 이미지 도트화 시키기 프로젝트 "도트는 귀여워"

by 배애앰이 좋아 2021. 1. 13.
반응형

< 프로젝트 구현 배경 >

 

1. 도트는 손이 많이 가는 작업이다. -> 쉽게 도트를 만들 수 있으면 좋겠다.

2. 미적 감각이 없는 사람은 도트를 잘 만들지 못함.

3. 그림이 아닌 일반 사진을 도트화하고 싶은 수요가 있음.

4. 그림 리소스 > 도트 리소스 양의 차이가 큼. -> 도트게임 만들 때 좀 더 리소스 구하는 게 수월했으면 좋겠다.

 

< 구현 과정 >

 

1. 도트화 하고 싶은 이미지를 가져와서 NxN 도트화를 할 N 값을 정하여 마스크 x2, y2 값 정하기

 

 

2. 이때 x2, y2 랑 조각조각 분할했을 때의 한 조각에 대한 아래와 같이 넓이와 높이를 가리킨다. 그리고 위 마스크의 픽셀들의 색깔 값을 다 더하여 평균내서 하나의 색깔 정해준다. (아래 경우 왼쪽 그림의 평균적인 색깔을 오른 쪽 그림의 갈색이라 계산하고 해당 픽셀들을 한 색깔로 바꿔주는 작업을 하였다.)

 

 

3. 평균해서 나온 색깔 값으로 다 칠해주기

 

이에 대한 결과 이미지들 :

 

결과 이미지

 

하지만 이는 도트화보다는 모자이크에 비슷함 -> 해당 원인을 색의 너무 다양함으로 생각.

 

위 문제를 해결하기 위해 색의 색의 다양함을 줄이고자 색칠할 색깔을 지정해 주고자 함.

 

4. 아래와 같이 색깔을 미리 주고 위 마스크의 픽셀들의 색깔 값을 다 더하여 평균 냈을 때 옆에 미리 지정한 색깔과의 차이를 구해 제일 차이가 적은 색깔로 칠해준다.

 

 

위 방법으로 했을 경우 결과 이미지들 : 

 

 

기존의 결과보다 안 좋아졌으며 한정적인 색깔로 표현하기에는 무리가 있다고 판단.

 

- 기존에는 한정적인 색깔의 사용이 도트의 특징이라 생각하여 색깔의 다양함을 줄이고자 함.

- 이번에는 아래와 같이 검고 사각형 윤곽선도트의 특징을 살릴 수 있을 것이라 생각하여 도전.

 

 

edge 찾는 것을 활용하여 윤곽선을 찾음

 

 

Edge 로 찾은 윤곽선을 3x3 or 5x5 사이즈로 칠해주면 사각형 윤곽선이 나올 거라고 예상한 바와 달리 곡선의 형태를 띄어 적용시키면 도트 느낌이 나지 않을 거라 판단하여 포기함.

 

- 다시 돌아와서 색의 다양함을 줄이고자 색칠할 색깔을 원본 이미지에서 정해주고자 함.

- 이를 고안한 2가지 방법 생각.

 

방법 1.

원본 이미지를 구성하는 색깔들을 저장하고 비교해서 같은 색깔이 있을 경우 카운트를 세어서 카운트가 높을 수록 해당 이미지를 구성하는 주요 색으로 판정. 대략 5~7개를 뽑아서 도트화 할 때 해당 색상만 이용해서 색칠

 

방법 2.

직접 사용자가 n개의 색깔을 지정하여 도트화 할 때 해당 색깔로만 이용해서 색칠

 

이중에서 방법 2 선택 : 방법 1을 택할 경우 사용자가 원하는 색깔이 나오지 않을 수도 있고 주요 색깔이 아닌 아래의 사진과 같이 회색 같은 색깔이 나올 수 있기 때문에 방법 2 선택 

 

 

사실 방법 1이 방법적으로 적합하고 회색이 나올 가능성이 적다고 생각이 들음 위에 회색이 많아보이기는 하나 실제로 RGB 값에서는 1이라도 오차가 있을 것이 분명하니 결국 방법 1하면 색깔이 나름 잘 뽑히지 않았을까 생각. 하지만, 시간 관계상과 실제로 사용자가 원하는 색깔로 구성하는 도트에 따라 차이가 크기 때문에 방법 2 택함.

 

구현 순서 :

 

1. 임의적으로 색깔 5개를 사용자가 직접 선택하도록 구현

2. 아래와 같이 원본 이미지가 뜨면 사용자는 마우스를 이용하여 왼쪽 버튼을 눌러 5개의 색깔 클릭

     (더 적은 색깔로도 구현 가능)

3. 색깔을 다 선택할 경우 오른쪽 버튼을 누르면 계산 후 결과 이미지가 나옴.

 

 

구현 방법 :

 

1. 색깔 선택 방법 : 사용자가 지정한 색깔 중에 위 마스크의 픽셀들의 색깔 값을 다 더하여 평균 냈을 때 차이를 구해 제일 차이가 적은 색깔로 칠해준다.

 

2. 원본 이미지와 사본 이미지 동시에 보여주는 방법 : 원본 이미지의 width 값이 2배인 흰 스케치북을 그려서 원본, 결과 각 픽셀 색칠

 

결과 이미지 : NxN 이기 때문에 N 값이 높을수록 색깔을 많이 지정할 수록  quality가 높아진다.

 

 

관련 영상 :

 

 

문제점 1. 아래와 같이 빈 공간이 생김 (NxN이기 때문에 사진이 정사각형이 아닌 이상 빈 공간이 생긴다고 예상 / 시간 상 이부분을 확인하고 수정하지 못함.)

 

 

문제점 2. 사진에 색깔이 많을 경우 색깔을 5개로 제한하였기 때문에 잘 구현이 안됨. (이 부분은 단순히 색깔 지정 배열의 길이 늘리면 되기 때문에 큰 문제는 아니라고 판단.)

 

 

추후 보완한 점 :

 

문제점 1. 원인은 NxN이기 때문에 낙오되는 픽셀이 생긴 문제인 것을 확인 -> 예를 들어서 350*600 사이즈 이미지를 100*100 도트화를 시킨다고 하면 350/100 하면 딱 나눠 떨어지지 않기 때문에 50픽셀이 낙오되면서 검은색 빈 공간이 생긴다. 이 문제를 해결하기 위해서는 도트화 시키기 전에 직접 이미지 크기를 맞춰주거나 픽셀 수에 맞춰서 나눠줘야 한다. -> 나중에는 어떤 이미지를 넣던 간에 알아서 이미지 크기를 늘려서 도트화 시켜주면 좋을 것 같음.

 

문제점 2. 배열 늘려줌. 매우 간단한 해결.

 

위 보완 후 결과 이미지들 :

 

결과이미지 1

 

결과 이미지 2

 

요즘 재밌게 읽고 있는 성스러운 아이돌 표지를 바꿔보았다.

 

결과 이미지 3

 

요즘 재밌게 하고 있는 게임 할로우 나이트 한 장면도 해보았다.

 

만약 사용자가 도트 색깔이 다르게 지정하면 아래와 같다.

 

 

보시다싶이 사용자의 선택이 많이 도트화에 영향 끼치는 것을 알 수 있다. 이 점은 장단점 둘 다 될 수 있다고 생각한다.

 

 

요즘 뜨고 있고 옛날에 재밌게 읽었던 전지적 독자시점 표지도 해보았다.

 

위 프로젝트를 하면서 소감 : 원래 도트 게임을 좋아하기 때문에 이미지 도트화에 흥미있게 생각하였는데 어떻게 기회가 되어서 관련 openCV 강의를 듣을 수 있게 되었고 해당 opencv를 통해서 해당 프로젝트를 하고 싶다고 마음을 먹었다. 그리고 이렇게 구현하는 동안 재미있었던 것 같고 나름 결과가 좋아서 만족도 200%였다. 역시 덕질도 하나의 코딩을 이끌어주는 욕망인 것 같다. 마음 같아서는 해당 프로젝트를 이렇게 끝이 아니라 더 활용할 수 있으면 좋을 것 같은데 아직 어떻게 발전해나가면 좋을 지 고민된다. 3d 를 2d 도트화 시키는 것도 해보고 싶은데 훗날 이야기일 거 같다. 

 

더보기

프로젝트 파일 이름 :

C:\Users\USER\source\repos\opencv_201804046_project

C:\Users\USER\source\repos\opencv_1230

반응형

댓글