Перейти к содержимому
Compvision.ru
anry

cvMatchTemplate

Recommended Posts

Mat t;

	IplImage iplimg = LogMag;

	CvPoint minloc, maxloc;

	double  minval, maxval;

	cvMinMaxLoc(&iplimg, &minval, &maxval, &minloc, &maxloc, 0);

	LogMag.convertTo(t,t.type(),10000/*(double)255/(maxval-minval),(double)(-minval)*255/(maxval-minval)*/);

	imwrite("polarToCart_Mag.png",t);

попробовал так, только что то начало проявляться.

т.е. тут получается что то типа нормализации яркости нужно для удобного просмотра, но нужно ли это для кросскорреляции непонятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Попробуйте так:

cv::normalize(src,dst,0,1,CV_MINMAX);

Там просто значения в минус уходят.

Логарифм нужен только для отображения картинки, в других преобразованиях он не участвует, хотя его часто используют, чтобы избежать вычислительных проблем с очень большими или очень малыми числами. После выполнения действий, конечно переводят все обратно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Mat t;

normalize(LogMag,t,0,1,CV_MINMAX);

так вообще черный экран выдает.

попробовал еще cv::equalizeHist, но работает только с CV_8UC1 похоже и все равно выдает результат не такой как надо.

а

cv::minMaxLoc(t, &minval, &maxval, &minloc, &maxloc, 0);

вообще отказывается почему то принимать cv::Mat

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

хотя вот вроде нашел

http://opencv.itseez.com/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html

теперь показывает как надо, осталось понять где в предыдущем коде ошибка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

normalize(LogMag,t,0,255,CV_MINMAX); тогда надо поставить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

еще картинка

1-s2.0-S0168169904001589-gr4ad.jpg

ну вобщем я попробовал делать фурье->логполар->потом находить пик, но такое ощущени ечто то не то, т.к. только при повороте долже быть свиг только по 1 оси, хотя может из-за того что перед этим фурье делается условия меняются.

может потому что картинки разного размера опять же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
normalize(LogMag,t,0,255,CV_MINMAX); тогда надо поставить.

не не помогает, там видимо в чем то другом дело.

и так тоже не помогло

Mat t;

	normalize(t, t, 0, 1, CV_MINMAX); 

	LogMag.convertTo(t,CV_8UC1,255);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

попробовал просто вырезать из изображения кусок ,по идее мы имеем просто сдвиг.

ну в итоге получил пик со сдвигом, но это неправильно, ибо логполар сдвиг отвечает за поворот и скейл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да и может можно прямо по фурье определить поворот?

1-s2.0-S1047320312000247-gr3.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

нашел http://www.cse.iitd.ac.in/~parag/projects/DIP/asign1/transrotfft.shtml

что если я возьму картинку вырежу из неё часть помещу эту часть в (0,0) остальное дополню нулями и потом сравню фурье преобразование от изначальной картинки и полученной? вмысле какая в них будет наглядная зависимость?

всё таки насчет поворота

оригинал

init.PNG

повернул на 34 градуса

rot_34.png

оригинал

fft.png

повернул на -34 градуса

fft_-34.png

предполагаю, что угол не равен из-за того, что повернутый прямоугольник смещен относительно центра изображения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

	Mat image1= imread("001_001.PNG",0);

	Mat image2= imread("001_002.PNG",0);

	int width = getOptimalDFTSize(max(image1.cols,image2.cols));

	int height = getOptimalDFTSize(max(image1.rows,image2.rows));

	Mat fft1(Size(width,height),CV_32F,Scalar(0));

	Mat fft2(Size(width,height),CV_32F,Scalar(0));


	copyMakeBorder(image1,fft1,0,height-image1.rows,0,width-image1.cols,BORDER_CONSTANT,Scalar::all(0));

	copyMakeBorder(image2,fft2,0,height-image2.rows,0,width-image2.cols,BORDER_CONSTANT,Scalar::all(0));

	/*image1.copyTo(fft1(Rect(0,0,image1.cols,image1.rows)));

	image2.copyTo(fft2(Rect(0,0,image2.cols,image2.rows)));*/


	dft(fft1,fft1,0,image1.rows);

	dft(fft2,fft2,0,image2.rows);

        mulSpectrums(fft1,fft2,fft1,0,true);

	idft(fft1,fft1);

	double maxVal;

	Point maxLoc;

	minMaxLoc(fft1,NULL,&maxVal,NULL,&maxLoc);

	int resX = (maxLoc.x<width/2) ? (maxLoc.x) : (maxLoc.x-width);

	int resY = (maxLoc.y<height/2) ? (maxLoc.y) : (maxLoc.y-height);

