К сожалению, я не смог дать желаемого результата, но с помощью довольно тупого алгоритма я немного приблизился.Общий алгоритм:
Добавьте один и тот же случайный шум к каждому изображению.
См. Первую и третью панели на рисунке 1. ДобавлениеОдин и тот же шум на обоих изображениях позволяет сравнивать безликие области (например, белый фон) с помощью фазовой корреляции (ниже).
Заполните матрицу нулей в штучной упаковке подразделом из изображения 1
Пример этой матрицы приведен всредняя панель рисунка 1. Это изображение должно быть того же размера, что и изображение 1 и изображение 2.
Выполните фазовую корреляцию между матрицей из второго шага и зашумленным изображением 2. Здесь можно повернуть несколько ручек, которые могут улучшить конечный результат.См. Выполнение фазовой корреляции с FFT в R
Извлечение значений x и y 'сдвигов', связанных с наибольшим значением корреляции Эти значения показывают, как матрица из шага 2 должна быть смещена в x и yнаправления, так что лучше соответствует шумное изображение 2.
Отрегулируйте положение подраздела в штучной упаковке на шаге 3, чтобы все области на зашумленном изображении 1 были зациклены.Затем повторите шаги 3 и 4. Это делается путем зацикливания строк и столбцов на изображении 1. Вы можете зацикливать каждый индекс или пропускать несколько индексов.
Создайте матрицу из сдвигов x и y и построите график, чтобы увидеть, как области на изображении1 сравниваются с изображением 2.
Обратите внимание, что результат не совсем то, что вы ищете, а его близость.В основном красные области указывают, что соответствующие области на изображении 1 не должны быть сдвинуты.Желтые области (в данном случае) необходимо сместить немного вниз, оранжевые - больше, а белые - сместить вверх.
Опять же, добавление одинакового шума к изображениям 1 и 2 является важным шагом.Алгоритм зависит от выделения небольших областей в штучной упаковке (в примере кода я использовал блоки размером 50x50 пикселей).Когда вы просматриваете строки и столбцы изображения 1 и изолируете соответствующие области в штучной упаковке, некоторые области будут содержать области без элементов.Это создает проблемы в фазовой корреляции, поскольку область без элементов в штучной упаковке будет иметь множество высоких значений корреляции во всех областях, которые имеют одинаковый фон без элементов.Эффективно, добавление шума добавляет функции к обоим изображениям, чтобы уменьшить неоднозначные фазовые корреляции.
Причины, по которым этот алгоритм не дает того же результата, что и требуемый, заключаются в том, что области в штучной упаковке не выбраны умным способом - они выбираются при циклическом цикле по строкам и столбцам изображения 1.Следовательно, в зависимости от выбранного размера блока некоторые области в штучной упаковке будут иметь функции, которые переводятся по-разному по сравнению с изображением 2. Возможно, этот алгоритм будет работать лучше после алгоритма кластеризации областей, предложенного yapws87
Вот код R для получения этих результатов:
## 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()