用图像替换箭袋箭头

matlab matlab-figure

419 观看

1回复

593 作者的声誉

我有一个圆形晶格,在晶格位置上,我绘制了归一化的箭头,这些箭头保持不变,并根据模拟改变方向,其细节无关紧要。

我的情节看起来像这样

在此处输入图片说明

是否可以用jpg / bmp / gif / png图像替换颤动图中的箭头?或通过任何其他命令?

理想情况下,它看起来应该像这样(尽管不一定是箭头)

在此处输入图片说明

作者: jarhead 的来源 发布者: 2016 年 3 月 17 日

回应 (1)


27

55918 作者的声誉

决定

说明

可以执行此操作的一种方法是,将带有纹理贴图表面对象用作FaceColor

在MATLAB中,您可以创建一个简单的矩形表面。您可以将设置为FaceColortexturemap这将导致分配给的值CData在整个曲面上映射。

然后,要获得透明度,您还可以将FaceAlphatexturemap设置为AlphaData并将其设置为,这些透明度值也将映射到整个曲面范围内。

要将其应用于您的案例,您需要将设置为CData要用来替换箭头的图像。并且您将希望与AlphaData图像数据具有相同的大小,在不透明的情况下值为1,在透明的情况下值为0。这将使它看起来不像您发布的图像,您可以清楚地看到边界框。然后,您将需要绘制这些箭头之一所在的表面,并对其进行适当的缩放/定位。

实作

更新:此代码(ImageQuiver)的更完善的版本现在可以在GithubMATLAB File Exchange上获得

为了说明我在说什么,我创建了以下函数,该函数实际上就是这样做的。它接受与输入相同的输入quiver(首先提供图像数据,最后提供可选AlphaData参数),并在指向请求方向的所有请求坐标上创建一个曲面,并按指定的比例缩放。

function h = quiverpic(im, X, Y, dX, dY, scale, alpha)
    % im - RGB or indexed image
    % X - X positions
    % Y - Y positions
    % dX - X direction vector
    % dY - Y direction vector
    % scale - Any scaling (Default = 1)
    % alpha - Transparency (same size as im), if not specified = ~isnan(im)

    h = hggroup();

    if ~exist('scale', 'var')
        % By default there is no scaling
        scale = 1;
    end

    if ~exist('alpha', 'var')
        % By default, any NaN will be transparent
        alpha = ~isnan(im);
    end

    % Determine aspect ratio of the source image
    width_to_height = size(im, 2) / size(im, 1);

    for k = 1:numel(X)
        % Determine angle from displacement vectors
        theta = atan2(dY(k), dX(k));

        % Subtract pi/2 to +y is considered "up"
        theta = theta + pi/2;

        % Setup surface plot boundary
        [xx,yy] = meshgrid([-0.5, 0.5] * width_to_height, [0 1]);

        % Scale depending on magnitude of dX and dY
        this_scale = scale * sqrt(dX(k).^2 + dY(k).^2);

        % Scale X and Y components prior to rotating
        xx = xx .* this_scale;
        yy = yy .* this_scale;

        % Rotate to align with the desired direction
        xdata = xx .* cos(theta) - yy .* sin(theta);
        ydata = xx .* sin(theta) + yy .* cos(theta);

        % Determine what is considered the "anchor" of the graphic.
        % For now this is assumed to be the "bottom-middle"
        xoffset = X(k) - mean(xdata(2,:));
        yoffset = Y(k) - mean(ydata(2,:));

        % Actually plot the surface.
        surf(xdata + xoffset, ...
             ydata  + yoffset, zeros(2), ...
             'Parent', h, ...
             'FaceColor', 'texture', ...
             'EdgeColor', 'none', ...
             'CData', im, ...
             'FaceAlpha', 'texture', ...
             'AlphaData', double(alpha));
    end
end

我写了一个小测试脚本来演示如何使用它并显示结果。

t = linspace(0, 2*pi, 13);
dX = cos(t(1:end-1));
dY = sin(t(1:end-1));
X = (3 * dX) + 5;
Y = (3 * dY) + 5;
scale = 1;

% Load the MATLAB logo as an example image
png = fullfile(matlabroot,'/toolbox/matlab/icons/matlabicon.gif');
[im, map] = imread(png);
im = ind2rgb(im, map);

% Determine alpha channel based on upper left hand corner pixel
flatim = reshape(im, [], 3);
alpha = ~ismember(flatim, squeeze(im(1,1,:)).', 'rows');
alpha = reshape(alpha, size(im(:,:,1)));

% Plot some things prior to creating the quiverpic object
fig = figure();
hax = axes('Parent', fig);
axis(hax, 'equal');

% Plot a full circle
t = linspace(0, 2*pi, 100);
plot((cos(t) * 3) + 5, (sin(t) * 3) + 5, '-')

hold(hax, 'on')

% Plot markers at all the quiver centers
plot(X, Y, 'o', 'MarkerFaceColor', 'w')

% Plot a random image behind everything to demonstrate transparency
him = imagesc(rand(9));
uistack(him, 'bottom')

axis(hax, 'equal')
colormap(fig, 'gray')
set(hax, 'clim', [-4 4]);

% Now plot the quiverpic
h = quiverpic(im, X, Y, dX, dY, 1, alpha);

axis(hax, 'tight')

结果

在此处输入图片说明

荒谬

矢量和缩放比例相同的图像

在此处输入图片说明

任何宽高比的图像都可以正常工作

在此处输入图片说明

作者: Suever 发布者: 17.03.2016 08:10
32x32