решил попробовать новый интерфейс. почему то падает на первом dft, закоменченныый вариант не падает, но выдает почему то 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

похоже так надо было

image1.convertTo(fft1(Rect(0,0,image1.cols,image1.rows)),CV_32F);

	image2.convertTo(fft2(Rect(0,0,image2.cols,image2.rows)),CV_32F);

только всё равно пик не выдает правильный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Наверное надо четверти переставить, чтобы нуль посередине был.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

решил подсунуть функцию которая считает корреляцию оптимизатору, т.е. на каждой итерации морфим и смотрим сколько выдала функция, как начальное приближение использовать просто простая корреляция без морфинга.

пока на матлабе.

смущает, то что результирующая матрица получается с комплексными числами

clc;

clear all;

close all;

im01 = imread('001_001.tif');

im02 = imread('001_002.tif');

im1= im01;

im2= im02;

%im1 = rgb2gray(im01);

%im2 = rgb2gray(im02);

F1 = fftshift(fft2(im1));%зачем мы четверти меняем местами?

F2 = fftshift(fft2(im2));

F = F1.*conj(F2);

F = F./abs(F);

mag = (ifft2(F)); % тут получается матрица комплексных чисел, это нормально? чтобы найти пик надо взять модуль?

%берем модуль

mag_m= abs(mag);

imshow(100*mag_m);% домножаем на 100, а то будет черный экран, кстати картинка получается шумная.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что с комплексными, это нормально.

Фаза будет phi=atan2(Re,Im);

Амплитуда будет mag=sqrt(Re^2+Im^2);

Часто работают с комплексными частями, и не заморачиваются с разложением на фазу и амплитуду.

Если мы применим одно и то-же преобразование к действительной и мнимой частям, это будет практически тоже самое, с точностью до множителя, что применить это преобразование к амплитуде, т.к. угол не меняется.

Четверти переставляют, для того чтобы нуль был посередине спектра.

Так удобнее работать, чем когда высокие частоты посередине, а низкие по углам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Часто работают с комплексными частями, и не заморачиваются с разложением на фазу и амплитуду.

Если мы применим одно и то-же преобразование к действительной и мнимой частям, это будет практически тоже самое, с точностью до множителя, что применить это преобразование к амплитуде, т.к. угол не меняется.

ну вот например мне надо найти максимум, mag комплексные же числа сами по себе не сравнимы, получается всё равно надо искать их модуль?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если максимум, то да, надо найти магнитуду.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну вроде набросал.

на изображениях которые частично перекрываются вроде работает, но я точно не проверял.

а вот на синтетическом примере когда берем и изменяем исходное изображение, а потом пытаемся восстановить искажения чтобы понять какая точность, что то не работает(выдаёт 1 0 0 0 1 0 0 0 1)

еще проблема, которая обнаружилась походу, это то что надо пересчитывать фурье и для первой статичной картинки,потому размер второй картинки(которая меняется) может изменится по ходу, хотя возможно можно не пересчитывать, а как то обрезать просто.

еще опять же вопрос как правильно прикрутить пирамиды к минимизатору, чтобы работало быстрее.

и как поставить ограничения на параметры не просто верхняя нижняя граница как какое либо условие уравнением.

main.m

global model;

global scene;

%загружаем изображения

scene = imread('001_001.tif');

%тестовое искажение формат m11 m12 m21 m22 m31 m32 потом добавим не изменяемые m13=0 m23=0 m33=1

H= [0.95 -0.05 0.0000 1.0000 -0.0000 -0.0000];% протестируем с известным искажением это позволит определить точность

model=warp_im(scene,H);

%m11 m12 m21 m22 m31 m32

init_sol= [1 0 0 1 0 0]; %начальное приближение и есть само изображение

%надо еще подумать над настройкой парамтеров

