聰明不如鈍筆
총명불여둔필
assignment KindeR

R에서 깔끔하게 레고 모자이크 만들기(feat. brickr)

레고만 있으면 못 만드는 게 없습니다.

 

거꾸로 그래서 무엇이든 레고로 만들고 싶다는 생각을 하는 분들도 적지 않습니다.

 

예를 들어 자기 사진을 레고로 만든 사람이 있습니다.

 

자기 사진을 레고로 만들 수 있다는 건 세상 모든 사진을 레고로 바꿀 수 있다는 뜻.

 

실제로 맨 위 사진에 나오는 '마블 스튜디오 아이언맨 31199'는 제법 인기 있는 레고 상품이기도 합니다.

 

R에도 이 아이언맨 상품처럼 '레고 모자이크'를 만들 수 있도록 도와주는 패키지가 있습니다.

 

제목을 통해 확인하실 수 있는 것처럼 바로 brickr 패키지입니다.

 

이번 포스트에서는 brickr 패키지를 활용해 실제로 레고 모자이크를 만드는 작업을 진행해 보겠습니다.


제일 먼저 할 일은 늘 그렇듯 tidyverse 패키지 (설치하고) 불러오기.

#install.packages('tidyverse')
library('tidyverse')
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.4     v dplyr   1.0.7
## v tidyr   1.1.4     v stringr 1.4.0
## v readr   2.0.2     v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

이어서 당연히 brickr 패키지도 (설치하고) 불러와야 합니다.

#install.packages('brickr')
library('brickr')

레고 모자이크로 만들 사진도 필요합니다.

 

이번 포스트에서는 제 메이저리그 응원팀 보스턴 로고를 레고 모자이크로 바꿔보겠습니다.

 

이 포스트와 똑같은 작업을 진행하고 싶으신 분은 그냥 마우스 오른쪽 버튼을 눌러서 파일을 저장하시면 됩니다.

 

이 파일은 JPEG이라는 이미지 파일 형식입니다. 

 

R에서 JPEG 형식을 불러오려면 jpeg 패키지가 필요합니다. 

 

이 패키지를 R를 설치할 때 따라오기 때문에 그냥 library() 함수로 불러오기만 하셔도 됩니다.

library('jpeg')

JPEG 파일을 불러오는 함수는 readJPEG()입니다. 

 

이 파일을 불러와서 image라는 객체(변수)에 넣어놓도록 하겠습니다.

 

file.choose() 함수를 쓰면 파일 선택창을 통해 파일을 불러올 수 있습니다.

readJPEG(file.choose()) -> image

객체 내용을 엿볼 수 있는 glimpse() 함수를 써보면 672 × 672 × 3 형태라는 걸 알 수 있습니다.

image %>% 
  glimpse()
##  num [1:672, 1:672, 1:3] 0.102 0.102 0.102 0.102 0.102 ...

이 이미지 사이즈가 가로 세로 모두 672픽셀이라 이런 형태인 겁니다.

 

이미지를 레고 모자이크로 만드는 함수는 image_to_mosaic()입니다.

 

이 함수에는 image_size 옵션을 넣어줘야 합니다. 그냥 결과만 확인하는 차원에서 1을 넣어보겠습니다.

image %>% 
  image_to_mosaic(img_size = 1) 
## $Img_scaled
## # A tibble: 1 x 7
##       y     x     R     G     B bg_transparent color  
##   <dbl> <dbl> <dbl> <dbl> <dbl> <lgl>          <chr>  
## 1     1     2 0.336 0.254 0.356 FALSE          #56415B
## 
## $dims
## [1] 1 1
## 
## $Img_lego
## # A tibble: 1 x 10
##       y     x     R     G     B color   Lego_name       Lego_color Level piece_type
##   <dbl> <dbl> <dbl> <dbl> <dbl> <chr>   <chr>           <chr>      <dbl> <chr>     
## 1     1     2  0.35  0.25  0.35 #56415B Dark stone grey #646464        1 p         
## 
## $brickr_object
## [1] "mosaic"
## 
## $Img_bricks
## # A tibble: 1 x 13
##   Level mid_level piece_type brick_type       brick_name   Lego_color Lego_name 
##   <dbl>     <dbl> <chr>      <chr>            <chr>        <chr>      <chr>     
## 1     1         0 p          x1y1_offx0_offy0 brick_x2_y1~ #646464    Dark ston~
## # ... with 6 more variables: brick_width <dbl>, brick_height <dbl>, xmin <dbl>,
## #   xmax <dbl>, ymin <dbl>, ymax <dbl>
## 
## $ID_bricks
##   Level mid_level piece_type x y       Lego_name Lego_color       brick_type
## 1     1         0          p 2 1 Dark stone grey    #646464 x1y1_offx0_offy0
##          brick_name brick_area brick_height brick_width
## 1 brick_x2_y1_1_0_p          1            1           1
## 
## $pieces
## # A tibble: 1 x 5
##   Brick_size Piece Lego_name       Lego_color     n
##   <chr>      <chr> <chr>           <chr>      <int>
## 1 1 x 1      p     Dark stone grey #646464        1
## 
## $use_bricks
## [1] "4x2" "2x2" "4x1" "3x1" "2x1" "1x1"

그러면 이런 저런 블록을 써서 모자이크를 만든다는 정보를 담고 있다는 사실을 알 수 있습니다.

 

레고 모자이크를 실물로 구현하고 싶으시면 저 블럭을 똑같이 사면 되는 겁니다.

 

이 결과에 build_mosaic() 함수를 적용하면 실제로 모자이크가 등장합니다. 이렇게 말입니다.

image %>% 
  image_to_mosaic(img_size = 18) %>% 
  build_mosaic()

이 그림을 보면 image_size가 무슨 뜻인지 알 수 있습니다.

 

image_size에 18을 넣었더니 가로와 세로가 모두 18칸인 이미지가 나왔습니다.

 

아직은 이미지가 너무 레고스러우니까(?) 점점 숫자를 키워보도록 하겠습니다.

image %>% 
  image_to_mosaic(img_size = 36) %>% 
  build_mosaic()

image %>% 
  image_to_mosaic(img_size = 72) %>% 
  build_mosaic()

image %>% 
  image_to_mosaic(img_size = 144) %>% 
  build_mosaic()

각자 원하는 정밀도(?)에 따라 알맞은 숫자를 넣으시면 되겠죠?

 

이번에는 에드바르 뭉크(1863~1944)가 그린 '절규'(아래 그림)를 한 번 바꿔보겠습니다.

 

이 그림은 PNG 파일 형식이라 readJPEG() 함수 대신 readPNG() 함수를 써야 합니다.

 

readPNG() 함수는 (당연히) png 패키지에 들어 있습니다. 이번에는 패키지를 불러오는 대신 '::' 기호를 써보겠습니다.

 

이 기호는 특정한 패키지에 있는 함수를 불러오라는 기능을 합니다.

 

그래서 따로 library() 함수로 패키지를 불러오지 않아도 해당 함수를 사용할 수 있게 해줍니다.

 

png::readPNG(file.choose()) %>%
  image_to_mosaic(img_size = 72,
                  brightness = 1.25) %>%
  build_mosaic()

원래 레고를 좋아하시지 않는 분이라면 '이런 패키지가 무슨 소용이람?'하고 생각하실지도 모릅니다.

 

그래도 혹시 또 압니까? 이 패키지 덕분에 사는 재미가 하나 늘어날지도 모르는 일인데 말입니다.

 

그럼 모두들 Happy Charting -_-)/

 

댓글,

KindeR | 카테고리 다른 글 더 보기