我有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
答案 0 :(得分:1)
考虑到你的图像是双倍的,并且有一层,对于圆的中心位于[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
代码的其他部分保持不变。
答案 1 :(得分:1)
只有一个循环(对于每个圆圈),您可以使用像磁盘一样的掩码从图像中选择适当的像素。 从您的初始代码开始。
% 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蒙版期间循环它。如果掩模只构建一次并用于很多图像,那么它可能是值得的。
答案 2 :(得分:0)
我有一个开源库pixelscan,它可以扫描各种空间模式(圆圈,环,蛇,网格,随机漫步)中的像素。还可以应用各种空间变换(例如,旋转,缩放,剪裁)。它是一个python库,但您可以将相关代码轻松移植到MATLAB。