EBImage
R 팩키지 1 2 3EBImage는 생물정보학에서 활발히 사용되는 의학 및 생명공학 영역에서 많이 다루어지는 영상 이미지처리를 위해서 활용되고 있고, magick, imager과 더불어 활용도가 높은 R 팩키지 중 하나로 판단된다.
영상 이미지가 데이터로 주어지면 가장 먼저 관심을 가지고 작업하게 되는 것은 다음과 같다.
EBImage
팩키지는 bioconductor 프로젝트의 일환으로 해당 생태계의 일환으로 bioconductor
에 맞춰 팩키지를 설치한다.
# 0. 환경설정 ----------------------------------------
# source("http://bioconductor.org/biocLite.R")
# biocLite()
# biocLite("EBImage")
library(EBImage)
# 1. 이미지 불러오기 ----------------------------------------
arch_101 <- readImage("fig/architecture_101.png")
rpi_logo <- readImage("fig/raspberrypi-logo.png")
# 2. 이미지 미리보기 및 정보 ----------------------------------------
EBImage::display(arch_101, method="raster")
# EBImage::display(arch_101, method="browser")
print(arch_101)
Image
colorMode : Color
storage.mode : double
dim : 592 859 4
frames.total : 4
frames.render: 1
imageData(object)[1:5,1:6,1]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0.4745098 0.4745098 0.4745098 0.4745098 0.4666667 0.4627451
[2,] 0.4745098 0.4745098 0.4745098 0.4745098 0.4666667 0.4627451
[3,] 0.4784314 0.4745098 0.4745098 0.4705882 0.4666667 0.4666667
[4,] 0.4862745 0.4745098 0.4666667 0.4627451 0.4627451 0.4666667
[5,] 0.4862745 0.4784314 0.4705882 0.4627451 0.4627451 0.4666667
hist(arch_101)
이미지를 불러오면 이미지에 4칙 연산과 승수연산을 통해 밝기와 명도를 조정하고 감마(\(\gamma\)) 값을 조절하여 이미지를 다양하게 표현할 수 있다.
# 3. 밝기 조정 ----------------------------------------
arch_101_plus <- arch_101 + 0.5
arch_101_minus <- arch_101 - 0.5
par(mfrow=c(1,3))
EBImage::display(arch_101_plus, method="raster")
text(x = 20, y = 20, label = "건축학 개론 밝기 0.5 증가", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론 원본", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101_minus, title="건축학 개론 밝기 0.5 감소", method="raster")
text(x = 20, y = 20, label = "건축학 개론 밝기 0.5 감소", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
# 4. 명도 조정 ----------------------------------------
arch_101_div <- arch_101 * 0.7
arch_101_mult <- arch_101 * 1.5
par(mfrow=c(1,3))
EBImage::display(arch_101_div, method="raster")
text(x = 20, y = 20, label = "건축학 개론 명도 70% ", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론 원본", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101_mult, title="건축학 개론 밝기 0.5 감소", method="raster")
text(x = 20, y = 20, label = "건축학 개론 명도 150% ", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
# 5. 감마 보정(Gamma Correction) ----------------------------------------
arch_101_gamma_growth <- arch_101 ^ 2
arch_101_gamma_dimin <- arch_101 ^ 0.5
par(mfrow=c(1,3))
EBImage::display(arch_101_gamma_growth, method="raster")
text(x = 20, y = 20, label = expression(paste("건축학 개론 감마: ", gamma ^2)), adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론 원본", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101_gamma_growth, title="건축학 개론 밝기 0.5 감소", method="raster")
text(x = 20, y = 20, label = expression(paste("건축학 개론 감마: ", gamma ^0.5)), adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
## 3.4. 밝기, 명도, 감마 ----------------------------------------
arch_101_pos <- ((arch_101 ^ 2) * 2) +0.5
arch_101_neg <- ((arch_101 ^ 0.5) * 0.5) - 0.1
EBImage::display(arch_101_pos, method="raster")
text(x = 20, y = 20, label = expression(paste("건축학 개론 감마: ", 2, gamma ^2, +0.5)), adj = c(0,1), col = "blue", cex = 2)
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론 원본", adj = c(0,1), col = "blue", cex = 2)
EBImage::display(arch_101_neg, title="건축학 개론 밝기 0.5 감소", method="raster")
text(x = 20, y = 20, label = expression(paste("건축학 개론 감마: ", 0.5, gamma ^0.5, -0.1)), adj = c(0,1), col = "blue", cex = 2)
대표적으로 이미지의 색상을 빼고 흑백으로만 다루고자 할 경우 활용한다.
# 4. 색상 관리(Color Management) ----------------------------------------
## 4.1. 흑백과 천연색상
par(mfrow=c(1,2))
colorMode(arch_101) <- Grayscale
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론: 흑백", adj = c(0,1), col = "blue", cex = 2)
colorMode(arch_101) <- Color
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론: 색상복원", adj = c(0,1), col = "blue", cex = 2)
## 4.2. RGB 색상결합
arch_101_ch <- channel(arch_101, 'rgb')
arch_101_r <- channel(arch_101_ch, "red")
arch_101_g <- channel(arch_101_ch, "green")
arch_101_b <- channel(arch_101_ch, "blue")
par(mfrow=c(1,4))
EBImage::display(arch_101_r, method="raster")
text(x = 20, y = 20, label = "RGB 중 빨강", adj = c(0,1), col = "red", cex = 2, family="NanumGothic")
EBImage::display(flip(arch_101_g), method="raster")
text(x = 20, y = 20, label = "RGB 중 녹색", adj = c(0,1), col = "green", cex = 2, family="NanumGothic")
EBImage::display(flop(arch_101_b), method="raster")
text(x = 20, y = 20, label = "RGB 중 파랑", adj = c(0,1), col = "blue", cex = 2, family="NanumGothic")
EBImage::display(rgbImage(arch_101_r, arch_101_g, arch_101_b), method="raster", all=TRUE)
text(x = 20, y = 20, label = "개별 RGB 결합", adj = c(0,1), col = "blue", cex = 2, family="NanumGothic")
## 4.3. RGB 색상결합 히스토그램
par(mfrow=c(2,2))
hist(arch_101)
hist(arch_101_g)
hist(arch_101_r)
hist(arch_101_b)
이미지의 밝기, 명도 등을 조정했다면, 경우에 따라서는 이미지 특정 영역을 뽑아내고, 회전, 이동을 시킬 수도 있다. 이미지를 좌우로 쭉 연결시키거나, 위아래로 순차적으로 쌓아 놓거나, 경우에 따라서는 이미지 내부에 이미지를 내포하는 것도 가능하다.
# 6. 잘라내기(Cropping) ----------------------------------------
suji <- arch_101[290:470, 170:550,]
han <- arch_101[130:290, 170:550,]
par(mfrow=c(1,3))
EBImage::display(han, method="raster")
text(x = 20, y = 20, label = "건축학 개론 감마: 한가인", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학 개론 원본", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(suji, method="raster")
text(x = 20, y = 20, label = "건축학 개론 감마: 수지", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
뒤집기, 좌우돌림, 크기조정, 이미지 회전를 통해 이미지를 변환시킬 수 있다.
# 6. 이미지 변환 ----------------------------------------
## ㄴ 6.1. 뒤집기, 좌우돌림, 크기조정, 이미지 회전 ------
arch_101_flip <- flip(arch_101)
arch_101_flop <- flop(arch_101)
arch_101_resize <- resize(arch_101, w=40, h=60)
arch_101_rotate <- rotate(arch_101, 45, bg.col = "white")
par(mfrow=c(1,4))
EBImage::display(arch_101_flip, method="raster")
text(x = 20, y = 20, label = "뒤집기(flip)", adj = c(0,1), col = "blue", cex = 1.5, family="NanumGothic")
EBImage::display(arch_101_flop, method="raster")
text(x = 20, y = 20, label = "좌우바꿈(flop)", adj = c(0,1), col = "blue", cex = 1.5, family="NanumGothic")
EBImage::display(arch_101_resize, method="raster")
text(x = 20, y = 20, label = "크기조정(resize)", adj = c(0,0.5), col = "blue", cex = 1.5, family="NanumGothic")
EBImage::display(arch_101_rotate, method="raster", all=TRUE)
text(x = 20, y = 20, label = "이미지 회전", adj = c(0,1), col = "blue", cex = 1.5, family="NanumGothic")
이미지를 회전 혹은 이동시키고 동시에 회전과 이동을 순차적으로 적용할 수 있다.
## ㄴ 6.2. 공간변환(Spatial Transformation) ----------------------------------------
arch_101_rot <- rotate(arch_101, 45)
arch_101_trans <- translate(arch_101, c(100,200))
arch_101_rot_trans <- translate(rotate(arch_101,45),c(100,200))
par(mfrow=c(1,3))
EBImage::display(arch_101_rot, method="raster")
text(x = 20, y = 20, label = "건축학 개론: 45도 회전", adj = c(0,1), col = "orange", cex = 2)
EBImage::display(arch_101_trans, method="raster")
text(x = 20, y = 20, label = "건축학 개론: 우측 300픽셀, 아래 500픽셀 이동", adj = c(0,1), col = "orange", cex = 2)
EBImage::display(arch_101_rot_trans, title="건축학 개론 밝기 0.5 감소", method="raster")
text(x = 20, y = 20, label = "건축학 개론: 45도 회전과 이동병행 ", adj = c(0,1), col = "orange", cex = 2)
# 7. 이미지 결합(Combine) ----------------------------------------
## ㄴ 7.1. 순서대로 결합 -----
colorMode(rpi_logo) <- Color
rpi_logo <- resize(rpi_logo, w=dim(arch_101)[1], h=dim(arch_101)[2])
par(mfrow=c(1,2))
EBImage::display(Image(abind::abind(rpi_logo, arch_101, along=1), colormode=Color), method="raster")
EBImage::display(Image(abind::abind(rpi_logo, arch_101, along=2), colormode=Color), method="raster")
## ㄴ 7.2. 겹쳐서 결합 ----
arch_rpi <- rpi_logo + arch_101
par(mfrow=c(1,3))
display(rpi_logo/3 + arch_101, method="raster")
display(arch_rpi, method="raster")
display(rpi_logo + arch_101/3, method="raster")
## ㄴ 7.3. 이미지 텍스트 추가 -----
colorMode(arch_101) <- Color
display(arch_101, method="raster")
text(x = 20, y = 20, label = "한국 R Meetup", adj = c(0,0.5), col = "blue", cex = 1.5, family="NanumGothic")
## ㄴ 7.4. 로고 위치 반영 -----
colorMode(arch_101) <- Grayscale
colorMode(rpi_logo) <- Grayscale
arch_101 <- resize(arch_101, w=200, h=400)
rpi_logo <- resize(rpi_logo, w=200, h=400)
img_logo <- paintObjects(rpi_logo, toRGB(arch_101), col='green')
display(img_logo, method="raster", all=TRUE)
고역(高域) 필터(High-pass Filter)를 적용하여 사진속 객체의 엣지(Edge)를 탐지해서 배경과 사물을 구분하거나, 저역(低域) 필터(Low-pass Filter)를 적용하여 잡음 노이즈를 제거하거나 이미지를 부드럽게 한다.
# 10. 고역/저역 필터 ----------------------------------------
## 10.1. 저역 필터
fLow <- makeBrush(21, shape= 'disc', step=FALSE)^2
fLow <- fLow/sum(fLow)
arch_101_fLow <- filter2(arch_101, fLow)
## 10.2. 고역 필터
fHigh <- matrix(1, nc = 9, nr = 9)
fHigh[5, 5] <- -64
arch_101_fHigh <- filter2(arch_101, fHigh)
par(mfrow=c(1,3))
EBImage::display(arch_101_fLow, method="raster")
text(x = 20, y = 20, label = "저역필터(Low-pass Filter)", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101, method="raster")
text(x = 20, y = 20, label = "건축학개론 원본", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
EBImage::display(arch_101_fHigh, method="raster")
text(x = 20, y = 20, label = "고역필터(High-pass Filter)", adj = c(0,1), col = "blue", cex = 1.5, family="nanum")
이미지의 특정 영역을 세분화하여 bwlabel
을 통해 그림 속에 포함된 특정객체가 몇 개인지 갯수를 센다.
# 11. 이미지 세분화 ----------------------------------------
## 11.1 동전이미지 가져오기
coins <- readImage("fig/quarters_dimes_pennies.png")
## 11.2 흑백이미지
colorMode(coins) <- Grayscale
## 11.3. 임계값 설정
coins_otsu_th <- coins > otsu(coins, levels=2048)
coins_otsu_th <- opening(coins_otsu_th, makeBrush(5, shape='disc'))
coins_otsu_th <- fillHull(coins_otsu_th)
## 11.4. 동전갯수
coins_label <- bwlabel(coins_otsu_th)
# max(coins_label)
nbr_coins <- apply(coins_label, 3, max)
cat('동전갯수 [1,2,3]=', '[', nbr_coins[1], ']','[', nbr_coins[2], ']', '[', nbr_coins[3], ']', "\n")
동전갯수 [1,2,3]= [ 19 ] [ 33 ] [ 45 ]
## 11.5. 시각화
par(mfrow=c(1,2))
EBImage::display(coins, method="raster", all=TRUE)
EBImage::display(coins_otsu_th, method="raster", all=TRUE)
par(mfrow=c(1,3))
colorMode(coins) <- Color
EBImage::display(coins, method="raster")
text(x = 20, y = 20, label = "동전 원본 사진", adj = c(0,1), col = "orange", cex = 1.5, family="nanum")
colorMode(coins) <- Grayscale
EBImage::display(coins, method="raster", all=TRUE)
text(x = 20, y = 20, label = "동전 흑백 사진", adj = c(0,1), col = "orange", cex = 1.5, family="nanum")
EBImage::display(coins_otsu_th, method="raster", all=TRUE)
text(x = 20, y = 20, label = "동전 임계값 적용된 사진", adj = c(0,1), col = "orange", cex = 1.5, family="nanum")