Is it possible to denormalize data created via the 'units', 'normalized' handles? /where does the handle get it's inputs from?

15 visualizaciones (últimos 30 días)
Hey!
As the question states. I assume this is possible providing I can retrieve the inputs from somewhere, the issue I have is I can't quite work out what inputs the function is using to begin with?
What I essentially have is a huge array of x y values normalized between 0-1, with 0, 0 being the bottom left corner of the figure window.
I know I can denormalize providing I know the original input parameters, which I think will likley be screen co-ordiantes/pixel values perhaps? What I need to know is exactly which values that 'units', 'normalized' flag is retrieving so I can reverse it. Does anyone know how I can retrieve them/work them out?
As such, if I just wanted to reverse the normalize function, I could do it like so.
%% Initially normalize...:
X = 1:5
X =
1 2 3 4 5
normalize(X)
ans =
-1.2649 -0.63246 0 0.63246 1.2649
%% Denormalize
mu = mean(X);
S = std(X);
Xnorm = (X - mu)/S
Xnorm =
-1.2649 -0.63246 0 0.63246 1.2649 % Note it's the same, so the normalize function must operate in this manner.
Xnorm*S + mu
ans =
1 2 3 4 5 % Retrieve the original values! Yay!
So, in my example above, what I need is what MATLAB is determining as the mu & S (pressumably via screensize in some way) in the 'units', 'normalized' call, so instead of values between 0 - 1, I can retrieve the original screen co-ordinates pre-processing.
Hopefully that makes some sense! Can it be done?
Thanks.
The line of code in question (incase it helps):
f = figure('WindowButtonUpFcn',@dropObject, 'units', 'normalized', 'WindowButtonMotionFcn',@moveObject);
I know there must be a function which exists somewhere for this, but I just can't quite place what it would be called!?
EDIT: Of note, this is more complex than simply getting the dimensions of the window. Scaling it between 0 - 1, then applying the equation above using the original figure window dimensions to retrieve it. That gets it in the right ball park, but no cigar...
  2 comentarios
Steven Lord
Steven Lord el 18 de Jul. de 2022
Can you describe your ultimate goal for this operation? What are you hoping to achieve by "denormalizing" the data? Perhaps there's a way to achieve that goal more simply.
Michael Vinsome
Michael Vinsome el 18 de Jul. de 2022
Evening Steven!
If you see my latest comment to Jan below, my ultimate goal in this case is too end up with two sets of points. one set which is normalized and one which is denormalised. If you can see the example function I posted below, that is essentially what we are aiming for here. So as you can see, it already produces the normalised set without any issue, what I now need is to take those values and use them to make the denormalised set, ideally as a seperate operation which can happen over in a seperate part of a larger backend.
Thanks for your help!

Iniciar sesión para comentar.

Respuesta aceptada

Michael Vinsome
Michael Vinsome el 19 de Jul. de 2022
Ok, so Jan was very close here (thanks Jan!), In my version of MATLAB (R2021b) however I couldn't quite get his code to run. Issues with uibutton among other things so it's not quite a copy & paste solve. Hopefully this will be for anyone who stumbles across it.
As you can see the finally equation successfully returns the original normalized element position, so it is clear that 'required location' is indeed to pixel positions. So to answer the question, yes, it is possible to retrieve the pixel locations which are generated using the normalized flag. :)
%Create a figure window and stick a panel in it using normalised
%co-ordinates.
figure_1 = figure('Units', 'normalized');
a = uipanel(figure_1,'Title','Denormalise me!','BackgroundColor','white');
a.Position = [0.35 0.30 0.30 0.35];
% Get the size of the figure in pixels:
old_units = get(figure_1, 'units');
set(figure_1, 'units', 'pixels');
FigPos_pixels = get(figure_1, 'Position');
set(figure_1, 'units', old_units);
% Calculate pixel position of button relative to figure:
required_location = get(a, 'Position') .* FigPos_pixels([3, 4, 3, 4]);
% Position relativ to the screen:
required_location + [FigPos_pixels(1:2), 0, 0];
% Renormalize to check, elementwise division returns the (original) normalized
% position!
renormalized = required_location ./ FigPos_pixels([3, 4, 3, 4]);

Más respuestas (1)

Jan
Jan el 18 de Jul. de 2022
About the reverse of the normalize() function: This is impossible. See:
X = 1:5;
normalize(X)
ans = 1×5
-1.2649 -0.6325 0 0.6325 1.2649
normalize(X + 1)
ans = 1×5
-1.2649 -0.6325 0 0.6325 1.2649
After the normalising some information is lost and you cannot recreate the original values.
The 'normalized' figure coordinates are something different. This scales the screen pixels of the figure to the range [0, 1] by a simple division.
"this is more complex than simply getting the dimensions of the window" - no, it is not more complex. Why do you think so?
The expression "normalized handles" is not meaningful. A handle is used to address a GUI object, which got its data from its inputs. Please explain more specifically, which data you want to extract from what.
  3 comentarios