opts= optimset('Algorithm','interior-point','MaxFunEvals',5000,'MaxIter',5000,'TolFun',1e-6,'TolX',1e-10);

problem= createOptimProblem('fmincon','objective','compute_NCC','x0',init_sol,'options',opts);

gs= GlobalSearch;

[x,f]= run(gs,problem)

param=x;

compute_NCC.m

function peak = compute_NCC(param)

global scene;

global model;

img= warp_im(model,param);

%возвращает изображения дополненные нулями

sz1= size(scene); % y x размеры

sz2= size(img);

sz= abs(sz2-sz1);

pad_im1=scene;pad_im2=img;

if(sz1(1)>sz2(1))%y

pad_im2= padarray(img,[sz(1),0],'post');

else

pad_im1= padarray(scene,[sz(1),0],'post');

end;

if(sz1(2)>sz2(2))%x

pad_im2= padarray(pad_im2,[0,sz(2)],'post');

else

pad_im1= padarray(pad_im1,[0,sz(2)],'post');

end;

FFT1 = fftshift(fft2(pad_im1));

FFT2 = fftshift(fft2(pad_im2));

FFT = FFT1.*conj(FFT2);

FFT = FFT./abs(FFT);

mag = (ifft2(FFT));

peak= -abs(max(max(mag))) % минус потому что минимизируем

warp_im.m

function out = warp_im(img,param)

%преобразуем к матрице гомографии 3х3 добавляя неизменяемые элементы

param=[param(1:2),0,param(3:4),0,param(5:6),1]

H=reshape(param,3,3)'

tform = maketform('projective',H');

out= imtransform(img,tform);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А что это должно быть ? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

если вы про алгоритм, то

фиксируем первое изображение, второе на каждом шаге варпаем параметрами которые приходят из минимизатора, как функцию цены используем фазовую корреляцию.

причем еще проверил например одно изображения большого размера и такие же маленького.

в первом случае выдало опять [1 0 0 1 0 0], во втором [0.9998 -0.0002 0 1 0 0]

всё таки что то неправильно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Очень напоминает то, что в TILT делается (может отсюда кусков натащить?):

http://www.compvision.ru/forum/index.php?showtopic=967

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я не очень понял, что там используется какой то branching ветвление чего?т.е. оптимизатора я там не нашел, они там работают с матрицами вроде как,

поворачивают так, чтобы ранг матрицы стал меньше(? минимизации ранга матрицы(?) или как звучит задача?)

и как поставить задачу для моего случая непонятно, т.е. откуда я возьму матрицу(с переменными(?)) у которой я буду потом каким либо способом минимизировать ранг, чтобы найти эти переменные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я имел в виду, что они применяют некоторое преобразование к матрице

и минимизируют некоторую метрику при помощи изменения параметров преобразования.

В том алгоритме вычисляется матрица с размерностью равному количеству подбираемых параметров. Ячейки этой таблицы заполняются вариантами изображения к которым применено преобразование с этими параметрами (изменяющимися с достаточно большим шагом). Затем смотрим, какое из этих изображений имеет наиболее оптимальную метрику, так получаем начальные приближения параметров. После этого, при помощи локальной оптимизации уточняем решение.

Преобразования, как я понимаю у Вас примерно те же, а метрика будет своя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

на самом деле хотелось бы даже понять, прав ли я хотя бы концептуально.

а то может быть такую cost function "метрику" как пик корреляции по каким либо причинам и нельзя использовать?

или проблема может быть в том, что пики сравнимы только между двумя изображениями, вот между двумя разными парами нет?

идею я взял на самом деле из KCreg только там другая cost function и используют fminsearch.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В том алгоритме вычисляется матрица с размерностью равному количеству подбираемых параметров. Ячейки этой таблицы заполняются вариантами изображения с этими параметрами (изменяющимися с достаточно большим шагом). Затем смотрим, какое из этих изображений имеет наиболее оптимальную метрику, так получаем начальные приближения параметров. После этого, при помощи локальной оптимизации уточняем решение.

ну пирамиды я еще не прикручивал, а так как раз и получается, что я 1 изображение изменяю и получаю отклик в виде пика корреляции и в итоге выбираю лучший вариант, только я не перебираю всё с каким то шагом, а загоняю всё это в минимизатор, а как он это делает я не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×