How to prevent imshow() from resizing the figure?

조회 수: 46(최근 30일)
Roger Breton
Roger Breton 2022년 1월 5일
답변: Roger Breton 2022년 1월 9일
I'm still at the stage of figuring out, to the best of my ability and according to the information I have access to, the interactions between a figure and commands like imshow(). I have a script where I first create an 800x1000 pixels figure but as soon as the imshow() executes, the figure is automatically resized, why? And how do I keep control over the figure (window) size? Here's my code :
f = figure('Position', [100 100 800 1000], 'Name','Roger Breton');
% imread resizes the figure?
img=imread('Fleur_3x4.jpg');
I've been searching the document to no avail :(

채택된 답변

Roger Breton
Roger Breton 2022년 1월 9일
Here's the final code :
global img;
f = figure('color', 'w', 'MenuBar', 'none', 'Position', [500 500 800 600])
global ax;
ax = axes
img = imread('Fleur_3x4.jpg');
imshow(img);
TailleImg = size (img);
global ah;
ah = annotation(f, 'line','Units', 'Pixels', 'Position', [311 183 TailleImg(2) 0], 'Color','k','LineWidth',10);
hold on
set(f, 'Position', [10 10 800 600]);
set(f, 'Resize','off');
set(ax, 'Units', 'Pixels');
set(ax, 'OuterPosition', [1 1 800 600]);
set(ax, 'InnerPosition', [311 191 TailleImg(2) TailleImg(1)]);
set(ax, 'Position', [311 191 TailleImg(2) TailleImg(1)]);;
global Inner;
[Inner] = get(ax, 'InnerPosition');
set (gcf, 'WindowButtonMotionFcn', @mouseMove);
function mouseMove (object, eventdata)
global img;
global ah;
global ax;
global Inner;
CP = round(get (ax, 'CurrentPoint'));
x = CP(1,1)
y = CP(1,2)
IntX = cast(x, 'uint16')
IntY = cast(y, 'uint16')
if IntX < 1
ah.Color=[1, 1, 1];
xlabel(ax, ' ');
return;
end
if IntX > Inner(3)
ah.Color=[1, 1, 1];
xlabel(ax, ' ');
return;
end
if IntY < 1
ah.Color=[1, 1, 1];
xlabel(ax, ' ');
return;
end
if IntY > Inner(4)
ah.Color=[1, 1, 1];
xlabel(ax, ' ');
return;
end
RGB = img(IntY,IntX, :);
Lab = rgb2lab(RGB)
rouge = double(RGB(1,1,1))/ 255.00
vert = double(RGB(1,1,2))/ 255.00
bleu = double(RGB(1,1,3))/ 255.00
ah.Color=[rouge, vert, bleu];
Temp1 = ['(X,Y) = ', num2str(IntX), ', ', num2str(IntY)];
Temp2 = ['RGB = ', num2str(RGB(1,1,1)), ', ', num2str(RGB(1,1,2)), ' , ', num2str(RGB(1,1,3))];
Temp3 = ['Lab = ', num2str(Lab(1,1,1),4), ', ', num2str(Lab(1,1,2),4), ' , ', num2str(Lab(1,1,3),4)];
xlabel(ax, [{Temp1, Temp2, Temp3}]);
end
I'm sure there's plenty of room for lot's of optimizations but, at the stage I'm at, learning Matlab, I feel like putting my feet up. The code would deserve adequate documentation, I know... I still have a ton of work to do, like, this works with one 'single image' but it's a 'proof of concept' for me. At least, I know what to expect now and the results meet my initial goals.

추가 답변(2개)

Roger Breton
Roger Breton 2022년 1월 5일
Strictly speaking, I could always issue a set('Position', ....) using my original figure size vector, after executing the imshow() like so :
f = figure('Position', [100 100 800 1000], 'Name','Roger Breton');
h2 = imshow(img);
f.Position = [100 100 800 1000];
But, 1) that seems an overkill? And 2) the picture area is now drawn in proportion to the figure and appears larger.
Not ideal. I bet the solution is to turn the 'fit' option off or something like that...
  댓글 수: 2
Roger Breton
Roger Breton 2022년 1월 5일
Looks like my anwer is to learn about axes...
I'm still not clear on the relationship between axes, figure and images...

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2022년 1월 5일
h2 = imshow(img, 'InitialMagnification', 'fit')
will examine the axes size and will set the image to just fill the axes drawing area.
If you want control over your axes and figure, I recommend against using imshow().
imshow() first checks for a current axes, and then compares the axes position to the default axes position within the figure. If they are the same size, then imshow() deletes the axes and creates a new one -- destroying any properties of the axes. If I recall correctly, it does not do this if "hold" is on, though.
Also, if you pass XData and YData to imshow() then it fits the image into those coordinates, same as if you had used image() or imagesc() with the same XData and YData. I would need to review the code to see whether it still deletes the axes in that situation.
image() on the other hand, never deletes the current axes, and never resizes the current figure. It is more robust when you want control over sizes and axes properties.
  댓글 수: 11
Walter Roberson
Walter Roberson 2022년 1월 8일
https://www.mathworks.com/matlabcentral/answers/62653-convert-currentpoint-to-x-and-y-value#answer_74247 "The CurrentPoint property of the axes replies a 2x3 array, which defines the viewing line through a 3D scene."
when you num2str then you are converting the numbers to character vector, such as 184 decimal to '184' character vector, which is a 1x3 array of character.
When you use a character vector as a subscript, the content of the character vector is not analyzed as a potential representation of a number, so the characters '184' are not treated as numeric 184. Instead, in most cases, the character vector is converted to a vector of the underlying Unicode code points, so '184' would be converted to the numeric vector [49 56 52]. You would then be indexing with a pair of 1x3 vectors. When you index with a non-scalar, the output is the result of indexing with all combinations selected from each index. If the second numeric value had been (say) 73 then your num2str would create the 1x2 character vector '73' and as an index go for the underlying Unicode [55 51] . The indexing by '184','73' would then effectively be the same as indexing by ([49 56 52], [55 51]) which would give you a 3x2 result.

댓글을 달려면 로그인하십시오.

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by