Prev: sinsouidal pulse.
Next: Indeo5 compressor warning!
From: Andriy Nych on 17 May 2010 02:47 Hi all I need to select a rectangular area that should include some features on four images simultaneously. I want to be able to select rectangle on one of the images and adjust it on any of the others. In other words I need positions of four rectangles to be linked. IMRECT and IMROI does not allow to do that. Moreover, if I use the same callback for each rectangle, I can not distinguish which one triggered the callback: IMRECT and IMROI does not have handle property, like rectangle does. So far I've come to the code below (R2008a), which works the way I want but looks ugly to me. Does anyone have any suggestions how to make it more "beautiful"? Is it possible somehow to avoid using four different callbacks for each rectangle? Thanks function MultipleRectangleTest f0 = figure('color','w'); subplot(2,2,1); imshow('cameraman.tif'); [UD.rectangles.h1,UD.id.i1] = AddRectangle([0 0 100 100],@Rect1CallBack); subplot(2,2,2); imshow('cameraman.tif'); [UD.rectangles.h2,UD.id.i2] = AddRectangle([0 0 100 100],@Rect2CallBack); subplot(2,2,3); imshow('cameraman.tif'); [UD.rectangles.h3,UD.id.i3] = AddRectangle([0 0 100 100],@Rect3CallBack); subplot(2,2,4); imshow('cameraman.tif'); [UD.rectangles.h4,UD.id.i4] = AddRectangle([0 0 100 100],@Rect4CallBack); set(f0, 'UserData',UD); end function [r,id] = AddRectangle(pos,funHand) r = imrect(gca, pos); id = addNewPositionCallback(r,funHand); fcn = makeConstrainToRectFcn('imrect',get(gca,'XLim'),get(gca,'YLim')); setPositionConstraintFcn(r,fcn); end function Rect1CallBack(p) disp('Rect1CallBack fired'); UD=get(gcf,'UserData'); RFN=fieldnames(UD.rectangles); IFN=fieldnames(UD.id); for k=[2 3 4] % remove PositionCallbacks from imrect in order to avoid "callback avalanche" removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); setPosition(UD.rectangles.(RFN{k}),p); % restore PositionCallbacks to keep the functionality UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); end; % title(['Rect1 - ' mat2str(p,3)]); set(gcf, 'UserData',UD); end function Rect2CallBack(p) disp('Rect2CallBack fired'); UD=get(gcf,'UserData'); RFN=fieldnames(UD.rectangles); IFN=fieldnames(UD.id); for k=[1 3 4] % remove PositionCallbacks from imrect in order to avoid "callback avalanche" removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); % restore PositionCallbacks to keep the functionality setPosition(UD.rectangles.(RFN{k}),p); UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); end; % title(['Rect2 - ' mat2str(p,3)]); set(gcf, 'UserData',UD); end function Rect3CallBack(p) disp('Rect3CallBack fired'); UD=get(gcf,'UserData'); RFN=fieldnames(UD.rectangles); IFN=fieldnames(UD.id); for k=[1 2 4] % remove PositionCallbacks from imrect in order to avoid "callback avalanche" removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); setPosition(UD.rectangles.(RFN{k}),p); % restore PositionCallbacks to keep the functionality UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); end; % title(['Rect3 - ' mat2str(p,3)]); set(gcf, 'UserData',UD); end function Rect4CallBack(p) disp('Rect4CallBack fired'); UD=get(gcf,'UserData'); RFN=fieldnames(UD.rectangles); IFN=fieldnames(UD.id); for k=[1 2 3] % remove PositionCallbacks from imrect in order to avoid "callback avalanche" removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); setPosition(UD.rectangles.(RFN{k}),p); % restore PositionCallbacks to keep the functionality UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); end; % title(['Rect4 - ' mat2str(p,3)]); set(gcf, 'UserData',UD); end
From: Corey Kelly on 29 May 2010 22:44 "Andriy Nych" <nych.andriy.nospam(a)gmail.com> wrote in message <hsqop7$svb$1(a)fred.mathworks.com>... > Hi all > I need to select a rectangular area that should include some features on four images simultaneously. I want to be able to select rectangle on one of the images and adjust it on any of the others. In other words I need positions of four rectangles to be linked. > IMRECT and IMROI does not allow to do that. Moreover, if I use the same callback for each rectangle, I can not distinguish which one triggered the callback: IMRECT and IMROI does not have handle property, like rectangle does. > So far I've come to the code below (R2008a), which works the way I want but looks ugly to me. > Does anyone have any suggestions how to make it more "beautiful"? > Is it possible somehow to avoid using four different callbacks for each rectangle? > > Thanks > > function MultipleRectangleTest > f0 = figure('color','w'); > subplot(2,2,1); imshow('cameraman.tif'); [UD.rectangles.h1,UD.id.i1] = AddRectangle([0 0 100 100],@Rect1CallBack); > subplot(2,2,2); imshow('cameraman.tif'); [UD.rectangles.h2,UD.id.i2] = AddRectangle([0 0 100 100],@Rect2CallBack); > subplot(2,2,3); imshow('cameraman.tif'); [UD.rectangles.h3,UD.id.i3] = AddRectangle([0 0 100 100],@Rect3CallBack); > subplot(2,2,4); imshow('cameraman.tif'); [UD.rectangles.h4,UD.id.i4] = AddRectangle([0 0 100 100],@Rect4CallBack); > set(f0, 'UserData',UD); > end > > function [r,id] = AddRectangle(pos,funHand) > r = imrect(gca, pos); > id = addNewPositionCallback(r,funHand); > fcn = makeConstrainToRectFcn('imrect',get(gca,'XLim'),get(gca,'YLim')); > setPositionConstraintFcn(r,fcn); > end > > function Rect1CallBack(p) > disp('Rect1CallBack fired'); > UD=get(gcf,'UserData'); > RFN=fieldnames(UD.rectangles); > IFN=fieldnames(UD.id); > for k=[2 3 4] > % remove PositionCallbacks from imrect in order to avoid "callback avalanche" > removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); > setPosition(UD.rectangles.(RFN{k}),p); > % restore PositionCallbacks to keep the functionality > UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); > end; > % title(['Rect1 - ' mat2str(p,3)]); > set(gcf, 'UserData',UD); > end > > function Rect2CallBack(p) > disp('Rect2CallBack fired'); > UD=get(gcf,'UserData'); > RFN=fieldnames(UD.rectangles); > IFN=fieldnames(UD.id); > for k=[1 3 4] > % remove PositionCallbacks from imrect in order to avoid "callback avalanche" > removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); > % restore PositionCallbacks to keep the functionality > setPosition(UD.rectangles.(RFN{k}),p); > UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); > end; > % title(['Rect2 - ' mat2str(p,3)]); > set(gcf, 'UserData',UD); > end > > function Rect3CallBack(p) > disp('Rect3CallBack fired'); > UD=get(gcf,'UserData'); > RFN=fieldnames(UD.rectangles); > IFN=fieldnames(UD.id); > for k=[1 2 4] > % remove PositionCallbacks from imrect in order to avoid "callback avalanche" > removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); > setPosition(UD.rectangles.(RFN{k}),p); > % restore PositionCallbacks to keep the functionality > UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); > end; > % title(['Rect3 - ' mat2str(p,3)]); > set(gcf, 'UserData',UD); > end > > function Rect4CallBack(p) > disp('Rect4CallBack fired'); > UD=get(gcf,'UserData'); > RFN=fieldnames(UD.rectangles); > IFN=fieldnames(UD.id); > for k=[1 2 3] > % remove PositionCallbacks from imrect in order to avoid "callback avalanche" > removeNewPositionCallback(UD.rectangles.(RFN{k}),UD.id.(IFN{k})); > setPosition(UD.rectangles.(RFN{k}),p); > % restore PositionCallbacks to keep the functionality > UD.id.(IFN{k}) = addNewPositionCallback(UD.rectangles.(RFN{k}),str2func(sprintf('Rect%dCallBack',k))); > end; > % title(['Rect4 - ' mat2str(p,3)]); > set(gcf, 'UserData',UD); > end I'm having a similar problem, except in my case I'm creating an arbitrary number of imellipse() objects, so I actually NEED a better solution. I haven't managed to get it working yet, but my best advice would be to pass the object number as an argument to the callback function, and use that number within the function to differentiate what happens. So in your case, I think you'd want something like: AddRectangle([0 0 100 100],{@RectCallBack,4}); And then change the callback function to a general one. If I make any headway with my problem, I'll let you know.
From: Walter Roberson on 30 May 2010 12:55 Corey Kelly wrote: > "Andriy Nych" <nych.andriy.nospam(a)gmail.com> wrote in message > <hsqop7$svb$1(a)fred.mathworks.com>... >> I need to select a rectangular area that should include some features >> on four images simultaneously. I want to be able to select rectangle >> on one of the images and adjust it on any of the others. In other >> words I need positions of four rectangles to be linked. >> IMRECT and IMROI does not allow to do that. Moreover, if I use the >> same callback for each rectangle, I can not distinguish which one >> triggered the callback: IMRECT and IMROI does not have handle >> property, like rectangle does. > I'm having a similar problem, except in my case I'm creating an > arbitrary number of imellipse() objects, so I actually NEED a better > solution. I haven't managed to get it working yet, but my best advice > would be to pass the object number as an argument to the callback > function, and use that number within the function to differentiate what > happens. I think that is the right general approach, but you have to be careful because it is not clear from the documentation that you are allowed to pass additional arguments to the callback directly. I would thus suggest using individual anonymous functions for K = 1 : 4 ... addNewPositionCallback(UD.rectangles.(RFN{k}),@(p) RectCallBack(p,K)); end
|
Pages: 1 Prev: sinsouidal pulse. Next: Indeo5 compressor warning! |