Jump to content
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);

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

Mat t;

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

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

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

а

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

еще картинка

1-s2.0-S0168169904001589-gr4ad.jpg

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

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

Share this post


Link to post
Share on other sites
normalize(LogMag,t,0,255,CV_MINMAX); тогда надо поставить.

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

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

Mat t;

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

	LogMag.convertTo(t,CV_8UC1,255);

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

нашел 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

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

Share this post


Link to post
Share on other sites

	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.

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

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, а то будет черный экран, кстати картинка получается шумная.

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites
Часто работают с комплексными частями, и не заморачиваются с разложением на фазу и амплитуду.

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

а вот на синтетическом примере когда берем и изменяем исходное изображение, а потом пытаемся восстановить искажения чтобы понять какая точность, что то не работает(выдаёт 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);

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×