본문 바로가기

프로젝트

opencv - 프로젝트 2 - 1. 카드 인식

저는 취미로 마술을 하고 있습니다. 같이 마술하는 친구들이랑 모여서 이야기를 하는데 이런 이야기가 나오더라고요

관객이 7하트를 들고 있는 모습을 찍었는데 나중에 사진 속 카드를 확인해 보니 7 스페이드로 바뀌어 있으면 신기하지 않을까?

 

딥러닝에서 U-net(https://codestudycafe.tistory.com/41)을 이용하면 충분히 만들 수 있겠다는 생각이 들었고 바로 작업에 들어갔습니다. 우선 카드를 인식하는 것부터 시작해 보겠습니다.

 

윤곽선 추출

1. 흑백 샤프닝

카드를 먼저 라벨링을 해줘야 학습을 시킬 수 있습니다. 이 부분을 opencv로 처리하겠습니다. 먼저 흑백으로 사진을 입력받고 윤곽선을 추출해 줍니다. 그리고 마우스로 영역을 클릭하면 해당 위치와 색이 비슷한 영역을 bfs로 탐색하면서 추출합니다. HSV로 입력받아서 비슷한 색상을 제거하는 것도 생각해 봤는데 흰색 옷 위에 있는 카드를 잘 인식하지 못할 것 같아 뒤로 미루어 두었습니다.

 

gaussianBlur로 이미지에 블러를 넣어줍니다. 그리고 addWeighted를 적용해 테두리를 추출합니다. img에 1 곱한 것과 blrImg에 -1을 곱한 것을 더하고 모든 픽셀에 128을 더해줍니다. 128은 이미지를 출력할 때 결과가 음수인 부분도 보기 위해서 넣어주었습니다.

 

dst를 출력하면 테두리를 잘 추출해 준 것을 확인할 수 있습니다.

 

이제 원본 이미지에서 테두리 이미지를 더해줍니다. 그러면 원본 이미지보다 더 날카로운 이미지를 얻을 수 있습니다.

 

왼쪽이 원본, 오른쪽이 테두리를 더해준 이미지입니다. 오른쪽 머리카락이 조금 더 선명하게 보입니다.

 

이제 클릭할 때 마다 클릭한 곳과 색이 비슷한 곳을 1로 바꿔 줄 것입니다. 최종적으로 카드에 해당하는 부분만 1로 바꿔줄 것입니다. 클릭한 곳의 색을 base로 하고 클릭한 곳 상하좌우로 탐색해가면서 색이 base $\pm$ margin인지 확인하고 비슷하면 1로 체크해 줍니다.

 

 

카드 부분을 적당히 클릭하고 이미지를 출력해 봤습니다.

 

뭔가 되는 듯 하면서도 이상한 것이 있습니다. 속도도 많이 느린 것 같네요.margin을 조금 더 늘려봅시다.

 

 

오 세상에 이건 아니였는데 말이죠

손가락은 살색이고 카드는 흰색인데도 흑백사진으로 바꾸니 이것을 구분하지 못하는 것을 볼 수 있습니다. 아무래도 HSV로 바꿔서 진행해야 할 것 같네요

2. HSV 샤프닝

 

이미지를 다시 BGR로 입력받고 위에서 했던 샤프닝을 각 색상마다 따로 적용을 해 줬습니다.

 

 

같은 영역의 카드를 그냥 보여준 것(왼쪽)과 샤프닝을 한 다음 보여준 것(오른쪽)입니다. 샤프닝을 한 쪽이 조금 더 선명하게 보입니다.

 

HSV로 바꾼 후 잘 바뀌어 졌는지 출력해 봅니다. 

 

179, 255, 255가 나온 것을 보니 0번째 채널이 H인 것을 알 수 있습니다.

 

이제 문제가 되었던 부분을 살펴봅시다.

 

확대를 해봅시다.

 

 

아무리 봐도 페인트 기능만으로는 해결하긴 어려워 보입니다. 어쩔 수 없이 그림판의 브러시 기능이 필요할 것 같네요.

그냥 윤곽선 + 브러시

b, c로 브러시의 크기를 조절하고 q, w로 브러시를 할지 페인트를 할지 정해줍니다.

 

그리고  hsv 같은거 다 지우고 다시 흑백 이미지를 받아줍니다.

 

브러시 기능을 만들어 줍니다.

 

이제 애매한 부분을 손으로 채워준 후 나머지를 페인트로 처리해 줍니다.

 

이제 그림판을 열고 튀어나온 부분 삭제하고 내부를 채워줍니다.

 

 이제 이것을 모든 카드에 대해 작업해 주면 됩니다.