🔎 명세
>> 사각형 내의 원의 수 세기
• 한 이미지 내에 여러 개의 사각형 존재
• 각 사각형 안에 각각 n개의 원이 있을 때, 각 사각형 별로 내 부에 있는 원의 숫자를 오름차순으로 console에 출력하기
• Grayscale 입력
• 배경은 어두운 색으로 가정
• 사각형의 배경색은 밝은 색으로 가정
• 원의 색은 어두운 색으로 가정
🔎 구현 단계
1. 회색조로 주사위 사진 파일 열기
• imread() 함수의 인자로 cv.IMREAD_GRAYSCALE을 넣어 회색조로 사진 파일을 열었다.
2. 이진화
• threshold() 함수의 인자로 cv.THRESH_OTSU를 이용해 자동으로 임계값을 결정했다.
3. 레이블링
• connectedComponents() 함수를 이용해 각 주사위 객체를 분리했다.
4. 외곽선 찾기
• findContours() 함수의 인자로 cv.RETR_CCOMP를 넣어 모든 외곽선을 검색하고 2단계 계층 구조를 구성하도록 했다. 또한 눈으로 외곽선이 잘 검출되었나 확인하기 위해 drawContours() 함수를 이용해 검출된 외곽선을 그렸다.
5. 객체(주사위) 당 눈금 수 세기
• 다음과 같이 주사위 하나를 정하는 반복문과 주사위 내부 눈금을 세는 반복문 두개를 사용하여 각 주사위에 눈금을 센 후 이를 list에 저장해 둔다.
• 다음 부분에 해당한다.
# 객채 마다 내부 외곽선 개수 세기
i=0
j=0
dice = [] # 읽은 눈금 저장 list
while (i!=-1): # 주사위 하나를 세는 반복문
j = hierarchy[0, i, 2] # j는 다음에 볼 인덱스
dicenum = 0
while (j!=-1): # 주사위 내부 눈금 수를 세는 반복문
dicenum += 1 # 눈금 세기
j = hierarchy[0,j,0]
i = hierarchy[0, i, 0] # 다음 객체(주사위)로 이동
dice.append(dicenum) # list에 읽은 눈금 넣어두기
6. 출력
• sort() 함수를 이용해 list내부의 수를 오름차순으로 정렬한 뒤 순서대로 출력한다.
🔎 소스코드
import random
import cv2 as cv
def detectDice2():
# 회색조로 파일 열기
src = cv.imread('dice2.jpg', cv.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
return
# 이진화
_, dst = cv.threshold(src, 0, 255, cv.THRESH_OTSU)
# 레이블링
cnt, lables = cv.connectedComponents(dst)
# print(f'cnt : {cnt}')
# print(f'labels : {np.max(lables)}')
# 외곽선 찾기
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]
# hierarchy[0,0,0] # 10
# hierarchy[0,10,0] # 19
# hierarchy[0,19,0] # 27
# hierarchy[0,27,0] # 34
# hierarchy[0,34,0] # 40
# hierarchy[0,40,0] # 45
# hierarchy[0,45,0] # 49
# hierarchy[0,49,0] # 52
# hierarchy[0,52,0] # -1
# 객채 마다 내부 외곽선 개수 세기
i=0
j=0
dice = [] # 읽은 눈금 저장 list
while (i!=-1): # 주사위 하나를 세는 반복문
j = hierarchy[0, i, 2] # j는 다음에 볼 인덱스
dicenum = 0
while (j!=-1): # 주사위 내부 눈금 수를 세는 반복문
dicenum += 1 # 눈금 세기
j = hierarchy[0,j,0]
i = hierarchy[0, i, 0] # 다음 객체(주사위)로 이동
dice.append(dicenum) # list에 읽은 눈금 넣어두기
dice.sort() # 오름차순 정렬
for i in range(0, len(dice)):
print(f'주사위 눈금 : {dice[i]}')
cv.imshow('src', src)
cv.imshow('dst', dst)
cv.waitKey()
detectDice2()
'컴퓨터 비전' 카테고리의 다른 글
[OpenCV][Python] 주사위 눈금 읽기 (0) | 2022.12.14 |
---|---|
[OpenCV][Python] 사각형 내의 원의 수 세기 | 주사위 눈금 읽기 | 하나의 사각형(객체) 대해 수행 (0) | 2022.12.14 |
[Python] Numpy 에러 - AttributeError: partially initialized module 'numpy' has no attribute 'array' (0) | 2022.11.04 |
[Python][OpenCV] 이미지 열고 밝기 조절 후 저장하기 - 평균 밝기를 기준으로 (0) | 2022.10.13 |
cv.cvtColor(frame, cv.COLOR_BGR2GRAY)후 write로 영상 저장 시 오류 (0) | 2022.10.12 |