실시간 킥보드 헬멧 단속 시스템 - 프로젝트 배경과 Dataset 구성
프로젝트 배경
2021년 5월 13일부터 도로교통법 개정으로 인해 전동 킥보드를 이용할 때 안전모를 착용하지 않으면 범칙금 2만원을 내야합니다. 하지만 여전히 안전모를 착용하지 않고 전동 킥보드를 이용하지 않는 많은 사람들이 존재하며, 경찰분들이 일일이 모두 단속할 수는 없기 때문에 실시간 킥보드 단속 시스템을 구상하게 되었습니다.
Dataset 구성
- 인터넷에서 수집한 사진 172장
- 직접 촬영한 사진 598장
- 비디오로 헬멧을 쓰고 전동킥보드를 이용하는 것과 헬멧을 쓰지 않고 전동 킥보드를 이용하는 모습을 촬영한 뒤 프레임 단위로 캡처되는 이미지로 변환하여 저장하였습니다.
import os
import cv2
def video2frame(video_name, invideofilename, save_path):
vidcap = cv2.VideoCapture(invideofilename)
count = 0
while True:
success,image = vidcap.read()
if not success:
break
if(int(vidcap.get(1)) % 10 == 0):
print ('Read a new frame: ', success)
fname = "{}.jpg".format("{0:05d}".format(count))
cv2.imwrite(save_path + video_name + '_' + fname, image) # save frame as JPEG file
count += 1
print("{} images are extracted in {}.". format(count, save_path))
video_list = os.listdir('./kickboard_video')
for video_name in video_list:
name = video_name.split('.')[0]
video2frame(name, './kickboard_video/' + video_name, './images/')
- 비디오로 헬멧을 쓰고 전동킥보드를 이용하는 것과 헬멧을 쓰지 않고 전동 킥보드를 이용하는 모습을 촬영한 뒤 프레임 단위로 캡처되는 이미지로 변환하여 저장하였습니다.
import os
import cv2
def video2frame(video_name, invideofilename, save_path):
vidcap = cv2.VideoCapture(invideofilename)
count = 0
while True:
success,image = vidcap.read()
if not success:
break
if(int(vidcap.get(1)) % 10 == 0):
print ('Read a new frame: ', success)
fname = "{}.jpg".format("{0:05d}".format(count))
cv2.imwrite(save_path + video_name + '_' + fname, image) # save frame as JPEG file
count += 1
print("{} images are extracted in {}.". format(count, save_path))
video_list = os.listdir('./kickboard_video')
for video_name in video_list:
name = video_name.split('.')[0]
video2frame(name, './kickboard_video/' + video_name, './images/')
⭐ 원본 데이터 셋이 770장으로 적은 편이기 때문에 Data Augmentation을 통해 늘릴 것 입니다.
Data Labeling
Data Labeling은 Make Sense를 이용하여 하였습니다. 라벨은 헬멧을 쓴 사람과 헬멧을 쓰지 않은 사람으로 2가지로 하였고 킥보드까지 전체 모습으로 하여야 전체 모습을 인식할 수 있기 때문에 전체 모습을 라벨링하였습니다.
Data Augmentation
다음 주소의 Github를 참고하여 코드를 만들었습니다. 코드의 기능은 이미 라벨링 되어 있는 이미지를 augmentation하고 라벨링까지 augmentation된 이미지에 맞게 바꿔주기 때문에 추가적인 라벨링 과정이 필요없기 때문에 유용합니다.
from data_aug.data_aug import *
from data_aug.bbox_util import *
import numpy as np
import cv2
import matplotlib.pyplot as plt
import pickle as pkl
%matplotlib inline
import os
from PIL import Image
def convert(size, box):
dw = 1./size[1]
dh = 1./size[0]
x = (box[0] + box[2])/2.0
y = (box[1] + box[3])/2.0
w = box[2] - box[0]
h = box[3] - box[1]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
img_path = '../images/' # 이미지 경로
label_path = '../labels/' # 라벨 경로
img_li = os.listdir(img_path)
label_li = os.listdir(label_path)
for i in range(len(img_li)):
file_name = img_li[i].split('.')[0]
image = '../images/' + img_li[i]
print('이미지 경로', image)
img = cv2.imread(image)[:,:,::-1]
label_name = label_path + image.split('/')[-1].split('.')[0] + '.txt'
print('라벨 경로', label_name)
size = []
size.append(img.shape[0])
size.append(img.shape[1])
print('이미지 크기', str(size))
bboxes = np.loadtxt(label_name, delimiter=' ', skiprows=0, dtype=float)
print('읽은 라벨 값 yolo', bboxes)
if bboxes.ndim==1:
rebboxes=np.zeros((1,bboxes.shape[0]))
else:
rebboxes=np.zeros(bboxes.shape)
if bboxes.ndim==1:
rebboxes[0][0]=bboxes[1]
rebboxes[0][1]=bboxes[2]
rebboxes[0][2]=bboxes[3]
rebboxes[0][3]=bboxes[4]
rebboxes[0][4]=bboxes[0]
boundingbox=np.zeros(rebboxes.shape)
else:
rebboxes=bboxes[:,1:]
rebboxes=np.hstack([rebboxes,bboxes[:,0:1]])
boundingbox=np.zeros(bboxes.shape)
print('순서 바꿈', rebboxes)
#([0]=좌측상단 x, [1]=좌측상단 y, [2]=우측하단 x,[3]=우측하단 y)
for i in range(boundingbox.shape[0]):
boundingbox[i,0], boundingbox[i,1] = size[1] * (rebboxes[i,0] - rebboxes[i,2] / 2), size[0] * (rebboxes[i,1] - rebboxes[i,3] / 2)
boundingbox[i,2], boundingbox[i,3] = size[1] * (rebboxes[i,0] + rebboxes[i,2] / 2), size[0] * (rebboxes[i,1] + rebboxes[i,3] / 2)
boundingbox[i,4]=rebboxes[i,4]
print('바운딩 박스', boundingbox)
# augmentation 과정
seq = Sequence([RandomHSV(40, 40, 30),RandomHorizontalFlip(), Scale(-0.7, -0.7),Translate(0.2, 0.2), RandomRotate(10), RandomShear()])
img_, boundingbox_ = seq(img.copy(), boundingbox.copy())
plotted_img = draw_rect(img_, boundingbox_)
plt.imshow(plotted_img)
yolobox=np.zeros((boundingbox_.shape))
plt.show()
# 라벨을 YOLO 형식으로 바꿔주는 과정
for i in range(0,boundingbox_.shape[0]):
x,y,w,h=convert(size,boundingbox_[i])
yolobox[i][0]=boundingbox_[i][4]
yolobox[i][1]=x
yolobox[i][2]=y
yolobox[i][3]=w
yolobox[i][4]=h
new_img_ = Image.fromarray(img_)
# augmentation한 이미지와 라벨 저장
print(new_img_.save('../aug_images_3/'+ 'aug_3_'+ file_name + '.jpg'))
print(np.savetxt('../aug_labels_3/' + 'aug_3_'+ file_name + '.txt',yolobox, fmt='%f',delimiter=' '))
Augmentation 결과
Author And Source
이 문제에 관하여(실시간 킥보드 헬멧 단속 시스템 - 프로젝트 배경과 Dataset 구성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jsleeg98/실시간-킥보드-단속-시스템-프로젝트-프로젝트-배경과-Dataset-구성저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)