Jan
Jan el 18 de Jul. de 2022
"You can see I have retrieved the same values in the example I posted above." - You have reversed the result of the normalize function, but you needed the original values to do so. But if you do have the original values, there is no need to reverse the function: simply use the original functions.
I assume that you are trapped.
If the units of a figure are set to 'normalized', the positions of the children of the figure (uicontrols, axes, annotations) are provided as values inside the range [0, 1]. Then e.g. [0.5, 0.5] is the center of the figure. If you set the units to 'pixels' instead, the values of the coordinates are multiplied by the number of pixels of the inner size of the window. This is trivial.
There is no "before it is normalized". The positions are stored in the format, which is set in the figure. Matlab does not normalize the positions, because the user is the one, who has to provide normalized positions to place the gui elements.
The graphics engine produces the screen position of the elements in pixels. This includes the pixels of e.g. a line relative to its axes, of the axes realtive to the figure and the figure relative to the screen.
To get the pixels coordinates of an object relative to the figure:
FigH = figure('Units', 'normalized');
ButtonH = uicontrol('Sytle', 'ToggleButton', 'Position', [0.5, 0.5, 0.4, 0.1]);
% Get the size of the figure in pixels:
bakUnits = get(FigH, 'units');
set(FigH, 'units', 'pixels');
FigPos_pixels = get(FigH, 'Position');
set(FigH, 'units', bakUnits);
% Calculate pixel position of button relative to figure:
ButtonPos_pixels = get(ButtonH, 'Position') .* FigPos_pixels([3, 4, 3, 4]);
% Position relativ to the screen:
ButtonPos_pixels + [FigPos_pixels(1:2), 0, 0]
" I have already tried that and did not get the desired results." - then your code contains a bug. If you post your code, we can find the bug. This is more efficient than speculating, that something more complex happens for normalized units. I guess boldly, you have confused the extent of the figure with the extent of the axes, which contains the observed object. But I promise: The normalized coordinates are very simple. No magic calculations are required.
Michael Vinsome
Michael Vinsome el 18 de Jul. de 2022
Hi Jan!
Of course, I won't post the full code for you because it's very long at this stage, this function below however I hope will show you what I am trying to achieve (see below):
You are correct, I am sligtly trapped as if I don't use normalised co-ordinates it ends up breaking various other parts of the function, as you can see from the one I've attached here.
I think you're right, it won't be magic, well all math is magic really but you know what I mean. I am just simply missing the inputs I need. I think you are probably right that my issue may well be that my calculation includes the entire figure window, when actually I only need the 'drawrable' area (The bit I can actually drag the figures around in) perhaps? If I could get hold of that perhaps it is then simply a case of using the calculation above to retrieve them, so as oppose to something being at 0.1123 0.3334 as an example, it is instead converted out of the normalized range so it is at 50 44 (figures invented for demonstration). Does that make it any clearer what I am trying to achieve?
Of note, ideally I do also need them to stay as normalized and then physically do this conversion aswell (So I have both sets), rather than just not convert them to begin with. Although if this is a huge amount of work, I could work around it to some extent.
Thanks!
function drag_drop
dragging = [];
orPos = [];
f = figure('WindowButtonUpFcn',@dropObject,'units','normalized','WindowButtonMotionFcn',@moveObject);
a = annotation('textbox','position',[0.2 0.2 0.2 0.2],'String','...','ButtonDownFcn',@dragObject);
a1 = axes('Position',[.7 .7 .2 .2], 'ButtonDownFcn', @dragObject)
function dragObject(hObject,eventdata)
dragging = hObject;
orPos = get(gcf,'CurrentPoint');
end
function dropObject(hObject,eventdata)
if ~isempty(dragging)
newPos = get(gcf,'CurrentPoint');
posDiff = newPos - orPos;
set(dragging,'Position',get(dragging,'Position') + [posDiff(1:2) 0 0]);
dragging = [];
end
end
function moveObject(hObject,eventdata)
if ~isempty(dragging)
newPos = get(gcf,'CurrentPoint');
posDiff = newPos - orPos;
orPos = newPos;
set(dragging,'Position',get(dragging,'Position') + [posDiff(1:2) 0 0]);
disp(orPos)
end
end
end

Iniciar sesión para comentar.

Categorías

Más información sobre Image Processing and Computer Vision en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by