【问题标题】:Speeding up Octave / Matlab plot加速 Octave / Matlab 绘图
【发布时间】:2017-09-21 11:49:43
【问题描述】:

Gnoivce 和 Hartmut 对这段代码帮助很大,但运行起来需要一段时间。 bar 命令中的 CData 属性似乎没有在我使用的 Octave 4.0-4.2.1 版本中实现。解决此问题的方法是单独绘制所有单个条并为每个单独的条设置单独的颜色。人们帮助我,让我走到了这一步,但情节需要 5 分钟 显示有没有人知道加快速度的方法?

以下代码运行: 下面使用的 marbles.jpg 图像文件:

clear all,clf reset,tic,clc 
rgbImage = imread('/tmp/marbles.jpg');
hsvImage = rgb2hsv(rgbImage);         % Convert the image to HSV space
hPlane = 360.*hsvImage(:, :, 1);      % Get the hue plane scaled from 0 to 360
binEdges = 0:360;                 %# Edges of histogram bins
N = histc(hPlane(:),binEdges);    %# Bin the pixel hues from above

C = colormap(hsv(360));  %# create an HSV color map with 360 points
stepsize = 1; % stepsize 1 runs for a while...

for n=binEdges(2:stepsize:end)   %# Plot the histogram, one bar each
    if (n==1), hold on, end
    h=bar(n,N(n));
    set(h,'FaceColor',C(n,:));   %# set the bar color individually
end

axis([0 360 0 max(N)]);           %# Change the axes limits
set(gca,'Color','k');             %# Change the axes background color
set(gcf,'Pos',[50 400 560 200]);  %# Change the figure size
xlabel('HSV hue (in degrees)');   %# Add an x label
ylabel('Bin counts');             %# Add a y label
fprintf('\nfinally Done-elapsed time -%4.4fsec- or -%4.4fmins- or -%4.4fhours-\n',toc,toc/60,toc/3600);

5 分钟后创建的情节:

查看原问题original question

【问题讨论】:

  • 您是否检查过代码的哪一部分花费了这么长时间?是循环吗?
  • @gnovice 是的 stepsize = 1; % stepsize 1 runs for a while... 会导致时间增加,如果 stepsize is set to 10 更快,但会在条形之间留下空白空间。
  • 为什么不生成图像而不是条形图?
  • @Andy 我愿意尝试任何东西,但我是否还需要循环通过导致速度变慢的 For 循环?还是我错过了什么?
  • @RickT 这两个答案中是否缺少某些内容?如果您不接受其中之一,您应该评论他们为什么不回答您的问题

标签: matlab plot octave


【解决方案1】:

我猜循环是你代码中的瓶颈,需要这么长时间?您可以通过调用bar 来删除循环并创建绘图,然后调用set 来修改hggroup 对象及其子patch 对象:

h = bar(binEdges(1:end-1), N(1:end-1), 'histc');   % hggroup object
set(h, 'FaceColor', 'flat', 'EdgeColor', 'none');
hPatch = get(h, 'Children');                       % patch object
set(hPatch, 'CData', 1:360, 'CDataMapping', 'direct');

在 Octave 4.0.3 中使用此修复程序重复您的代码会立即为我呈现:

【讨论】:

    【解决方案2】:

    正如我在评论中建议的那样,我会使用图像(在我的系统上为您的图像花费 0.12 秒)。

    编辑:更多 cmets,修复小错误,允许创建步长 > 1 的 bin

    img_fn = "17S9PUK.jpg";
    if (! exist (img_fn, "file"))
      disp ("downloading image from imgur.com...");
      fflush (stdout);
      urlwrite ("http://i.imgur.com/17S9PUK.jpg", "17S9PUK.jpg");
    endif
    
    rgbImage = imread (img_fn);
    
    ## for debugging so the matrixes fit on screen
    if (0)
      pkg load image
      rgbImage = imresize (rgbImage, [6 8]);
    endif
    
    hsvImage = rgb2hsv(rgbImage);
    hPlane = 360 .* hsvImage(:, :, 1); 
    
    ## create bins, I've choosen 2 step to "smooth" the result
    binEdges = 1:2:360;
    N = histc (hPlane(:), binEdges)';
    
    cm = permute (hsv (numel (binEdges)), [3 1 2]);
    
    ## Create an image with x = hue
    img = repmat (cm, max(N), 1);
    
    ## Create binary mask which is used to black "img" dependent on N
    sp = sparse (N(N > 0), (1:360)(N > 0), true, max(N), numel (binEdges));
    mask = full (cumsum (flipud (sp)));
    
    ## extend mask in depth to suppress RGB
    mask = repmat (mask, [1 1 3]);
    
    ## use inverted mask to "black out" pixels < N
    img(logical (1 - flipud (mask))) = 0;
    
    ## show image
    image (binEdges, 1:max(N), img)
    set (gca, "ydir", "normal");
    xlabel('HSV hue (in degrees)');
    ylabel('Bin counts');
    
    ## print it for stackoverflow
    print ("out.png")
    

    与上述相同,但 bin 宽度为 1(经过的时间为 0.167423 秒。)

    binEdges = 1:360;
    

    【讨论】:

    • 啊,还有一个小BUG,因为一次性的,最大峰值丢失了……
    • @Rick T:你做过一些基准测试,哪个答案更快?因为“速度”是您问题的实际目标。
    猜你喜欢
    • 2022-01-25
    • 2013-05-10
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多