MATLAB/Octave:从图像中切出很多圆圈
我有一个矩阵(图像)和有关圆圈内有趣部分的信息 (给出中心坐标和半径)。我想剪掉所有的圆 矩阵的一部分,以便对每个圆进行更多计算。或者至少我想要一个带有所有圆圈的位掩码。
我使用 Octave(但也可以使用 MATLAB,但由于许可证问题,这会很困难),并且有以下脚本,其中包含来自 stackoverflow 的一些提示。我有 20 个圆圈的信息,在我的 Core i5 上使用 Octave 大约需要 0.7 秒:
% image
dim_x = 1000;
dim_y = 1000;
A=rand(dim_x,dim_y);
% center positions and ...
c = [222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112];
%... radii of the circles
r = [10 33 55 2 22 10 33 55 2 22 10 33 55 2 22 10 33 55 2 22];
tic;
for i=1:size(c,1)
% create a bitmask ...
mask = bsxfun(@plus, ((1:dim_y) - c(i,1)).^2, (transpose(1:dim_x) - c(i,2)).^2) < r(i)^2;
% ... cut the circles out of the image
B=A.*mask;
end;
toc;
你知道一个性能更高的解决方案吗,因为我想要大约 600 个圆圈。
提前致谢
I have an matrix (image) and information about interesting part within circles
(center corrdinates and radii given). I want to cut for all the circles the
parts of the matrix in order to do some more calculations for each circle. Or at least I want to have a bitmask with all the circle.
I use Octave (but could also use MATLAB but it would be difficult because of licence iusses) and have the following script with some hints from stackoverflow. I have information of 20 circles and it takes about 0.7 s on my Core i5 using Octave:
% image
dim_x = 1000;
dim_y = 1000;
A=rand(dim_x,dim_y);
% center positions and ...
c = [222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112];
%... radii of the circles
r = [10 33 55 2 22 10 33 55 2 22 10 33 55 2 22 10 33 55 2 22];
tic;
for i=1:size(c,1)
% create a bitmask ...
mask = bsxfun(@plus, ((1:dim_y) - c(i,1)).^2, (transpose(1:dim_x) - c(i,2)).^2) < r(i)^2;
% ... cut the circles out of the image
B=A.*mask;
end;
toc;
Do you know a more performant solution since I want to have about 600 circles.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试
根据我的 MATLAB 分析器,这比您的版本快大约 4 倍。此外,
B = A.*mask
行与原始mask = ...
行花费的时间大致相同。不确定对此您能做些什么。Try
According to my MATLAB profiler, this is about 4 times faster than your version. Also, the
B = A.*mask
line takes about the same amount of time as the originalmask = ...
line. Not sure there's much you can do about that.您可以采取多种措施来提高代码效率,尽管其中一些具体取决于您最终想要什么,以及您可以对圆做出哪些假设(例如,它们可以重叠吗?是否有许多相似的半径?) 。
下面是一个假设半径之间很少重复的解决方案,并且中心坐标始终是整数像素值。
顺便说一句:如果您有不重叠的圆圈,则可以在循环后使用
bwlabel
(或使用 find 和 sub2ind 将i
写入各个圆圈),这样您可以使用accumarray一次性处理所有圆。There's several things you can do to make your code more efficient, though some of them depend on exactly what you want in the end, and on what assumptions you can make about the circles (e.g. can they overlap? Are there many similar radii?).
Below is a solution that assumes that there is very little repetition among radii, and center coordinates are always integer pixel values.
By the way: If you have non-overlapping circles, you can use
bwlabel
after the loop (or use find and sub2ind to writei
into the individual circles), so that you can process all circles in one go usingaccumarray
.您可能想研究一下 Matlab 的
strel
(不确定 Octave 的可用性,在 Matlab 中它是图像处理工具箱的一部分)。nn
参数影响性能。将其设置为 4、6 或 8 将提高性能,但代价是遮罩不完全是圆形。您还可以通过使用
bsxfun
重写repmat
位来榨取一些性能。You may want to look into Matlab's
strel
(not sure about Octave availability, in Matlab it is part of the image processing toolbox).The
nn
parameter effects performance. Making it 4, 6, or 8 will improve performance at the cost of your mask not being precisely a circle.You can also squeeze some performance out of it by rewriting the
repmat
bit using absxfun
.我建议使用 MATLAB 图像处理中的 POLY2MASK 函数工具箱(也可在 Octave 的 Image 包中找到)。检查“算法”部分以了解它如何处理离散像素。
这是测试性能的示例:
在我的笔记本电脑上,这完成于:
I am going to suggest using POLY2MASK function from the MATLAB Image Processing Toolbox (also available in the Image package for Octave). Check the "algorithm" section to see how it handles the discrete pixels.
Here is an example to test performance:
On my laptop, this finishes in: