不幸的是,我不能产生确切的期望结果,但通过一个相当生硬的算法,我得到了一些接近。一般算法是:
-
请参见图1中的第一个和第三个窗格。向两幅图像中添加相同的噪声可确保通过相位相关(如下)比较无特征区域(例如白色背景)。
-
用图1中的框分段填充一个由零组成的矩阵
这个矩阵的一个例子在图1的中间窗格中给出。此图像必须与图像1和图像2的尺寸相同。
-
在步骤2的矩阵和噪声图像2之间执行相位相关。
有几个旋钮,你可以在这里转,可以改善最终结果。见
Performing a phase correlation with fft in R
-
提取与最高相关值相关的x和y值“移位”
这些值表示步骤2中的矩阵应如何在x和y方向上移动,以便
比赛
噪声图像2。
-
这是通过在图像1中的行和列上循环来完成的。可以循环遍历每个索引或跳过几个索引。
-
创建一个x和y位移矩阵并绘制以观察图像1中的区域与图像2的比较。
注意,结果并不完全是你想要的,而是它的结束。基本上,红色区域表示图像1中的相应区域不必移动。黄色区域(在本例中)需要稍微向下移动,橙色区域需要稍微向下移动,白色区域需要向上移动。
同样,向图像1和2添加相同的噪声也是一个重要步骤。算法依赖于分离小的框区域(在示例代码中,我使用了50x50像素框)。当循环遍历图像1的行和列并隔离相应的框区域时,几个区域将包含没有特征的区域。这在相位相关中造成了问题,因为在具有相似无特征背景的所有区域中,盒装无特征区域将具有多个高相关值。有效地,添加噪声会在两幅图像中添加特征,以减少不明确的相位相关性。
此算法产生的结果与所需的结果不同的原因是,装箱区域不是以聪明的方式选择的——它们是在循环图像1的行和列时选择的。因此,根据您选择的框大小,某些框区域将具有与图像2相比转换不同的功能。
也许在yapws87提出的区域聚类算法之后,该算法能更好地工作
## read in the images
img1 <- readJPEG('./img1.jpg')
img2 <- readJPEG('./img2.jpg')
## grayscale the images
img1 <- (img1[,,1]+img1[,,2]+img1[,,3])/3
img2 <- (img2[,,1]+img2[,,2]+img2[,,3])/3
## rotate the images for more intuitive R plotting
img1 <- t(apply(img1,2,rev))
img2 <- t(apply(img2,2,rev))
## create some uniform noise
noise <- matrix(runif(n=nrow(img1)*ncol(img1)),nrow=nrow(img1),ncol=ncol(img1))*0.1
## add the SAME noise to both images
img1 <- noise+img1
img2 <- noise+img2
## remove the mean from both images (this may not be necessary)
img1 <- img1/mean(img1)
img2 <- img2/mean(img2)
## Take the conjugate of the fft of the second image
IMG2c <- Conj(fft(img2))
## define how to loop through the first image
row.step=50
col.step=50
## create a zero image (made with all 0s)
zero.img <- matrix(0,ncol=ncol(img1),nrow=nrow(img1))
## initialize some vectors to hold the x and y
## shifts that correspond to the highest phase correlation value
shift.x.vec=NULL
shift.y.vec=NULL
## keep track of how many iterations you go through
i.iters=1
## loop over the columns
i=1
while((i+col.step-1)<nrow(img1)) {
## keep track of how many iterations you go through
j.iters=1
## loop over the rows
j=1
while((j+col.step-1)<ncol(img1)) {
## define a current 'box' as the zero image
cbox1 <- zero.img
## then populate a small box with values from image 1
cbox1[i:(i+row.step-1),j:(j+col.step-1)] <- img1[i:(i+row.step-1),j:(j+col.step-1)]
## PERFORM THE PHASE CORRELATION
## go into the frequency domain
CBOX1 <- fft(cbox1)
## find a normalized value
norm <- abs(CBOX1 * IMG2c)
## perform the phase correlation and go back to the space domain
corr <- Re(fft((CBOX1 * IMG2c)/norm,inv=TRUE)/length(CBOX1))
## this rearranges the quadrants of the matrix see
## matlabs function fftshift
corr <- fftshift(corr)
## find the x and y index values associated with the
## highest correlation value.
shift <- which(corr==max(corr),arr.ind=TRUE)
shift.x <- shift[1]
shift.y <- shift[2]
## populate the x and y shift vectors
shift.x.vec <- c(shift.x.vec,shift.x)
shift.y.vec <- c(shift.y.vec,shift.y)
## THIS IS ADDITIONAL PLOTTING AND CAN BE IGNORED
if(i.iters==6 & j.iters==6) {
dev.new()
##jpeg('./example.jpeg',width=900,height=700)
split.screen(c(1,3))
screen(1)
image(1:nrow(img1),1:ncol(img1),img1,col=gray.colors(200),axes=FALSE,ylab="",xlab="",useRaster=TRUE,main='Noisy Image 1')
rect(j,i,(j+col.step-1),(i+row.step-1))
screen(2)
image(cbox1,col=gray.colors(200),axes=FALSE,useRaster=TRUE,main='Current Box')
screen(3)
image(img2,col=gray.colors(200),axes=FALSE,useRaster=TRUE,main='Noisy Image 2')
##dev.off()
}
j.iters=j.iters+1
j=j+row.step
}
i.iters=i.iters+1
i=i+col.step
}
## make a matrix of shifts values
## in this example, only the y shifts are interesting though
shift.x.mat <- matrix(shift.x.vec,ncol=j.iters-1,nrow=i.iters-1,byrow=TRUE)
shift.y.mat <- matrix(shift.y.vec,ncol=j.iters-1,nrow=i.iters-1,byrow=TRUE)
##jpeg('./final.jpeg',width=800,height=800)
image(shift.y.mat,axes=FALSE,useRaster=TRUE)
##dev.off()