YOLO
1234객체 분류(object classification)을 위해서 먼저 해야 될 작업이 아마도 객체를 탐지하는 것이 아닐까 싶다. MNIST와 같은 데이터는 이미 손글씨를 탐지해서 인식 및 분류를 위한 사전준비가 완료된 상황이고, 대부분의 객체분류문제는 먼저 객체를 탐지하는 것부터 시작된다.
신경망 분류모형은 기본적으로 지도학습(Supervised Learning)이라 라벨 작업이 먼저 사람에 의해 이뤄져야 한다. 이미지 라벨작업을 수월히 하는데 LabelImg
등 도구가 있어 YOLO
모형 개발에 필요한 라벨 생성작업에 도움을 줄 듯 싶다.
이미지에서 객체가 위치한 곳을 제대로 탐지하는지 먼저 살펴보자. 이를 위해서 대상 이미지를 magick
팩키지로 살펴보자.
library(tidyverse)
library(magick)
airplane <- image_read("fig/airplane.jpeg")
airplane %>%
image_resize(200)
YOLO
팩키지 설치image.darkent
팩키지를 설치하여 이미지에서 YOLO
알고리즘으로 이미지 탐지를 위한 팩키지를 설치한다.
YOLO
실행YOLO
Real-Time Object Detection이 현재 가장 성능이 좋다고 하며, 파스칼 타이탄 X (Pascal Titan X) GPU 칩을 기준으로 초당 30 프레임(30 FPS) 속도로 COCO
데이터셋 기준 mAP(mean Average Precision) 57.9%을 기록하고 있다.
library(image.darknet)
labels_COCO <- readLines(
system.file(package="image.darknet", "include", "darknet", "data",
"coco.names")
)
yolo_cfg <- "DL_library//yolov2.cfg"
yolo_weights <- "DL_library/yolov2.weights"
yolo_COCO <- image_darknet_model(type = 'detect',
model = yolo_cfg,
weights = yolo_weights,
labels = labels_COCO)
# yolo_COCO$labels
image_darknet_detect(file = "fig/airplane.jpeg",
object = yolo_COCO,
threshold = 0.5)
predictions.png
파일로 출력결과만 떨어질 뿐, 후속 작업을 위한 텍스트를 잡아낼 수 없기 때문에 yolo
알고리즘 실행 중 콘솔에 떨어지는 출력결과를 방향을 바꿔(redirect)시켜 파일에 텍스트로 떨어뜨린다.
## lapply 적용을 위한 함수: 매개변수 다수 전달
detect_object <- function(filename){
pred <- image_darknet_detect(file = filename,
object = yolo_COCO,
threshold = 0.19)
}
# detect_object("fig/airplane.jpeg")
## 결과값을 가로채는 함수
library(Rcpp)
cppFunction('void redir() {FILE* F = freopen("capture.txt", "w+", stdout);}')
redir()
yolo_df <- lapply("fig/airplane.jpeg", detect_object)
yolo_df <- tibble(text = read_lines("capture.txt"))
system("rm capture.txt")
yolo_df
# A tibble: 0 x 1
# … with 1 variable: text <chr>
먼저 다수 이미지를 가져온다. 이를 yolo
알고리즘을 태우고 텍스트 파일에 저장한다.
## 대상 이미지 지정
filenames <- list.files(path = "fig/yolo/")
path_filenames <- glue::glue("fig/yolo/{filenames}")
## 다수 이미지 위치 정보를 텍스트로 저장
redir()
image_df <- lapply(path_filenames, detect_object)
image_df <- tibble(text = read_lines("capture.txt"))
system("rm capture.txt")
# image_df %>% write_rds("data/image_df.rds")
텍스트로 추출한 데이터를 후속 처리가 가능한 데이터프레임으로 변환시킨다.
image_dat <- read_rds("data/image_df.rds")
image_df <- image_dat %>%
filter(!str_detect(text, "^Boxes")) %>%
mutate(file = str_extract(text, ".*\\.jpe?g")) %>%
tidyr::fill(file, .direction = "down") %>%
mutate(file = str_remove(file, "fig/yolo/"))
image_df <- image_df %>%
mutate(processing = str_extract(text, "\\d\\.\\d+ seconds")) %>%
tidyr::fill(processing) %>%
separate(text, into = c("object", "confidence"), sep=":") %>%
filter(!str_detect(object, "fig/yolo/")) %>%
mutate(confidence = str_trim(confidence)) %>%
select(file, processing, object, confidence)
image_df
# A tibble: 12 x 4
file processing object confidence
<chr> <chr> <chr> <chr>
1 airplane_and_ship.jpg 8.485884 seconds aeroplane 77%
2 airplane_and_ship.jpg 8.485884 seconds boat 60%
3 airplane_lighthouse.jpeg 8.717672 seconds aeroplane 85%
4 airplane_ship_ocean.jpeg 8.447571 seconds aeroplane 86%
5 airplane_ship_ocean.jpeg 8.447571 seconds boat 42%
6 airplane_ship_ocean.jpeg 8.447571 seconds boat 79%
7 cat_dog.jpg 8.347606 seconds dog 25%
8 cat_dog.jpg 8.347606 seconds orange 29%
9 cat_dog.jpg 8.347606 seconds cat 68%
10 cats_dogs.jpeg 8.373252 seconds dog 64%
11 cats_dogs.jpeg 8.373252 seconds person 19%
12 cats_dogs.jpeg 8.373252 seconds cat 95%
다수 이미지를 YOLO
알고리즘으로 추출하여 작업한 결과를 이미지와 텍스트로 저장시켜 두고 이를 제대로 작업했는지 시각적으로 확인하는 과정을 거친다.
## lapply 적용을 위한 함수: 매개변수 다수 전달
detect_object <- function(filename){
pred <- image_darknet_detect(file = filename,
object = yolo_COCO,
threshold = 0.19)
file_extension <- basename(filename)
only_filename <- tools::file_path_sans_ext(file_extension)
mv_instruction <- glue::glue("mv predictions.png fig/yolo/{only_filename}_yolo.png")
# system("mv predictions.png fig/yolo/predictions.png")
system(mv_instruction)
}
# detect_object("fig/airplane.jpeg")
## 결과값을 가로채는 함수
library(Rcpp)
cppFunction('void redir() {FILE* F = freopen("capture.txt", "w+", stdout);}')
redir()
## 배치처리
redir()
image_df <- lapply(path_filenames, detect_object)
image_df <- tibble(text = read_lines("capture.txt"))
system("rm capture.txt")
이제 작업된 결과를 다음과 같은 방식으로 후속작업을 할 수 있다.
magick
팩키지 stack
기능magick
팩키지 GIF
기능slickR
.tabset
기능trelliscopeJS
기능magic
팩키지를 통해 다양한 작업을 배치처리 하고자 할 경우 먼저 이미지를 리스트로 만들고 이를 image_join()
함수를 사용해서 결합을 시키고 나서, GIF 로 만들어 최종 결과물을 만들어 낸다.
## 이미지 파일 목록
yolo_path_filenames <- glue::glue("fig/yolo/{list.files('fig/yolo')}")
## 이미지 파일 객체
yolo_images <- map(yolo_path_filenames, magick::image_read)
yolo_images <- map(yolo_images, magick::image_resize, geometry = 500 )
## 이미지 파일 결합: list --> 데이터프레임
yolo_images_data <- yolo_images %>%
image_join()
## GIF 생성: 데이터프레임 --> GIF
yolo_images_data %>%
image_animate(fps = 1)