如何在MATLAB中创建一个带有线条的图像矩阵?

10
我想画一条从一个明确定义的点到另一个点的线,然后将其转换为图像矩阵,以便在其上使用高斯滤波器进行平滑处理。我使用函数 linegetframe 来绘制一条线并捕获图形窗口中的图像,但是 getframe 很慢而且不太可靠。我注意到当计算机被锁定时它不会捕捉任何内容,并且在执行了 170 次之后出现了 out of memory 错误。
我的问题是:
  • 是否有替代品可以代替 getframe 使用?
  • 是否有办法直接创建图像矩阵并在其中绘制线条?
这是一个最小化的代码示例:
figure1=line([30 35] ,[200 60]);
F= getframe;
hsize=40; sigma=20;
h = fspecial('gaussian',hsize,sigma); 
filteredImg = imfilter(double(F.cdata), h,256);
imshow(uint8(filteredImg));

[更新]

使用 linspace 的高性能 Mark提出的想法看起来非常有希望,但我该如何访问使用 linspace 计算出的矩阵坐标?我尝试了以下代码,但它并没有按照我的预期工作。我认为这是一个非常简单和基本的MATLAB问题,但我无法理解:

matrix=zeros(200,60);
diagonal=round([linspace(30,200,numSteps); linspace(35,60,numSteps)]);
matrix(diagonal(1,:), diagonal(2,:))=1;
imshow(matrix);

所以,你正在对矢量图像进行光栅化处理。关于这个主题有很多好的参考资料,维基百科一如既往地是一个很好的起点。 - High Performance Mark
我知道,但我总是尽量使用Matlab自带的函数。虽然我学不到太多东西,但它们更快,而且我不必像调试自己的代码那样花时间。 - Framester
4个回答

17

这里是一个将直线直接绘制到矩阵中的例子。首先,我们会创建一个值为0的矩阵来表示一张空白图片:

mat = zeros(250, 250, 'uint8');  % A 250-by-250 matrix of type uint8

假设我们想要从 (30, 35)(200, 60) 画一条线。我们首先需要计算这条线需要多长的像素:

x = [30 200];  % x coordinates (running along matrix columns)
y = [35 60];   % y coordinates (running along matrix rows)
nPoints = max(abs(diff(x)), abs(diff(y)))+1;  % Number of points in line

接下来,我们使用 linspace 计算线像素的行和列索引,使用sub2ind将它们从下标索引转换为线性索引,然后使用它们修改mat

rIndex = round(linspace(y(1), y(2), nPoints));  % Row indices
cIndex = round(linspace(x(1), x(2), nPoints));  % Column indices
index = sub2ind(size(mat), rIndex, cIndex);     % Linear indices
mat(index) = 255;  % Set the line pixels to the max value of 255 for uint8 types

你可以使用以下代码来可视化该行以及过滤后的版本:

subplot(1, 2, 1);
image(mat);        % Show original line image
colormap(gray);    % Change colormap
title('Line');

subplot(1, 2, 2);
h = fspecial('gaussian', 20, 10);  % Create filter
filteredImg = imfilter(mat, h);    % Filter image
image(filteredImg);                % Show filtered line image
title('Filtered line');

在此输入图片描述


感谢gnovice提供的全面回答! - Framester

5
如果您拥有计算机视觉系统工具箱,那么可以使用ShapeInserter对象。它可用于在图像上绘制线条、圆形、矩形和多边形。
mat = zeros(250,250,'uint8');
shapeInserter = vision.ShapeInserter('Shape', 'Lines', 'BorderColor', 'White');
y = step(shapeInserter, mat, int32([30 60 180 210]));
imshow(y);

http://www.mathworks.com/help/vision/ref/vision.shapeinserterclass.html


0

你可以在这里检查我的答案。这是一种强大的方法来实现你所要求的内容。我的方法的优点是它不需要额外的参数来控制所画线条的密度。(density)


-1

类似这样:

[linspace(30,200,numSteps); linspace(35,60,numSteps)]

你觉得这样行吗?

马克


Linspace看起来非常有前途,但我如何访问使用linspace计算的矩阵坐标?我尝试了最后30分钟,但以下代码不起作用,我认为它应该..(scnr)我假设这是一个非常简单和基本的Matlab问题,但我无法理解它。 matrix=zeros(200,60); diagonal=round([linspace(30,200,numSteps); linspace(35,60,numSteps)]); matrix(diagonal(1,:), diagonal(2,:))=1; imshow(matrix); - Framester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接