10/13 오늘의 시간표
09:00 ~ 10:00 [테스트] 쪽지시험
10:00 ~ 11:00 [원격] 실전 머신러닝 적용
11:00 ~ 12:00 [원격] 실전 머신러닝 적용
12:00 ~ 13:00 [원격] 실전 머신러닝 적용
13:00 ~ 14:00 점심식사
14:00 ~ 15:00 [원격] 실전 머신러닝 적용
15:00 ~ 16:00 [원격] 실전 머신러닝 적용
16:00 ~ 17:00 [원격] 실전 머신러닝 적용
17:00 ~ 18:00 [원격] 실전 머신러닝 적용
18:00 ~ 19:00 저녁식사
19:00 ~ 20:00 [원격] 실전 머신러닝 적용
20:00 ~ 21:00 [원격] 실전 머신러닝 적용
오늘도 어제와 마찬가지로 실전 머신러닝 적용 원격강의날이었지만 오전에 쪽지시험이 있다는 것이 달랐다.
쪽지시험
- opencv 활용
어제 특강에서 알려주신 opencv와 torch의 사물인식 기능을 활용하는 문제였다.
어제 특강을 통해 필요한 패키지 파일들은 미리 다 받아놓았기 때문에 바로 진행하면 되는 문제였는데 이미지 파일 경로설정에서 오류가 발생해 시간을 많이 잡아먹고 시작했다. 다행히 이미지 파일의 이름에 내가 특수문자를 넣었기 때문에 발생한 오류임을 알게되었고 즉시 수정하여 다음으로 넘어갈 수 있었다.
import torch
import cv2
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
imgs = ['10.13test\photo.jpg']
results = model(imgs)
tmp_img = cv2.imread("10.13test\photo.jpg")
문제를 풀 수 있도록 다음과 같이 기본세팅을 해 두고 본격적으로 작업에 들어갔다.
가로, 세로가 몇 px인지 구하기 위한 방법으로는 여러가지가 있지만 나는 .shape 함수를 활용하였다. .shape 함수는 해당 도형의 높이(세로),넓이(가로),채널 값을 구하는 함수인데 여기에서 나는 채널 값은 필요없고 세로, 가로의 값만 구하면 되기 때문에 인덱스 설정을 통해 앞의 두 값만 가져왔다.
print('세로:', tmp_img.shape[0], 'px', '가로:', tmp_img.shape[1], 'px')
다음으로 해야 할 것은 이미지에서 사람을 찾아 하얀색 네모로 표시하는 것인데 이것은 어제 특강에서 배운 사물인식 기능을 활용하였다.
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())), (255,255,255))
cv2.rectangle(tmp_img, (int(results.xyxy[0][1][0].item()), int(results.xyxy[0][1][1].item())), (int(results.xyxy[0][1][2].item()), int(results.xyxy[0][1][3].item())), (255,255,255))
cv2.rectangle(tmp_img, (int(results.xyxy[0][2][0].item()), int(results.xyxy[0][2][1].item())), (int(results.xyxy[0][2][2].item()), int(results.xyxy[0][2][3].item())), (255,255,255))
cv2.rectangle(tmp_img, (int(results.xyxy[0][3][0].item()), int(results.xyxy[0][3][1].item())), (int(results.xyxy[0][3][2].item()), int(results.xyxy[0][3][3].item())), (255,255,255))
cv2.rectangle(tmp_img, (int(results.xyxy[0][4][0].item()), int(results.xyxy[0][4][1].item())), (int(results.xyxy[0][4][2].item()), int(results.xyxy[0][4][3].item())), (255,255,255))
cv2.imwrite('result1.png', tmp_img)
opencv의 rectangle을 활욯하여 tmp_img안에서 class가 사람으로 분류되는 값 5개에 사각형을 입히고 그 색은 흰색(255,255,255)로 지정하였고 결과물을 result1.png에 저장하도록 했다.
마지막으로 각 사람들의 이미지만 따로 잘라내 people1~5.png에 저장하게 설정하면 쪽지시험은 완료인데 이 부분은 어제 배운 내용안에 포함되지 않아 해결을 위해 구글링을 해 보았다.
opencv에서 이미지파일을 잘라내려면
이미지파일[잘라낼 x축의 범위, 잘라낼 y축의 범위] 인데 이 x축 y축의 범위를 알 필요가 있었다.
print(tep_img.pandas().xyxy[0])를 통해 찾아보니
xmin ymin xmax ymax confidence class name 0 437.679291 163.035065 631.465515 806.554688 0.919314 0 person 1 623.300171 155.730515 790.887573 806.233215 0.906667 0 person 2 763.604370 131.484940 950.967285 816.322571 0.898564 0 person 3 99.867783 106.271996 314.064270 823.680542 0.879437 0 person 4 271.601868 175.287766 458.354980 803.830566 0.856607 0 person 5 513.423645 272.386627 551.081421 458.215179 0.361376 27 tie
이라는 범위가 나왔고 여기서 5번째 index는 class가 27번 tie이기 때문에 필요가 없으므로 0부터 4번까지만 사용하게 될 것이다.
x축의 범위 = xmin:xmax이고 y축의 범위=ymin:ymax이기 때문에 이를 대입해보면
people1 = tmp_img[int(results.xyxy[0][0][0].item()):int(results.xyxy[0][0][2].item()), int(results.xyxy[0][0][1].item()):int(results.xyxy[0][0][3].item())].copy()
cv2.imwrite('people1.png', people1)
people2 = tmp_img[int(results.xyxy[0][1][0].item()):int(results.xyxy[0][1][2].item()), int(results.xyxy[0][1][1].item()):int(results.xyxy[0][1][3].item())].copy()
cv2.imwrite('people2.png', people2)
people3 = tmp_img[int(results.xyxy[0][2][0].item()):int(results.xyxy[0][2][2].item()), int(results.xyxy[0][2][1].item()):int(results.xyxy[0][2][3].item())].copy()
cv2.imwrite('people3.png', people3)
people4 = tmp_img[int(results.xyxy[0][3][0].item()):int(results.xyxy[0][3][2].item()), int(results.xyxy[0][3][1].item()):int(results.xyxy[0][3][3].item())].copy()
cv2.imwrite('people4.png', people4)
people5 = tmp_img[int(results.xyxy[0][4][0].item()):int(results.xyxy[0][4][2].item()), int(results.xyxy[0][4][1].item()):int(results.xyxy[0][4][3].item())].copy()
cv2.imwrite('people5.png', people5)
그런데 막상 작성한 코드로 나온 결과물을 확인해보니 원하는 사람부분이 잘린게 아니라 엉뚱하게 잘려 있었다. 내가 코드작성을 잘못했나 싶어서 여러번 새로 작성해보고 범위지정도 다시해보고 구글링도 새로 해보았지만 해결이 되지않아 결국 튜터님께 여쭤보는게 가장 빠르겠다는 생각에 점심시간이 끝나자마자 튜터님께 질문을 했다.
늘 그랬듯이 해결법은 아주 쉬운것이었는데 x축 y축 순서로 범위를 지정해 둔 것을 y축 x축 순서로 범위를 지정했더니 바로 해결이 되었다. opencv에서는 y축 즉 높이를 먼저 두고 넓이를 두어야 하는 것이다. 일반적으로는 x축이 먼저오는 경우가 많다보니 이런 실수를 하고 만 것이다. 덕분에 이것만 수정하니 금방 해결되었다.
people1 = tmp_img[int(results.xyxy[0][0][1].item()):int(results.xyxy[0][0][3].item()), int(results.xyxy[0][0][0].item()):int(results.xyxy[0][0][2].item())].copy()
cv2.imwrite('people1.png', people1)
people2 = tmp_img[int(results.xyxy[0][1][1].item()):int(results.xyxy[0][1][3].item()), int(results.xyxy[0][1][0].item()):int(results.xyxy[0][1][2].item())].copy()
cv2.imwrite('people2.png', people2)
people3 = tmp_img[int(results.xyxy[0][2][1].item()):int(results.xyxy[0][2][3].item()), int(results.xyxy[0][2][0].item()):int(results.xyxy[0][2][2].item())].copy()
cv2.imwrite('people3.png', people3)
people4 = tmp_img[int(results.xyxy[0][3][1].item()):int(results.xyxy[0][3][3].item()), int(results.xyxy[0][3][0].item()):int(results.xyxy[0][3][2].item())].copy()
cv2.imwrite('people4.png', people4)
people5 = tmp_img[int(results.xyxy[0][4][1].item()):int(results.xyxy[0][4][3].item()), int(results.xyxy[0][4][0].item()):int(results.xyxy[0][4][2].item())].copy()
cv2.imwrite('people5.png', people5)
대신 이렇게 하니까 앞에 만들어 둔 흰색 네모들이 잘라진 이미지에 나와 거슬렸다.
tmp_img = cv2.imread("10.13test\photo.jpg")
people1 = tmp_img[int(results.xyxy[0][0][1].item()):int(results.xyxy[0][0][3].item()), int(results.xyxy[0][0][0].item()):int(results.xyxy[0][0][2].item())].copy()
cv2.imwrite('people1.png', people1)
people2 = tmp_img[int(results.xyxy[0][1][1].item()):int(results.xyxy[0][1][3].item()), int(results.xyxy[0][1][0].item()):int(results.xyxy[0][1][2].item())].copy()
cv2.imwrite('people2.png', people2)
people3 = tmp_img[int(results.xyxy[0][2][1].item()):int(results.xyxy[0][2][3].item()), int(results.xyxy[0][2][0].item()):int(results.xyxy[0][2][2].item())].copy()
cv2.imwrite('people3.png', people3)
people4 = tmp_img[int(results.xyxy[0][3][1].item()):int(results.xyxy[0][3][3].item()), int(results.xyxy[0][3][0].item()):int(results.xyxy[0][3][2].item())].copy()
cv2.imwrite('people4.png', people4)
people5 = tmp_img[int(results.xyxy[0][4][1].item()):int(results.xyxy[0][4][3].item()), int(results.xyxy[0][4][0].item()):int(results.xyxy[0][4][2].item())].copy()
cv2.imwrite('people5.png', people5)
그냥 tmp_img파일을 흰 네모가 그려지기 전인 새걸로 가져와서 이를 해결했다.
이렇게 해서 나온 결과물을 GitHub에 올리고나니 오늘의 쪽지시험내용이 끝이났다.
10.13 쪽지시험 결과물 GitHub 링크
원래는 1시간짜리 쪽지시험인데 시간안에 해결하지 못하고 오전시간을 전부 소모해버렸다. 시간안에 한번에 해결한 분들은 이걸 어떻게 한시간안에 한건지 정말 대단하다고 생각이 들었다.
머신러닝 적용 원격 강의
- 4주차
오늘 하루를 마치며
오늘도 하루종일 열심히 머신러닝을 배웠는데 머리가 채워지고는 있지만 이해가 되고있냐라고 묻는다면 아직도 물음표이다. 그래도 쪽지시험을 통해 시간과 노력을 부으면 할 수 있다는 것을 알게되었으니 나쁘지않은 하루였다고 생각한다.