-
[퍼즐:01] 퍼즐 조각 외곽선 추출개발 2023. 8. 6. 18:10
https://hellojkw.tistory.com/entry/직소-퍼즐-맞추는-프로그램-단계
퍼즐을 맞추기 위한 단계 중 핵심은 사진을 디지털 퍼즐 객체로 바꾸는 것이다.
그 첫 번재가 외곽선을 추출하는 것.
Canny 라는 알고리즘이 대표적인 윤곽선 알고리즘인데 잘 모르겠어서 접어뒀다.
배경과 전경(사물)을 분리하는 알고리즘으로 GrabCut을 알게 되었다.
속도가 너무 느리기도 하고 퍼즐에 잘 맞지도 않았다.
알고리즘이 퍼즐을 사물로 인식을 잘 못하는 것 같다.
배경이 흰색, 검정색 모두 잘 동작하지 않았고,
그림자 문제 해결도 쉽지 않았다.
그리고 처음엔 LINQPad에서 C#으로 개발했었는데,
모든 예제가 python으로 되어 있어서
어차피 맥북 많이 쓰니까 테스트는 그냥 맥에서 python으로 했다.
다시 돌고돌아 Canny로 왔다.
Canny를 쓰기 전처리를 해야겠다는 생각을 했다.
1. 흰/검 으로 구분
2. 노이즈 제거
두가지가 중요했는데,
가우시안 필터로 노이즈를 제거하고,
흰/검으로 변경했더니 잘 동작했다.
순서
- 회색조로 변경
- 가우시안 필터 적용
- 흰/검 으로 변환
- Canny 적용
윤곽선을 추출했다!
이제 코너를 찾고, 엣지를 추출해야 한다.
코드의 각종 값은 대충 동작하는 선에서 대충 넣은 것.. (공부를 많이 하진 않음..ㅋㅋ)
https://github.com/jkwchunjae/JigsawPuzzleSolver/commit/f00f261e6d08e1372d8bd5db70779fdd2d3d49bc
import cv2 # 이미지를 불러오고 그레이스케일로 변환 image = cv2.imread('20230804_225655_3.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gaussian = cv2.GaussianBlur(gray, (5, 5), 0) _, black_white = cv2.threshold(gaussian, 127, 255, cv2.THRESH_BINARY) # 경계선 검출 (Canny edge detection 예제) edges = cv2.Canny(black_white, 50, 255) cv2.imshow('gray', gray); cv2.imshow('gaussian', gaussian); cv2.imshow('black_white', black_white); # 경계선 검출 결과에서 퍼즐 조각의 외곽을 감싸는 경계 상자를 찾음 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) puzzle_contour = max(contours, key=cv2.contourArea) cv2.drawContours(image, [puzzle_contour], -1, (0, 255, 0), 2); # 퍼즐 영역 추출 # x, y, w, h = cv2.boundingRect(puzzle_contour) # puzzle_area = image[y:y+h, x:x+w] # 결과 이미지 출력 cv2.imshow('Puzzle Area', image) cv2.waitKey(0) cv2.destroyAllWindows()
'개발' 카테고리의 다른 글
[퍼즐:05] 모서리 테스트 (0) 2023.08.11 [퍼즐:04] 퍼즐 모서리 정규화 (0) 2023.08.08 [퍼즐:03] 퍼즐 조각 외곽선을 각 모서리로 분할 (0) 2023.08.07 [퍼즐:02] 퍼즐 조각 외곽선에서 코너 검출 (0) 2023.08.06 [퍼즐:00] 직소 퍼즐 맞추는 프로그램 단계 (0) 2023.03.02