django 머신러닝 팀 프로젝트를 진행하면서 사용자가 업로드한 이미지 파일을 머신러닝으로 인식하여 다시 사용자에게 원본에서 머신러닝이 인식한 부분을 라벨링한 사진과 함께 카테고리를 전달해주는 것을 구현하던 중 머신러닝으로 사물 인식을 하는 부분이 이해가 되지 않았다.
yolov5를 사용한 사물인식 강의 내용을 토대로 팀원과 구글링을 하면서 코드를 하나하나 파헤치기 시작하면서 추상적으로나마 이해할 수 있었다.
코드를 파헤치면서 cv2의 imread(파일 읽기), imwrite(편집한 파일 저장), rectangle(x,y 좌표로 라벨링)과 to_numpy(n차원 배열 형태로 변환) 등을 알 수 있었다.
현재는 yolov5를 사용하기 위한 사용법을 알아본 수준으로 이해했지만 조금 더 깊게 이해하면서 응용할 수 있도록 나중에 더 공부해야 할 것 같다.
import torch
import cv2
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
# model 변수에 torch.hub.load 메소드로 ultralytics의 yolov5 레포지토리의 yolov5s 모델을 불러옴
img = cv2.imread('zidane.jpg')
# cv2의 imread 함수로 zidane.jpg를 읽어 img에 저장
results = model(img)
# 위에서 선언한 model에 zidan.jpg 이미지를 넣어 results로 사용
results.save()
# 컴퓨터 디스크에 저장
result = results.pandas().xyxy[0].to_numpy()
# 위의 results를 pandas의 xmin, xmax, ymin, ymax 좌표로 변환하고,
# to_numpy로 x,y 좌표를 ndarray 타입(n차원 배열 객체)으로 바꿔준다.
result = [item for item in result if item[6]=='person']
# 변환된 배열 객체를 반복문과 조건문을 통해 6번 컬럼이 person인 값만 result에 담아준다.
tmp_img = cv2.imread('zidane.jpg')
print(tmp_img.shape)
# zidane.jpg을 cv2.imread로 읽어 tmp_img에 저장 후 tmp_img의 모양을 print함.
cropped = tmp_img[int(result[0][1]):int(result[0][3]), int(result[0][0]):int(result[0][2])]
# person = result[0]이고, [1] [3] [0] [2] x y x y 좌표 만큼 사진을 자름
print(cropped.shape)
# 자른 person의 크기(shape)를 출력
cv2.imwrite('zidane.png', cropped)
# cv2 imwrite로 zidane.png의 cropped 만큼 자른 이미지를 저장
cv2.rectangle(tmp_img, (int(results.xyxy[0][0][0].item()), int(results.xyxy[0][0][1].item())), (int(results.xyxy[0][0][2].item()), int(results.xyxy[0][0][3].item())), (0,0,255))
# tmg_img에 위 좌표로 네모 표시를 해 준다.
cv2.imwrite('zidane2.png', tmp_img)
# 이미지 zidane.png 라는 이름으로 저장