From: Tom Blanpied on
Hi,

I'd like to add a horizontal calibration bar to a displayed image. This isn't so hard to do if the image isn't resized via zooming, but I'd like to have the bar automatically recalculated (to e.g. 1/10th of the image width) and replotted when a user uses the magnifier to zoom in on a region.

Any thoughts?

Tom
From: Walter Roberson on
Tom Blanpied wrote:

> I'd like to add a horizontal calibration bar to a displayed image. This
> isn't so hard to do if the image isn't resized via zooming, but I'd like
> to have the bar automatically recalculated (to e.g. 1/10th of the image
> width) and replotted when a user uses the magnifier to zoom in on a region.

I suggest you see the zoom() documentation for information about post-zoom
callbacks.
From: David Young on
I'm sure there will be a way to display the bar as an object which is automatically resized, and that's probably the nicest way. However, a cheap and cheerful approach is just to make the scale bar part of the image data before you display it. Something along these lines:

img = imread('gantrycrane.png'); % example image

% Make a little scale bar image
scalelen = round(size(img,2)/5); % for example
scalewid = 10;
scalebar = zeros(scalewid, scalelen);
scalebar(3:scalewid-2, mod((1:scalelen), scalelen/5) > scalelen/10) = 256;

% overwrite part of the image with it
img(41:40+scalewid, scalelen+1:2*scalelen, :) = repmat(scalebar, [1 1 size(img,3)]);

imshow(img);
From: Tom Blanpied on
Walter Roberson <roberson(a)hushmail.com> wrote in message
> > I'd like to add a horizontal calibration bar to a displayed image. This
> > isn't so hard to do if the image isn't resized via zooming, but I'd like
> > to have the bar automatically recalculated (to e.g. 1/10th of the image
> > width) and replotted when a user uses the magnifier to zoom in on a region.
>
> I suggest you see the zoom() documentation for information about post-zoom
> callbacks.

Thanks Walter, that was the perfect lead.

FYI, I'm doing it the following way. A bit clunky, integer output, text not elegantly positioned, blah blah, but it works for me. (Our images are scaled in nm/px, btw.)

imshow('pout.tif');
pxscale=1;
newXLim=XLim;
newYLim=YLim;
scalevertpos=newYLim(1)+(newYLim(2)-newYLim(1))*.95;
xpts = [newXLim(1)+(newXLim(2)-newXLim(1))*.65, newXLim(1)+(newXLim(2)-newXLim(1))*.85];
ypts = [scalevertpos, scalevertpos];
len=xpts(2)-xpts(1);
dist=len*pxscale;

scaleline=imline(gca,xpts,ypts);

textx=xpts(1)+len/2.2;
texty=newYLim(1)+(newYLim(2)-newYLim(1))*.90;
textchars=[num2str(dist) ' px'];

scaletext=text(textx,texty,textchars,'Color','r');

h = zoom;
set(h,'ActionPostCallback',{@zoompostcallback,scaleline,scaletext,pxscale});
set(h,'Enable','on');
%
function zoompostcallback(obj,evd,lineh,texth,nmperpx)
newXLim = get(evd.Axes,'XLim');
newYLim = get(evd.Axes,'YLim');

vertpos=newYLim(1)+(newYLim(2)-newYLim(1))*.95;
xpts = [newXLim(1)+(newXLim(2)-newXLim(1))*.65, newXLim(1)+(newXLim(2)-newXLim(1))*.85];
ypts = [vertpos, vertpos];
len=xpts(2)-xpts(1);
dist=len*nmperpx;

setPosition(lineh,xpts,ypts);

textx=xpts(1)+len/2.2;
texty=newYLim(1)+(newYLim(2)-newYLim(1))*.90;
textchars=[num2str(dist) ' px'];

set(texth,'String',textchars);
set(texth,'Position',[textx texty]);