Mapping an image to a surface

7 views (last 30 days)
Michael
Michael on 28 Feb 2011
Hello,
I am trying to write a function that will keystone an image in a very specific way. Essentially, I need the image to be manipulated so that, if x and y were to represent the width and height (relative to the bottom) of the image, then the image would be mapped to the surface
z(x,y) = 0 with bounding regions
(bottom of image) < y < (top of image)
l(y) < x < r(y).
l(y) and r(y) are two different logarithmic functions (l(y) has a positive correlation while r(y) has a negtive). The image maintains its height but slowly shrinks in width the further up the image, making sort of a curve sided trapezoid.
I have attempted using the warp function, using the image boundaries as the x, y, z inputs, however this did not work. I have looked into also making a custom tform but it looks as though it can only translate pixels and not stretch or compress them. However, I am still relatively new to matlab and could be mistaken. All I need is just a general point in the right direction or some suggestions.
thanks in advance for any consideration or response,
mike

Answers (1)

Walter Roberson
Walter Roberson on 28 Feb 2011
As a first pass:
outIM = zeros(size(IM));
h = size(IM,1);
w = size(IM,2);
for Y = 1:h
L = round(l(Y));
R = round(r(Y));
p = round(interp1(linspace(L,R,w),1:w,1:w));
pv = ~isnan(p);
outIM(Y,p(pv),:) = IM(Y,L:R,:);
end
outIM = flipud(outIM);
This is far from ideal, as it pulls the values from individual complete pixels rather than some weighted color; likewise because it uses ragged edges rather than anti-aliasing the edges. Better yet would be a 2D interpolation.
I think it might be possible to vectorize the linspace and interp1 parts, but not the filling part, at least not with this quantized weighting.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!