我需要通过平移和旋转将两个图像转换为另一个图像。为此,我有这样的功能:
function [differences] = cost_function(transformation)
disp(transformation);
offset_x = transformation(1); % one of the images will be shifted by these many
offset_y = transformation(2); % pixels in either direction
angle = transformation(3); % and rotated by this much
% snip:
% * transform the second image
% * otsu treshold both
% * xor the results
% * count pixels that xored
然后我试着找到它的最小值!
best_transform = fminunc(@cost_function, [0 0 0]);
然而,求解器日志显示了一个非常大的问题:
1.0e-007 *
0.1490 0 0
1.0e-007 *
0 0.1490 0
1.0e-007 *
0 0 0.1490
0 0 1
0.0000 0 1.0000
0 0.0000 1.0000
0 0 1.0000
0 0 0.3333
0.0000 0 0.3333
求解器试图在每个维度上微微移动以找到最佳线条,但显然将图像移动0.1490像素确实没有太大作用,而将其移动0.1490弧度自然会做到。然而,我不知道0.1490实际来自哪里。
The documentation似乎没有给出建议。如何增加求解器的初始步骤?
答案 0 :(得分:2)
fminunc
旨在找到一个连续函数的最小值,正如您所指出的那样,这不是您的情况,因为更改像素数量会使图像移动无穷小的数量导致无结果。
您可以通过以愚弄 fminunc
的方式正确扩展目标函数来解决此问题,使其相信您的功能确实是连续的。要实现这一点,只需将偏移参数乘以一个相当大的标量,例如:
offset_x = transformation(1)*1000;
offset_y = transformation(2)*1000;
angle = transformation(3);
并用同一组标量划分你的最终解决方案,以获得移动的像素数。
通常,即使您的问题没有出现不连续性问题,在非线性优化问题中正确缩放变量也是至关重要的。
答案 1 :(得分:0)
我目前有这个kludge:
best_score_so_far = 9999999999;
best_so_far = [0 0 0];
optimset('display', 'off', 'MaxIter', 100);
for dist = 1:1:10
for angle = 0:2*pi/4/dist:2*pi
x = cos(angle)*dist;
y = sin(angle)*dist;
disp([dist angle x y]); %heh
[best, cost] = fminunc(@(angle)cost_function([x,y,angle]), 0);
if(cost < best_score_so_far)
best_score_so_far = cost;
best_so_far = best;
end
end
end
......但是它很丑陋,超级慢,而且是一个kludge。