YOLO
1234객체 분류(object classification)을 위해서 먼저 해야 될 작업이 아마도 객체를 탐지하는 것이 아닐까 싶다. MNIST와 같은 데이터는 이미 손글씨를 탐지해서 인식 및 분류를 위한 사전준비가 완료된 상황이고, 대부분의 객체분류문제는 먼저 객체를 탐지하는 것부터 시작된다.
신경망 분류모형은 기본적으로 지도학습(Supervised Learning)이라 라벨 작업이 먼저 사람에 의해 이뤄져야 한다. 이미지 라벨작업을 수월히 하는데 LabelImg
등 도구가 있어 YOLO
모형 개발에 필요한 라벨 생성작업에 도움을 줄 듯 싶다.
이미지에서 객체가 위치한 곳을 제대로 탐지하는지 먼저 살펴보자. 이를 위해서 대상 이미지를 magick
팩키지로 살펴보자.
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)