본문 바로가기
컴퓨터 비전

[OpenCV][Python] 사각형 내의 원의 수 세기 | 주사위 눈금 읽기 | 하나의 사각형(객체) 대해 수행

by miiinn 2022. 12. 14.

🔎 명세

>> 사각형 내의 원의 수 세기 

• 한 이미지 내에 하나의 사각형이 있고, 그 안에 n개의 원이 있을 때, 원의 숫자를 console에 출력하기
• Grayscale 입력
    • 배경은 어두운 색으로 가정
    • 사각형의 배경색은 밝은 색으로 가정
    • 원의 색은 어두운 색으로 가정

🔎 구현 단계

 

1. 회색조로 주사위 사진 파일 열기

imread() 함수의 인자로 cv.IMREAD_GRAYSCALE을 넣어 회색조로 사진 파일을 열었다.

 

 

2. 이진화

 threshold() 함수의 인자로 cv.THRESH_OTSU를 이용해 자동으로 임계값을 결정했다.

 

 

3. 외곽선 찾기

 findContours() 함수의 인자로 cv.RETR_CCOMP를 넣어 모든 외곽선을 검색하고 2단계 계층 구조를 구성하도록 했다. 또한 눈으로 외곽선이 잘 검출되었나 확인하기 위해 drawContours() 함수를 이용해 검출된 외곽선을 그렸다.

 

 

4. 주사위 눈금 읽기

 주사위 눈금을 읽기 위해 검출된 외곽선들 중에 부모 계층(사각형 부분)이 아니라 자식 계층(동그라미 부분)의 개수를 세기 위해 전체 외곽선 개수(len(hierarchy[0]))만큼 반복문을 돌려 배열의 4번째 부분이 0(자식 계층)일 때만 수를 더해주었다.

<hierarchy> 출력

<hierarchy>의 출력 결과에서  4번째 요소가 -1이면 부모 계층 / 0이면 자식 계층

 


🔎 소스코드

import random
import cv2 as cv

def detectDice1():
    # 회색조로 파일 열기
    src = cv.imread('dice_seven.jpg', cv.IMREAD_GRAYSCALE)

    if src is None:
        print('Image load failed!')
        return

    # 이진화
    _, dst = cv.threshold(src, 0, 255, cv.THRESH_OTSU)

    # 외곽선 찾기
    contours, hierarchy = cv.findContours(dst, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)

    idx = 0
    while idx >= 0:
        c = (random.randint(0, 255), random.randint(0, 255), random.randint(0,255))
        cv.drawContours(dst, contours, idx, c, 2, cv.LINE_8, hierarchy)
        idx = hierarchy[0, idx, 0]

    # 검출된 외곽선 만큼 반복. 부모 아닌 외곽선 개수 세기
    dicenum = 0
    for i in range (0, len(hierarchy[0])):
        isParent = hierarchy[0, i, 3] # 부모 외곽선이면 -1, 자식이면 0
        if (not isParent): # 자식일 경우 눈금이므로 세기
            dicenum += 1

    print(f'주사위 눈금 : {dicenum}')

    cv.imshow('src', src)
    cv.imshow('dst', dst)
    cv.waitKey()

detectDice1()