How to prevent imshow() from resizing the figure?

조회 수: 91 (최근 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개)

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
Roger Breton
Roger Breton 2022년 1월 8일
I think I am having difficulty with 'data types'?
If I use this line of code, to index into the Image array :
RGB = img(143, 179, :)
I get exactly what I expect, a 1×1×3 uint8 array.
But if I used the same code as before :
PetitX = num2str(C(1,1)) % X = 179
PetitY = num2str(C(1,2)) % Y = 143
OR this :
PetitX = uint8(C(1,1)) % X = 179
PetitY = uint8(C(1,2)) % Y = 143
RGB = img(PetitY, PetitX, :)
OR this :
RGB = img(uint8(C(1,2), C(1,1), :)
I invariably get a 3×3×3 uint8 array? The trouble is that PetitX and PetitY are coming out as 1x3 char? Pardon my ignorance but in some other programming languages, the type 'char' means a 'caracter', like an ASCII character. Which could explain why I am getting a 3x3 array instead of just a 1x3 vector?
Walter Roberson
Walter Roberson 2022년 1월 8일
편집: 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.

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


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일
편집: Walter Roberson 2022년 1월 5일
Well, I tried this code :
h2 = imshow(img);
set(h2, 'InitialMagnification',100);
f.Position = [100 100 800 1000];
and I get an error :
Unrecognized property InitialMagnification for class Image.
Back to square one...
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...

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

카테고리

Help CenterFile Exchange에서 Line Plots에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by