Text inside the meshgrid

4 views (last 30 days)
Al Ne
Al Ne on 6 Jun 2024
Commented: Al Ne on 7 Jun 2024
Hello,
I am trying to place an arbitrary text inside the meshgrid. The code is as follows:
Nx = 201; Ny = 201;
TEXT = 'K e k'; % Text to draw
FONT_SIZE = 10; % Font size
FONT_NAME = 'Castellar'; % Font style (you can change this to any available font)
% Create a black image
img = zeros(Ny, Nx);
% Create a figure, axes, and an image object
figure('Visible', 'off'); % Create an invisible figure
axes('Units', 'pixels', 'Position', [1, 1, Nx, Ny], 'Visible', 'off'); % Create axes
imageHandle = imshow(img); % Show the black image
% Add text to the image
text(Nx / 2, Ny / 2, TEXT, 'FontSize', FONT_SIZE, 'FontName', FONT_NAME, ...
'Color', [1, 1, 1], 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle');
% Get the image data
frame = getframe(gca);
imgWithText = frame.cdata;
% Convert to grayscale and then to binary mask
imgWithTextGray = rgb2gray(imgWithText);
mask = imgWithTextGray > 0;
% Invert the binary mask
mask_inverted = ~mask;
% Convert the inverted binary mask to double type
mask_double = double(mask_inverted);
% Flip upside down
obst = flipud(mask_double);
% Display the final mask (optional)
figure;
imshow(obst);
The code works fine with this grid resolution. However, when i increase the number of mesh points along y-axis (Ny), i get incorrect size of the obst. In particular, the maximum resolution of Ny is 420. For example, if i set Nx=601 and Ny=601, i will get the obst size of 420x601. Obviously, the problem is in this part:
% Get the image data
frame = getframe(gca);
imgWithText = frame.cdata;
I cannot understand why the frame data is limited along y-axis (Ny) by 420 points despite i have enough memory. Can someone suggest anything to fix this problem?
kind regards,
Alex

Accepted Answer

Adam Danz
Adam Danz on 6 Jun 2024
The problem: the initial image it not fully displayed in the figure
Below is the section of code that creates the axes where the initial image is displayed. The intention was to set the axes size to the size of the image. This makes the axes larger than the figure so the image is cut off by the figure frame.
This went unnoticed for two reasons. First, Visible is set to Off for the figure and axes so they never appear. Second, the image is merely black and imshow doesn't show the axes rulers so even if the figure and axes were visible, it would just look all black.
Nx = 601;
Ny = 601;
figure('Visible', 'off');
axes('Units', 'pixels', 'Position', [1, 1, Nx, Ny], 'Visible', 'off');
imageHandle = imshow(img);
Let's plot an image using the small and large image sizes from your question.
% Small size
Nx = 201;
Ny = 201;
figure('Visible', 'on');
axes('Units', 'pixels', 'Position', [1, 1, Nx, Ny], 'Visible', 'on');
imageHandle = imshow("peppers.png");
% large size
Nx = 601;
Ny = 601;
figure('Visible', 'on');
axes('Units', 'pixels', 'Position', [1, 1, Nx, Ny], 'Visible', 'on');
imageHandle = imshow("peppers.png");
You can see that the larger image extends beyond the figure space. When getframe captures the image, it only captures what's in the axes so the center of the larger image is not the center of the axes.
Solutions
One solution is to set the figure size so the axes fits within the figure.
Nx = 601;
Ny = 601;
figure('Visible', 'on','Units', 'pixels', 'Position', [1, 1, Nx*1.05, Ny*1.05]);
axes('Units', 'pixels', 'Position', [1, 1, Nx, Ny], 'Visible', 'on');
imageHandle = imshow("peppers.png");
Also, if you have the image processing toolbox, look into insertText which does a lot of the work in your question.
  3 Comments
Adam Danz
Adam Danz on 7 Jun 2024
If the dog shape is all black and the background is all white (or vise versa) and you're looking for any image of a dog, I would start by doing the following.
  1. Find a very clean image of a dog against a solid or transparent background, no shadowing (example).
  2. Use imbinarize to convert the image to black and white where the background is white and the dog is black (or vise versa).
  3. Then you can easily center the image by padding the array (or see imtranslate).
No need to insert it in to another array if you're just dealing with these conditions.
If you have no restrictions on the shape of the dog, you could even use an emoji, though a word of caution: emojis render differently on different platforms.
h = imshow(255*ones(600,600));
ax = ancestor(h,'axes');
text(ax,300,300, char([55357 56341]), FontSize=90, horizontalAlignment='center',VerticalAlignment='middle')
F = getframe(ax);
BW = any(F.cdata < uint8(255),3);
imshow(BW) % imshow(~BW) if you want to reverse polarity
Al Ne
Al Ne on 7 Jun 2024
That's exactly what i need. Many thanks for this clear step by step algorithm!

Sign in to comment.

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!