Load the required R packages. EBImage handles image data, RSNNS contains an RBF function
source("http://bioconductor.org/biocLite.R")
biocLite("EBImage")
## package 'EBImage' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\baris0074\AppData\Local\Temp\RtmpIXrMUQ\downloaded_packages
library("EBImage")
library(RSNNS)
Load the image to reconstruct
# 150x100 brown sheep
filename = "C:/Users/baris0074/Desktop/CS 545/brown_sheep.jpg"
Define image data for the original image. This must be done before any functions are defined since they all reference the length and height of the image.
# display original image
# raster method displays image in RStudio
# browser method (default) displays image in browser
image = readImage(filename)
# imageData() gives pixel values of the image in the form:
# imageData = [R,G,B] where R,G,B represent a matrix of normalized
# pixel values for each color pane
originalImage = imageData(image)
Determine the dimensions of the image
length = dim(image)[1]
height = dim(image)[2]
size = length*height
Artificially damage an image by adding “noise”
createNoiseImage = function(imageData,noiseLevel){
# data from original image
imageData = imageData(imageData)
# make empty image
noiseImage = array(dim=c(length,height,3))
# create "noisy" image
for(i in 1:height){
# a random number in (-noiseLevel,noiseLevel) will give pixels
# noise of < (100*noiseLevel)%
noise = runif(length, min=-noiseLevel, max=noiseLevel)
noiseImage[,i,1] = imageData[,i,1] + noise
noiseImage[,i,2] = imageData[,i,2] + noise
noiseImage[,i,3] = imageData[,i,3] + noise
}
damagedImage = rgbImage(noiseImage[,,1],noiseImage[,,2],noiseImage[,,3])
display(damagedImage)
return(imageData(damagedImage))
}
Artificially damage images by removing random pixels
createMissingPixels = function(imageData,numPixels){
# make empty image
holesImage = array(dim=c(length,height,3))
# create "full of holes" image
for(i in 1:length){
for(j in 1:height){
#
# if a random number in (0,1) is less than numPixels
# then (100*numPixels)% of pixels will be blacked out
if(runif(1) < numPixels){holesImage[i,j,1] = 0;
holesImage[i,j,2] = 0;
holesImage[i,j,3] = 0}
else{holesImage[i,j,1] = imageData[i,j,1];
holesImage[i,j,2] = imageData[i,j,2];
holesImage[i,j,3] = imageData[i,j,3]}
}
}
damagedImage = rgbImage(holesImage[,,1],holesImage[,,2],holesImage[,,3])
display(damagedImage)
return(imageData(damagedImage))
}
The RBF function takes a single row or column of the damaged image and applies a Radial Basis Function Network to approximate an output. The network can be optimized by adjusting the size of the hidden layer, the number of iterations, etc.
RBF = function(input,output){
# input is just an index
inputs = input
# outputs either row or column of image
outputs = output
# RBF network
model = rbf(inputs, outputs, size=10, maxit=1000,
initFuncParams=c(0, 1, 0, 0.01, 0.01),
learnFuncParams=c(1e-8, 0, 1e-8, 0, 1), linOut=TRUE)
# predictive model
return(fitted(model))
}
Perform interpolation of image, first length-wise then height-wise. Then overlay each interpolated image and average.
interpolate = function(imageData){
interpolatedImage_H = matrix(,ncol=length,nrow=height)
interpolatedImage_L = matrix(,ncol=length,nrow=height)
input_H = as.matrix(seq(1,height,1))
input_L = as.matrix(seq(1,length,1))
# interpolate in height direction
for(i in 1:length){
model = RBF(input_H,imageData[i,])
interpolatedImage_H[,i] = model
}
# interpolate in length direction
for(j in 1:height){
model = RBF(input_L,imageData[,j])
interpolatedImage_L[j,] = model
}
# put them together
# overlay images interpolated by length and by height
# and average
interpolatedImage = t((interpolatedImage_H + interpolatedImage_L)/2)
# return image data of interpolated image
return(interpolatedImage)
}
Use interpolate function on each color pane separately, then combine.
interpolateColors = function(imageData){
# Red
interpolateRed = interpolate(imageData[,,1])
# Green
interpolateGreen = interpolate(imageData[,,2])
# Blue
interpolateBlue = interpolate(imageData[,,3])
# Combine
interpolateImage = rgbImage(interpolateRed,interpolateGreen,interpolateBlue)
display(interpolateImage)
# return image data of interpolated image
return(imageData(interpolateImage))
}
Mean Square Error between original image and restored image to measure how well the interpolation performs.
MSE = function(originalImage,restoredImage){
sumRed = 0
sumGreen = 0
sumBlue = 0
for(i in 1:length){
for(j in 1:height){
sumRed = sumRed + (originalImage[i,j,1] - restoredImage[i,j,1])^2
sumGreen = sumGreen + (originalImage[i,j,2] - restoredImage[i,j,2])^2
sumBlue = sumBlue + (originalImage[i,j,3] - restoredImage[i,j,3])^2
}
}
MSERed = sumRed/size
MSEGreen = sumGreen/size
MSEBlue = sumBlue/size
avgMSE = (MSERed + MSEGreen + MSEBlue)/3
print('MSE of red pixels:')
print(MSERed)
print('------------------')
print('MSE of green pixels:')
print(MSEGreen)
print('--------------------')
print('MSE of blue pixels:')
print(MSEBlue)
print('-------------------')
print('average MSE:')
print(avgMSE)
}
Use RBF Networks on to restore each of the damaged images
## [1] "MSE of red pixels:"
## [1] 0.0208891
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.0208891
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.0208891
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.0208891
## [1] "MSE of red pixels:"
## [1] 0.005829795
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.006915936
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.003987197
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.005577643
## [1] "MSE of red pixels:"
## [1] 0.1844834
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.1844834
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.1844834
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.1844834
## [1] "MSE of red pixels:"
## [1] 0.01396887
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.01509207
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.01220049
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.01375381
## [1] "MSE of red pixels:"
## [1] 0.04842484
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.06622047
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.01701701
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.04388744
## [1] "MSE of red pixels:"
## [1] 0.01959483
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.02632066
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.008152145
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.01802255
## [1] "MSE of red pixels:"
## [1] 0.1432768
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.1953974
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.05011653
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.1295969
## [1] "MSE of red pixels:"
## [1] 0.1128522
## [1] "------------------"
## [1] "MSE of green pixels:"
## [1] 0.1537243
## [1] "--------------------"
## [1] "MSE of blue pixels:"
## [1] 0.04008002
## [1] "-------------------"
## [1] "average MSE:"
## [1] 0.1022188