Регистрация изображений на основе БПФ в питоне

Я нашел простой код на Python для регистрации изображений здесь

в простом случае перевода имеем:

def translation(im0, im1):
    """Return translation vector to register images."""
    shape = im0.shape
    f0 = fft2(im0)
    f1 = fft2(im1)
    ir = abs(ifft2((f0 * f1.conjugate()) / (abs(f0) * abs(f1))))
    t0, t1 = numpy.unravel_index(numpy.argmax(ir), shape)
    if t0 > shape[0] // 2:
        t0 -= shape[0]
    if t1 > shape[1] // 2:
        t1 -= shape[1]
    return [t0, t1]

но я не понимаю эту часть:

if t0 > shape[0] // 2:
    t0 -= shape[0]
if t1 > shape[1] // 2:
    t1 -= shape[1]

также иногда это дает неправильный сдвиг, поэтому кажется, что вывод t0, t1 зависит от некоторых случаев? Может быть, это потому, что у меня есть только перекрытие между изображениями?

ИЗМЕНИТЬ:

Также вот мои тесты с использованием других инструментов:

Для изображения льва из Википедии (чистый сдвиг)

http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/im1.png http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/im2.png

ImageJ дает (второй стек относительно первого стека) x= -20 y= -23 R= 0,8126828943265368 (хорошо)

PhaseCorrelate дает x = 20,19 y = 22,56 (это дает сдвиг первого изображения относительно второго изображения или что-то не так?)

нет окна Ганна x= 20,23 y= 22,43

код Python х = -22 у = - 14

сопоставление тестового шаблона для льва и головы льва, обрезанных в (1,1)

http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/im2.png 1.png" rel="nofollow noreferrer">http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/temp

def translation(im0, im1):
    """Return translation vector to register images."""
    shape = im0.shape
    f0 = fft2(im0)
    f1 = fft2(im1)
    ir = abs(ifft2((f0 * f1.conjugate()) / (abs(f0) * abs(f1))))
    t0, t1 = numpy.unravel_index(numpy.argmax(ir), shape)
    if t0 > shape[0] // 2:
        t0 -= shape[0]
    if t1 > shape[1] // 2:
        t1 -= shape[1]
    return [t0, t1]
1.png

ImageJ дает (второй стек относительно первого стека) x = 0 y = 1 R = 0,7905318337522524 (неудачный 1 пикс)

PhaseCorrelate дает x = -0,4 y = -2,45 (неточно и снова в противоположном направлении)

нет окна Ганна x= -0,88 y= -0,86

то же самое, но обрезано в (18,23)

http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/im2.png http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/temp_18_23.png

ImageJ дает (второй стек относительно первого стека) x = 17 y = 23 R = 0,8119669906973865 (неудачный 1 пикс)

PhaseCorrelate дает x = -18 y = -23 (хорошее, но противоположное направление)

нет окна Ханна x= -18 y= -22,98

тестовое изображение, разделенное на 2 изображения с % перекрытия (без шума, без искажений)

http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/1.png http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/2.png

(второй стек относительно первого стека) x= 744 y= 0 R= 0,99999999999999999

PhaseCorrelate дает x = -743,48 y = 0 (противоположное направление)

нет окна Ханна x= -743,49 y= 0

тест на реальных данных

http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/1_.PNG http://dl.dropbox.com/u/8841028/FFT%20template%20matching/test%20images/2_.PNG

ImageJ дает (второй стек относительно первого стека) x = 878 y = -3 R = 0,9667271264277764

PhaseCorrelate дает x = 34,47 y = -35,5 (неверно)

нет окна Ганна x= 146,32 y= 3,06 (неверно)

код opencv 2.4.3 (предварительная сборка), который я использовал.

#include "stdafx.h"
#include <opencv.hpp>

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    Mat im1= imread("1.PNG",0);
    Mat im2= imread("2.PNG",0);

    Mat r1;
    im1.convertTo(r1,CV_64F);
    Mat r2;
    im2.convertTo(r2,CV_64F);

    Point2d phaseShift;

    if(r1.cols!=r2.cols||r1.rows!=r2.rows)
    {
        int n_cols= max(r1.cols,r2.cols);
        int n_rows= max(r1.rows,r2.rows);

        Mat r1_pad;
        copyMakeBorder(r1,r1_pad,0,n_rows-r1.rows,0,n_cols-r1.cols, BORDER_CONSTANT, Scalar::all(0));
        Mat r2_pad;
        copyMakeBorder(r2,r2_pad,0,n_rows-r2.rows,0,n_cols-r2.cols, BORDER_CONSTANT, Scalar::all(0));

        Mat hann;
        createHanningWindow(hann, r1_pad.size(), CV_64F);
        phaseShift = phaseCorrelate(r1_pad, r2_pad, hann);
    }
    else
    {
        Mat hann;
        createHanningWindow(hann, r1.size(), CV_64F);
        phaseShift = phaseCorrelate(r1, r2, hann);
    }

    return 0;
}

person mrgloom    schedule 30.04.2013    source источник
comment
что ты делаешь в ir = abs(ifft2()f0 * f1.conjugate() /...) ? Я думаю, что если вы делаете f1.conjugate(), это потому, что есть связь между f0 и f1, а значит, есть связь между im0 и im1.   -  person Stephane Rolland    schedule 30.04.2013
comment
См. ссылку №2, чтобы узнать об отношениях значений сдвига и направлений сдвига изображения.   -  person cgohlke    schedule 30.04.2013
comment
Только что попробовал: кроме последнего теста imreg.translation правильно прописывает все изображения. В последнем тестовом примере перекрытие слишком мало, и if t1 > shape[1] // 2: t1 -= shape[1], по-видимому, не следует применять. В ссылке № 2 упоминается минимальное необходимое перекрытие 30%.   -  person cgohlke    schedule 30.04.2013
comment
Всем, кому интересно, код от @cgohlke стал основа модуля Python imreg_dft, который должен раскрывать функциональность в более полной форме.   -  person bubla    schedule 27.02.2015