대기열 혼잡도 검색 시스템
프로젝트를 진행함에 있어서 사진으로부터 사람 수를 추출하는 모듈이 필요하게 되었다.
object detection에 있어서 가장 성능이 좋은 yolo를 활용해서 모듈을 만들어 보기로 하였다.
자세한 설명은 공식 페이지
(option)gpu 사용 설정
CMake 다운로드
Path
에 설치한 cmake/bin 경로를 추가해주어야 한다.darknet-yolov4 다운로드 (repository)
yolov4.weights
와 Source code (zip)
을 다운받고 소스코드의 압축을 풀고 소스코드 내부에 yolov4.weights
파일을 넣는다. 그리고 build.ps1
을 실행 시키고 현재 환경에 맞게 빌드를 진행한다.darknet_yolov4 폴더내에 보면 darknet_images.py 파일이 있는데 이를 실행시키고 이미지 경로를 입력하면 객체검출을 해준다.
먼저 detections 데이터를 반환하는 함수를 살펴보면 다음과 같다.
def image_detection(self, image_path, network, class_names, class_colors, thresh):
# Darknet doesn't accept numpy images.
# Create one with image we reuse for each detect
width = darknet.network_width(network)
height = darknet.network_height(network)
darknet_image = darknet.make_image(width, height, 3)
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
darknet.free_image(darknet_image)
return detections
width = darknet.network_width(network)
height = darknet.network_height(network)
darknet_image = darknet.make_image(width, height, 3)
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
darknet.free_image(darknet_image)
return detections
리스트에 객체들에 대한 정보가 튜플형태로 포함되어 있으며 각 객체의 형태는 다음과 같다.
('객체', '확률', '객체 바운딩 박스 좌표')
PeopleCounter 라는 클래스를 만들어서 사진으로부터 사람 수를 셀 수 있도록 하였다. 다음은 메소드들에 대한 설명이다.
코드
from darknetyolov4 import darknet
import random
import cv2
import os
class PeopleCounter:
def __init__(self):
random.seed(3) # deterministic bbox colors
cd_path = os.path.dirname(os.path.abspath(__file__))
self.network, self.class_names, self.class_colors = darknet.load_network(
cd_path + '/darknetyolov4/cfg/yolov4.cfg',
cd_path + '/darknetyolov4/cfg/coco.data',
cd_path + '/darknetyolov4/yolov4.weights',
batch_size=1
)
def image_detection(self, image_path, network, class_names, class_colors, thresh):
# Darknet doesn't accept numpy images.
# Create one with image we reuse for each detect
width = darknet.network_width(network)
height = darknet.network_height(network)
darknet_image = darknet.make_image(width, height, 3)
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
darknet.free_image(darknet_image)
return detections
def count_people(self, image_name):
detections = self.image_detection(
image_name, self.network, self.class_names, self.class_colors, 0.3
)
cnt = 0
for i in detections:
if i[0] == 'person':
cnt+=1
return cnt