Manipulating image data

Mahbubul Majumder, PhD
Nov 18, 2014

What is image data?

  • We used data to create image.

  • Some times image itself could be data

    • Magnetic Resonance Imaging (MRI)
    • digital pictures taken by a traffic camera
    • google earth or satellite imagery
  • Every image can be expressed as a two dimensional layout of colors

    • chopped into small (really tiny) rectangles
    • the color of each piece is recorded in a two dimensional matrix
    • this generates image data
    • videos can be considered as the time series of image data

Types of image

  • Vector image based on specific shapes like circle, rectangle, line and texts

    • uses mathematical equation or formula
    • can be scaled to any size without distortion
    • examples: SVG, pdf
    • usually data are visualized using these types of plots
  • Raster image based on pixels

    • uses an array of square or rectangular region of color
    • can't scale larger than some specific size
    • example JPEG, BMP, PNG
    • usually captured by digital camera or medical scans, not generated from data

Vector vs Raster image

  • Vector image can be scaled to any size
  • Raster image distorts when enlarged

Raster image

  • Array of colors

    • first two dimensions are locations
    • third dimension is color values
    • a fourth dimension often store transparency
  • Vector images are not always preferred

    • for big data, many shapes may be plotted
    • file size gets much bigger for large data
    • raster image can be used to solve it

plot of chunk unnamed-chunk-2

Bangladesh map

library(maps)
par(mar=rep(0, 4))
map(region="Bangladesh", col="black", fill=TRUE)

plot of chunk unnamed-chunk-3

Bangladesh flag

  • Bangladesh flag taken from wikipedia and saved as png file
library(png)
bdFlag <- readPNG("bangladesh-flag.png")
flagRaster <- as.raster(bdFlag)

library(grid)
grid.raster(flagRaster)

plot of chunk unnamed-chunk-4

Bangladesh flag with map overlaid

bdFlag <- readPNG("bangladesh-flag.png")
bdMap <- readPNG("bangladesh-map.png")

flagRaster <- as.raster(bdFlag)
mapRaster <- as.raster(bdMap)

grid.raster(flagRaster)
grid.raster(mapRaster)

plot of chunk unnamed-chunk-5

Raster image as array

  • Raster images are like arrays, we can subset like a matrix so the dimensions are same
dm <- dim(mapRaster)
flagRaster <- flagRaster[1:dm[1], 134:(dm[2] + 133)]

dim(flagRaster)
[1] 600 686
dim(mapRaster)
[1] 600 686
flagRaster[1:3,1:5]
     [,1]        [,2]        [,3]        [,4]        [,5]       
[1,] "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF"
[2,] "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF"
[3,] "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF" "#036A4EFF"

Manipulating the raster image

indx <- mapRaster =="#00000000"
flagRaster[indx] <- "transparent"

grid.raster(flagRaster)

plot of chunk unnamed-chunk-7

Digital postmortem

  • Virtual Autopsy, getting widely used
    • provides convenience and easy to re-examine the evidence
    • some features are not possible to get in traditional autopsy
    • 3D structures can be examined
    • even soft tissues can be segmented
    • generates huge amount of data

A full body MRI scan taken from Beautiful Visualization edited by Julie at el.

Case study: bullet holes

bulletHole <- readPNG("bullet-hole.png")
bulletHole <- as.raster(bulletHole)
grid.raster(bulletHole)

plot of chunk unnamed-chunk-8 Picture source:
https://www.demongraphics.co.uk/index.php?main_page=product_info&cPath=68&products_id=802

How many bullet holes are there?

holes <- bulletHole[270:470, 250:890]
grid.raster(holes)

plot of chunk unnamed-chunk-9

indx <- as.matrix(holes) > "#857C7DFF"
bholes <- holes
bholes[indx] <- "transparent"
grid.raster(bholes)

plot of chunk unnamed-chunk-10

High level view of the bullet holes

dm <- dim(holes)
cl <- matrix(1,ncol=dm[2], nrow=dm[1])
cl[indx] <- 0
x <- dm[1]:1
y <- 1:dm[2]
dat <- data.frame(expand.grid(x,y), z = as.vector(cl))
names(dat) <- c("x","y","z")

ggplot(dat, aes(y, x, z = z)) + stat_contour()

plot of chunk unnamed-chunk-11

Digital investigation

  • Often we have low resolution image to investigate

  • This bullet case study provides critical information that can be computed

    • relative distances of bullet holes, adjusting the units and camera angles
    • measurements would be quite accurate and automatic
    • the area of impact, not all holes are same

Clusters around bullet holes

d <- dist(cl)
hc <- hclust(d)

groups <- cutree(hc, k = 14)
plot(hc)
rect.hclust(hc,  border="red",k=14)

plot of chunk unnamed-chunk-15

Low level image processing

## source("http://bioconductor.org/biocLite.R")
## biocLite("EBImage")

library(EBImage)
f = system.file("images", "lena.png", package="EBImage")
lena = readImage(f)
grid.raster(lena)

plot of chunk unnamed-chunk-16

Viewing image data

print(lena)
Image 
  colorMode    : Grayscale 
  storage.mode : double 
  dim          : 512 512 
  frames.total : 1 
  frames.render: 1 

imageData(object)[1:5,1:6]
          [,1]      [,2]      [,3]      [,4]      [,5]      [,6]
[1,] 0.5372549 0.5372549 0.5372549 0.5372549 0.5372549 0.5490196
[2,] 0.5372549 0.5372549 0.5372549 0.5372549 0.5372549 0.5490196
[3,] 0.5372549 0.5372549 0.5372549 0.5372549 0.5372549 0.5137255
[4,] 0.5333333 0.5333333 0.5333333 0.5333333 0.5333333 0.5098039
[5,] 0.5411765 0.5411765 0.5411765 0.5411765 0.5411765 0.5333333

Algebraic operation with image

lena1 <- lena + 0.5
grid.raster(lena1)

plot of chunk unnamed-chunk-18

Increase in color means more light or white in color

lena2 <- lena * 3
grid.raster(lena2)

plot of chunk unnamed-chunk-19

Multiplication gets the difference multiplied which is causing the increased contrasts

More about EBImage package

  • More functions like rotate() , flip() , translate() and filter2()
    • details can be found in the package vignette
fhi = matrix(1, nc=3, nr=3)
fhi[2,2] = -8
lenafhi = filter2(lena, fhi)
grid.raster(lenafhi)

plot of chunk unnamed-chunk-20

Reading assignment and references