티스토리 뷰
Original Post
http://aishack.in/tutorials/sudoku-grabber-opencv-detection/
2 Grid detection
이 포스트에서, 우린 Sudoku Puzzle을 감지할것이다. 여기서 이미지에 대한 모든 전처리가 이루어진다:
이미지에서 nosie가 너무많이 감지되지 않게 필터링을 수행하고, 이미지 segmenting 또한 여기서 다뤄진다. 난 여기서 꽤 이상한 segmentation 방법을 사용했는데, 여러분이 꽤 관심을 가질 수도 있다. 이 포스트를 통해, 퍼즐의 상자를 이루는 선들을 얻게 될것이다.
시작하기
- OpenCV with gcc and CMake
- OpenCV's C++ interface
<스도쿠 퍼즐 이미지>
제대로 로드되었는지 다음과 같은 코드로 확인할 수 있습니다.
우리는 이미지를 grayscale mode로 로드했습니다. (imread 함수의 2번째 인자가 0임을 확인)
왜냐하면 색에 대한 정보는 필요가 없기 때문이죠. 그리고 다음에는, 같은 크기의 빈이미지를 생성했습니다. 이 이미지는 퍼즐의 바깥상자를 저장할것입니다.
이미지 전처리하기
이미지를 약간 Blur 처리할겁니다. 이건 노이즈를 조금 감소시키고, 상자 선을 뽑아내는데 더 쉽게 만들어줍니다.
이렇게 노이즈를 줄여주면, 이제 이미지를 threshold 할 수 있습니다. threshold란 이미지의 특정 영역을 인지해서 이미지로부터 분할(segmenting)하는 것입니다. 링크참조
이미지는 다양한 illumination level을 가질 수 있는데, adaptive threshold 알고리즘이 좋은 선택이 될 수 있습니다. - 더 자세한 내용은 원본 포스트 참조바람 -
다음의 소스코드를 통해 적용할 수 있습니다.
그 뒤, 우리가 경계에 대해 관심이 있고, 그게 검은색이므로 outerBox를 역변환 해주어야합니다. 그러면, 퍼즐의 경계가 하얗게 변합니다.
그리고 이 thresholding 작업은 연결된 부분(Connected Component)들을 분할 시킬수 있습니다. 그러므로 이를 보완하기위해서 dilate함수가 사용됩니다. 링크참조
가장 큰 blob 찾기
#blob은 object라고 이해하면 될 듯
이 프로젝트에서, blob들을 찾기위해 라이브러리를 써도되지만, 저는 blob을 인지하는 작은 소스를 만들어보았습니다. 만약 라이브러리를 쓰고싶으면, cvBlobsLib를 써도됩니다.
저는, 먼저 floodfill 함수를 사용합니다. 이 함수는 픽셀에서 사각형을 리턴합니다.
우선 우리가 이미지에서 가장 큰 부분을 차지하는게 퍼즐이라고 가정했으므로, 가장 큰 blob 또한 퍼즐이 되어야합니다. 퍼즐이 이미지에서 제일 크므로, 퍼즐의 테두리 상자 경계가 이미지 내의 상자중에선 가장 커야합니다. 그러므로, 우린 floodfill을 통해 그 테두리 상자의 위치를 찾고 저장할 수 있습니다.
Flood filling each blob (진행 중에)
함수에 대한 설명은 원문 포스트를 통해 참조해주세요. 어쨌든 이걸 수행하고 나면 다음과 같은 결과를 얻을 수 있다.
그리고 maxPt엔 가장 큰 blob의 위치가 담긴다. 이 지점부터 흰색으로 floodfill을 수행하면 가장 큰 지점을 흰색으로 하이라이트 할 수 있을 것이다. 다음의 코드를 통해 수행이 가능하다.
가장 큰 blob이 희므로, 다른것들은 까맣게 만들어줄 필요가 있다. 다음과 같은 명령어로 수행할 수 있다.
그 뒤, 이미지를 dilate 했으므로 다시 erode 함수를 통해 복구한다.
최종 결과는 다음과 같다.
선 찾기
OpenCV에서 제공이되므로, 다음과 같은 코드만 사용하면 된다.
자 이제, 우린 각각의 선을 그려볼건데. 아래의 결과가 괜찮은지 안괜찮은지 살펴보자. 참고로 소스는 다음과 같다. 우선 drawLine 함수를 정의한다.
이 함수는 정규화된 선을 취하며(x축의 각과 원래 선의 거리에 따라). 그리고 선이 만약 수직이면(기울기가 무한대이다), 그러면 선이 제대로 그려진거다. 그게 아니라면, 두 점을 찾아 선을 그린다. 결과의 그림은 다음과 같다.
보는 것과 같이 각 선들은 가능한 근사치들을 조금 많이 가지고 있다. 이런 상황은 원래 선이 두꺼울때 나타는 결과이다. (두꺼우니까 가능한 직선들이 여러개가 나타나는것이다.)
그래서 이 선을 이용해 퍼즐이 어디에 위치하고 있나 찾는건 적절하지 않다. 그래서 다음 포스트에서는 이 문제를 해결할까 하는데, 좀 수학적인 이야기가 필요하다.
요약
다음포스트 보기 Extracting the grid
'IoT 과정' 카테고리의 다른 글
sudoku grabber 3 Extracting the grid (0) | 2017.11.24 |
---|---|
sudoku grabber in Opencv (0) | 2017.11.23 |
임베디드 관련 블로그 (0) | 2017.09.08 |
라즈베리파이와 개발pc와의 nfs 설정 및 tftp등등 (0) | 2017.09.07 |
LVM & RAID (0) | 2017.07.19 |
- Total
- Today
- Yesterday
- 이산수학
- Propositional and Predicate Logic
- 이산 수학
- flutter
- 그라파나
- paul wilton
- 엄청난 인내심과 시뮬레이션을 위한 아레나 툴
- Simulation
- 명제논리
- javascript
- grafana cloud
- 아레나
- Arena
- 데이터 중심 애플리케이션 설계
- beginning javascript
- rosen
- 자바스크립트
- 아레나 시뮬레이션
- 아레나시뮬레이션
- 항해99
- 로젠
- 백준
- Discrete Mathematics
- 대규모 시스템 설계 기초
- 가상 면접 사례로 배우는 대규모 시스템 설계 기초
- arena simulation
- 시뮬레이션
- Grafana
- 최단경로 알고리즘
- 자바스크립트 예제
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |