우연찮게 당시 코드를 짜면서 찍은 사진들을 찾아서 이를 추가했습니다.

기존의 방식으로는 갯수를 정확히 따질 수 없어서 HoughCircles를 이용하기로 했다.
기구와 정확히 구분되는 파란색 원형스티커를 각각의 추에 붙이고 해당 스티커의 수를 세는 방식이다.
또한 스티커를 일직선으로 붙이고 ROI를 더 좁게 설정하여 판정의 정확도를 올렸다.
항상 측정하여 연산을 진행하면 라즈베리파이에 부하가 걸릴 수 있으므로 추에 초음파센서를 달아 일정높이 이상올라가면 스티커의 개수를 측정하는 방식으로 진행하였다.

이때 사용한 코드는 아래와 같다

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,500)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,300)
if cap.isOpened():
    ret,a=cap.read()
    while ret:
        ret,a=cap.read()

        dst = a.copy()
        a=cv2.medianBlur(a,5)
        a=a[31:170,146:260]
        dst=dst[31:170,146:260]
        gray = cv2.cvtColor(a, cv2.COLOR_BGR2HSV)
        hsv_1=np.array([95,70,100]) # 파란색 하한선
        hsv_2=np.array([135,255,255])# 파란색 상한선
        img_mask=cv2.inRange(gray,hsv_1,hsv_2) #이미지 마스크 제작
        circles = cv2.HoughCircles(img_mask, cv2.HOUGH_GRADIENT, 1, 100, param1 = 255, param2 = 10, minRadius = 2, maxRadius = 25) #2에서 25사이의 반지름을 가진 원 검출
        if circles is not None:
            for i in circles[0]:
                cv2.circle(dst, (int(i[0]), int(i[1])), int(i[2]), (255, 255, 255), 5)

        cv2.imshow("camera",dst)
        cv2.imshow("camera2",img_mask)
        if cv2.waitKey(1) & 0xFF == 27:
            break
cap.release()
cv2.destroyAllWindows()

허나 위의 과정을 거쳤을때 파란색 스티커와 웹캠이 완벽하게 평행할 때를 제외하고는 검출이 정상적으로 되지 않았다.

위의 그림을 보면 3개의 스티커 중 가운데의 스티커만 원으로 인식하여 camera창에 테두리가 그려진 것을 볼 수 있다.

이를 해결하기 위해서 HoughCircles 대신 connectedComponentsWithStats을 사용하여 labeling을 진행하였다.
connectedComponents가 아니라 connectedComponentsWithStats를 사용하게 된 이유는 해당 함수가 객체의 크기와 중심을 return해 주기 때문이다.

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,500)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,300)
if cap.isOpened():
    ret,a=cap.read()
    while ret:
        ret,a=cap.read()
        dst = a.copy()
        a=cv2.medianBlur(a,5)
        a=a[31:170,146:260]
        dst=dst[31:170,146:260]
        gray = cv2.cvtColor(a, cv2.COLOR_BGR2HSV)
        hsv_1=np.array([95,70,100])
        hsv_2=np.array([135,255,255])
        img_mask=cv2.inRange(gray,hsv_1,hsv_2)
        cnt, labels, stats, centroids = cv2.connectedComponentsWithStats(img_mask)
        for i in range(1,cnt):
            (x,y,w,h,area)=stats[i]
            if area <5: # 크기가 5이하면 무시
                continue
            cv2.rectangle(dst,(x-5,y-5,w+10,h+10),(255,255,255)) # 그 외의 경우 주위에 흰 테두리를 설정함
        cv2.imshow("camera",dst)
        cv2.imshow("camera2",img_mask)
        if cv2.waitKey(1) & 0xFF == 27:
            break
cap.release()
cv2.destroyAllWindows()

이를 통해서 무게추의 움직임을 측정할 수 있었다.


측정 실험 당시 카메라를 배치할 방법이 없어서 아령으로 높이를 맞춰 진행했던 사진이다. 2번째 사진을 보면 추에 파란색 스티커를 붙여 진행했다는 걸 알 수 있다.

0개의 댓글