Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 快速复制属于圆的像素的方法_Matlab_Image Processing_Vectorization - Fatal编程技术网

Matlab 快速复制属于圆的像素的方法

Matlab 快速复制属于圆的像素的方法,matlab,image-processing,vectorization,Matlab,Image Processing,Vectorization,我有一个初始灰度图像img,采用double格式,具有许多相同半径的圆和具有圆心坐标x和y的列向量。我需要将属于圆的所有像素复制到数组cpix。到目前为止,我只想到了使用for循环的最直接的解决方案。有没有一种方法可以将代码矢量化,或者让它工作得更快 % x(:) - vector with a few circles center X coordinates % y(:) - vector with a few circles center Y coordinates d = 27;

我有一个初始灰度图像
img
,采用
double
格式,具有许多相同半径的圆和具有圆心坐标
x
y
的列向量。我需要将属于圆的所有像素复制到数组
cpix
。到目前为止,我只想到了使用
for
循环的最直接的解决方案。有没有一种方法可以将代码矢量化,或者让它工作得更快

% x(:) - vector with a few circles center X coordinates
% y(:) - vector with a few circles center Y coordinates
d = 27;                  %diameter
r = floor(d/2);          %radius
cpix = double(zeros(d,d,size(x,1)));

for iCent = 1:size(x,1)  %for each circle
    for ix = 1:d
        for iy = 1:d
            if ((ix-r)^2 + (iy-r)^2) < r^2
                cpix(iy,ix,iCent) = img(iy+y(iCent)-r,ix+x(iCent)-r);
            end
        end
    end
end
%x(:)-以x坐标为中心有几个圆的向量
%y(:)-以y坐标为中心有几个圆的向量
d=27;%直径
r=地板(d/2);%半径
cpix=双精度(零(d,d,大小(x,1));
对于iCent=1:每个圆的尺寸(x,1)%
对于ix=1:d
对于iy=1:d
如果((ix-r)^2+(iy-r)^2)
考虑到您的图像是双层的,并且有一层,因为圆的中心位于
[cx,cy]
您可以得到一个矩阵,其大小与主图像相同,具有逻辑值,其中
1
指定像素位于圆内(半径=
r
),否则
0

[X,Y] = meshgrid(1:size(img,1),1:size(img,2));
C = bsxfun(@le,(X-cx).^2+(Y-cy).^2 ,r);
最后,
img(C)
包括所有有效像素值

单圈示例:

r = 5;
cx=100;
cy=100;
Id = im2double(imread('myimage.png'));
Id1 = Id(:,:,1);
[X,Y] = meshgrid(1:size(Id1,1),1:size(Id1,2));
C = bsxfun(@le,(X-cx).^2+(Y-cy).^2 ,r);

length(Id1(C))
ans = 
      21
如果有多个圆,则需要一个for循环

cx = [100,110,120];
cy = [150,170,190];

for ii = 1:length(cx);
    C = bsxfun(@le,(X-cx(ii)).^2+(Y-cy(ii)).^2 ,r);
end
代码的其他部分保持不变。

只有一个循环(对于每个圆),您可以使用类似磁盘的遮罩从图像中选择适当的像素。 从初始代码开始

% x(:) - vector with a few circles center X coordinates
% y(:) - vector with a few circles center Y coordinates
d = 27;                  %diameter
r = floor(d/2);          %radius
cpix = double(zeros(d,d,size(x,1)));
现在创建具有所需半径的遮罩。如果您有图像处理工具箱,则可以轻松完成此操作

h = fspecial('disk', r);
h = h > 0;
然后在循环中使用此遮罩选择所需区域

for i = 1:size(x,1)
    cpix(:,:,i) = h .* img(x(i)-r:x(i)+r, y(i)-r:y(i)+r);
end
由于只创建一次遮罩,因此它应该比为每个圆计算遮罩要快

如果你建立一个3D蒙版,你可以一次完成。如果
a x b
是图像的大小,
n
是圆圈数,则遮罩将是
a x b x n
。如果
repmat
将图像复制到大小为
n
的堆栈中。然后可以使用
*
乘法来获得最终结果。但是,结果将是一堆
a x b
图像,而不是您提到的
d x d

不确定它是否会更快,因为在创建3D遮罩的过程中,无论如何都要循环它。如果蒙版只构建一次并在很多图像中使用,那么它可能是值得的。

我有一个开源库,可以扫描各种空间模式(圆、环、蛇、网格、随机行走)中的像素。还可以应用各种空间变换(例如,旋转、缩放、剪裁)。这是一个python库,但是您可以轻松地将相关代码移植到MATLAB。

圆是否可以靠近图像的边界?在这种情况下会发生什么呢?不,圆圈距离边界的半径大于一个半径,这是一种方法,但您可以扩展示例以处理中心
cx
cy
数组。OP似乎有一些需要处理。谢谢你的建议,这是一个有趣的方法。但关键是要得到三维数组,其三维度等于圈数。完全矢量化在这里可能没有好处,因此我认为一个循环是合理的。干得好在执行建议的代码之后,我需要再次进行分段,以获得所需的数组,其中所有关于圆内磁盘区域的信息都将在第三维中进行索引。要处理350圈半径=15的样本图像966x966px,我的代码需要4.59秒,NKN提出的代码需要3.60秒(请记住,在执行后,我需要再次执行某种循环以获得所需的数组),那么有没有办法进行向量化操作以生成指定的数组?我无法提出基于网格的解决方案yetThanks!这是一个完美的解决方案,只需0.008290秒,而我的原始代码为4.594374秒。我唯一需要更改的是img索引-y和x被交换,因此该行看起来像
cpix(:,:,I)=h.*img(y(I)-r:y(I)+r,x(I)-r:x(I)+r)请通知某个地方,用户将需要图像处理工具箱来运行您的解决方案。如果以后的用户尝试此代码,并且在他们不知道原因的情况下失败,可能会减少挫折感。谢谢@hoki!我添加了图像处理工具箱说明。