Modify line style with insertShape

6 views (last 30 days)
Hi all,
I wrote a function to make a grid on an image. I can either draw the grid on top of the image or burn/insert it into the image, depending on user input. I can also modify line width and style- but only for the 'draw' method, because I can't seem to modify line style using insertShape. Does anyone know how to do this? I'll post the code. There is an example at the top for draw method, and for the burn method. Both should run and use default images. Thanks.
function [varargout] = imageGrid(I, varargin)
% imcirclecrop puts a grid on an image
% Example 1:
% I = imread('rice.png');
% vertLines = 10;
% horzLines = 10;
% lineWidth = 2;
% imshow(I);
% Igrid = imageGrid(I, 'vertLines', vertLines, 'horzLines', horzLines, 'lineWidth', lineWidth, 'lineStyle', ':', 'technique', 'Draw');
% Example 2:
% I = imread('cameraman.tif');
% vertLines = 15;
% horzLines = 10;
% lineWidth = 1;
% imshow(I);
% Igrid = imageGrid(I, 'vertLines', vertLines, 'horzLines', horzLines, 'lineWidth', lineWidth, 'lineStyle', ':', 'technique', 'burn');
% imshowpair(I, Igrid, 'montage')
%Set defaults
defaultVertLines = 10;
defaultHorzLines = 10;
defaultLineWidth = 1;
defaultLineStyle = ':';
defaultTechnique = 'Draw';
p = inputParser;
p.CaseSensitive = false;
p.KeepUnmatched = true; %store extra inputs instead of throwing error
addRequired(p, 'I');
addOptional(p, 'vertLines', defaultVertLines);
addOptional(p, 'horzLines', defaultHorzLines);
addOptional(p, 'lineWidth', defaultLineWidth);
addOptional(p, 'lineStyle', defaultLineStyle);
addOptional(p, 'technique', defaultTechnique);
%Parse inputs
parse(p, I, varargin{:});
vertLines = p.Results.vertLines;
horzLines = p.Results.horzLines;
lineWidth = p.Results.lineWidth;
technique = p.Results.technique;
lineStyle = p.Results.lineStyle;
drawCases = {'Draw'};
drawLogical = strcmpi(technique, drawCases); %True if 'technique' is a variation of 'draw'
horzTicks = round(linspace(1, size(I,1), horzLines),0); %cols where we will draw vertical lines
vertTicks = round(linspace(1, size(I,2), vertLines),0); %rows where we will draw horizontal lines
maxY = size(I,1); %num pixels in Y
maxX = size(I,2); %num pixels in X
if drawLogical %draw on the current image
for i = 1:1:vertLines
line([vertTicks(i), vertTicks(i)], [maxY, 0], 'LineWidth', lineWidth, 'Color', 'k', 'LineStyle', lineStyle); %draw vertical lines
for i = 1:1:horzLines
line([0, maxX], [horzTicks(i), horzTicks(i)], 'LineWidth', lineWidth, 'Color', 'k', 'LineStyle', lineStyle); %draw horizontal lines
varargout{1} = 'Done';
else %burn/insert the lines into the image
%Put together line coordinates the way that ShapeInserter wants
% [x1_line1, y1_line1, x2_line1, y2_line1;...
% x1_line2, y1_line2, x2_line2, y2_line2]
Vlines = zeros(length(vertTicks),4);
Vlines(:,1) = vertTicks;
Vlines(:,2) = 0;
Vlines(:,3) = vertTicks;
Vlines(:,4) = maxY;
Hlines = zeros(length(horzTicks), 4);
Hlines(:,1) = 0;
Hlines(:,2) = horzTicks;
Hlines(:,3) = maxX;
Hlines(:,4) = horzTicks;
%Put the two together
lines = vertcat(Vlines, Hlines);
lines = int32(lines);
%Insert them and output the modified image
Igrid = insertShape(I, 'Line', lines, 'LineWidth', lineWidth, 'Color', 'black');
varargout{1} = Igrid;
end %end imageDrawGrid()

Accepted Answer

Duncan Lilley
Duncan Lilley on 19 Sep 2017
One potential workaround to this is to create a new figure, display the image over the axes, and use the grid lines of the axes to display the desired grid. Then, the lines can be "burned" into the image by extracting the color data from the axes.
Note that, since MATLAB can automatically resize images if they do not fit within the screen, this may not work correctly for images larger than the screen.
Consider the following code:
%%Create new figure for image
fig = figure;
%%Draw the image
%%Format the axes
ax = gca;
ax.Visible = 'on';
axis(ax, 'equal');
grid(ax, 'on');
% Set line properties
ax.LineWidth = lineWidth;
ax.GridAlpha = 1;
ax.GridColor = 'k';
ax.GridLineStyle = lineStyle;
% Remove the x- and y-axes
ax.XAxis.Visible = 'off';
ax.YAxis.Visible = 'off';
% Set the spacing of the grid lines
ax.XTick = horzTicks;
ax.YTick = vertTicks;
% Remove any extra space around the image
ax.XLim = [0, maxX];
ax.YLim = [0, maxY];
% Set the size of the axes to be the same size as the image
ax.Units = 'Pixels';
ax.Position = [ax.Position(1),ax.Position(2), maxX, maxY];
%%Get the image data from the axes
% This will have the grid lines burned into the image
Igrid = getframe(ax);
Igrid = Igrid.cdata;
% If initial image was black & white, flatten the new image to
% match the format
if size(I,3) == 1
Igrid = rgb2gray(Igrid);
% Close the figure to clean up
varargout{1} = Igrid;
  1 Comment
Clay Swackhamer
Clay Swackhamer on 19 Sep 2017
Hi Duncan,
Thanks for answering. Unfortunately my images are higher resolution than my display. Also, I would like to save these gridded images without displaying them at all, because I am processing images in batches. Anyway this does give me another idea so I am grateful for it.
I guess I could always do it "manually" using some loops to go over the images and set pixels to desired colors. I'm afraid this might be difficult though, especially for creating images with dashed lines and such.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!