Reputation: 73
function() {
img1<-readImage("image.jpg")
img2<-img1+0.2
img1.b<-sum(img1[,,1:3])
img1.max<-length(img1[,,1:3])
diff1<-img1.b/img1.max
toincr<-increment(diff1)
img4<-img1
img4[,,1:3]<-img1[,,1:3]+toincr
img2.b<-sum(img2[,,1:3])
img2.max<-length(img2[,,1:3])
diff2<-img2.b/img2.max
toincr<-increment(diff2)
img3<-img2
img3[,,1:3]<-img2[,,1:3]+toincr
if(length(img3)==length(img4))
{
paste(100*sum(img3==img4)/length(img3),"%")
}
}
function(diff)
{
brightness<-0.25
incr<-brightness-diff
return(incr)
}
i have written above test function which read an image then create a copy and brighten that copy image.then i am adjusting the brightness of both the image to make them equally brighten with value 0.25 i.e. image img3 and img4.when i an comparing these two images using then its showing result as 0% but expected result is 100%.how should i modify the program??
Upvotes: 3
Views: 5069
Reputation: 8691
here with png
library
require(png)
img1<-readPNG("apple1.png")
img2<-readPNG("apple2.png")
if(length(img1)==length(img2)){ # check same pixel number
paste(100*sum(img1==img2)/length(img1),"%")
}
#[1] "32.098125 %"
It compare the 2 arrays to give you a BOOLEAN array of matches. The sum() of this gives you the number of matching pixels.Divide by total pixels (length() of array) to give you the matching factor (* 100 for percent)
OK, so answer edited following the comments!
Firstly, a caveat. The fields of image comparison and change detection are extremely complicated and a lot of commercial work has gone into them, you may be better off using a commercial package rather than re-inventing the wheel.
There is a good paper on intruder detection algorithms here:http://ijcnis.org/index.php/ijcnis/article/viewFile/88/87
However, the question is about R and it deals with useful concepts, so here is an (admittedly simplistic) answer:
When you are looking a sequential frames, you need to remember that at normal resolutions, tiny changes in light and exposure settings will make your images completely different for the purposes of basic arithmetical computation. You also need to be aware that a tiny movement in camera due to vibration or whatever (e.g. ~ 1/10000 of a degree for a 15 degree angle of view camera at 400x400) can misalign your pixels so that they CANNOT be compared even with brightness adjusting algorithms)
So to make this work, you need to do 2 things:
1) de-resolve the image (i.e. aggregate the pixels up to less blocks)
2) bucket the brightness score so that small changes in values as per normal shift do not give you false signals.
Try this:
For example, with 2 sample images:
Empty Room
Intruder
require(png)
img.reference<-readPNG("room-empty.png") # empty room as reference
img.empty<-readPNG("room-empty.png") # empty room copy
img.person<-readPNG("room-with-person.png") # room with person in it
# function to de-resolve image into levels (n=granularity)
# and divide the image up into blocks (n=result.length)
chunkImage<-function(image,granularity=10,result.length=100){
img.1D<-(image[,,1]+image[,,2]+image[,,1])/3
pix.n<-length(img.1D)
groups<-rep(1:result.length,each=ceiling(pix.n/result.length))[1:pix.n]
imgmap.new<-aggregate(as.vector(img.1D),list(newpix=groups),mean)
return(as.numeric(cut(imgmap.new$x,c(0:granularity)/granularity)))
}
# this returns an array (of reduced granularity) which describes each image in simpler terms
# you can think of it as a de-resolution or grouping function
chunkImage(img.reference)
#[1] 4 4 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 6 6 7 7 7 7 6 5 5 5 6 6 5 5 5 5
#[52] 5 5 5 5 5 5 5 5 5 4 4 4 5 4 4 3 3 3 3 3 3 4 5 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4
# so to compare an empty room against reference
sum(chunkImage(img.empty)!=chunkImage(img.reference))
#[1] 0
# Score 0 so probably nothing to worry about
# now to compare with the image containing the person
sum(chunkImage(img.person)!=chunkImage(img.reference))
#[1] 14
# score 14 may indicate a person
You will have to tinker with the resolution & granularity depending on the specifics of your site & environment.
PS: here are visual representations of the de-resolved images, to show you how they can visually be seen as different;
m.p<-matrix(chunkImage(img.person),ncol=10)/10
m.e<-matrix(chunkImage(img.empty),ncol=10)/10
m.p.big<-matrix(sapply(apply(m.p,1,function(x)rep(x,40)),function(x)rep(x,40)),ncol=400,byrow=T)
m.e.big<-matrix(sapply(apply(m.e,1,function(x)rep(x,40)),function(x)rep(x,40)),ncol=400,byrow=T)
m.alpha<-matrix(rep(1,160000),ncol=400)
length(m.e.big)
writePNG(array(c(rep(m.p.big,3),m.alpha),dim=c(400,400,4)),"person-deresolved.png")
writePNG(array(c(rep(m.e.big,3),m.alpha),dim=c(400,400,4)),"empty-deresolved.png")
Upvotes: 8