有人可以帮我在图像上放置徽标(例如,MATLAB徽标)吗?
首先我使用imread
命令读取图像,然后在左上角,我需要在该图像上添加MATLAB徽标。我该怎么做?
答案 0 :(得分:6)
这是一个可重现的例子。 @liangbright走在正确的轨道上,但我想制作一个有效的例子。让我们说我想在显示fictional federal agent, turned rogue: Jack Bauer的快照的左上角嵌入MATLAB徽标。以下是Wikimedia Commons媒体档案中的MATLAB徽标示例:
以下是Jack Bauer的图片我将把MATLAB徽标嵌入:
来源:The Mirror
MATLAB徽标非常大,所以我们要调整它的大小,使它成为一个小图标。让我们将其调整为原始大小的10%。一旦我们这样做,我们只需要用MATLAB徽标替换左上角的像素。请记住,此MATLAB徽标采用PNG格式,这意味着它将具有透明度/ Alpha通道。这很棒,因为我们需要alpha通道,这样我们就可以放置MATLAB徽标,同时让它看起来很自然。这就是透明度的全部要点。您可以使用imread
,但我们需要指定其他输出参数才能获取Alpha通道。具体来说,我们需要第三个参数。第二个参数是颜色图,但是我们忽略它,因为我们不需要它来做你想做的事情。现在,alpha通道只是一个2D矩阵,而MATLAB徽标和Jack Bauer是颜色图像。因此,我们希望将所有颜色混合在一起,因此我们需要将alpha通道设为3D矩阵。这可以通过简单地复制alpha贴图3次并将其堆叠成3D矩阵来完成。我们可以使用repmat
来完成此操作。
一旦我们有了这个,我们最终可以将徽标与图像混合在一起。 @liangbright的方程式正确。如果你想将两个图像混合在一起,给定一个alpha通道,你可以这样做:
out = alpha*im1 + (1-alpha)*im2;
im1
是您要混合的图片,而im2
是im1
将放置在此图片顶部的图片。在我们的例子中,im1
是我们的MATLAB徽标,而im2
是Jack Bauer。在我们甚至可以做到这一点之前,实际上从imread
返回的alpha通道(通常是......)是一个无符号的8位整数类型图像,其alpha值跨越[0-255]
。因此,我们需要转换alpha地图,使其跨越[0-1]
。您可以使用im2double
为我们执行此操作。
最后,我们可以使用imresize
缩小图像,使其原始大小为10%。我们还需要知道此调整大小的图像的尺寸,以便我们可以正确地将其放入更大的图像中。
最后一点说明:我们需要暂时将每张图片的类型转换为double
,因为alpha贴图现在为double
。我们需要确保当您将两个矩阵相乘时,它们必须是相同的类型。一旦我们将这些内容混合在一起,我们就会将图像的这一部分转换回uint8
,因为这是原始类型的较大图像。
不用多说,这里是您应该使用的代码。请注意,在运行此图像之前,我已将图像保存到计算机中:
%// Load in MATLAB logo
[logo, map, alpha] = imread('Matlab_Logo.png');
%// Load in Jack Bauer
jack = imread('Kiefer-Sutherland-in-24.jpg');
%// Resize the MATLAB logo
logoResize = imresize(logo, 0.1, 'bilinear');
%// Make sure you do the same for the alpha map
alphaResize = imresize(alpha, 0.1, 'bilinear');
%// Duplicate the alpha map to make this three channels - This is a colour image
alphaResize = repmat(alphaResize, [1 1 3]);
%// Make double to ensure mixing
alphaResize = im2double(alphaResize);
%// Get the size of the resized logo - we need this
%// to properly mix the stuff in
rows = size(logoResize, 1);
cols = size(logoResize, 2);
%// Mix in the logo with the image
jack(1:rows,1:cols,:) = uint8(alphaResize.*double(logoResize) + ...
(1-alphaResize).*double(jack(1:rows,1:cols,:)));
figure;
imshow(jack);
这是我得到的图像:
现在,假设您要更改徽标的位置,使其显示在右上角,左下角或右下角。因此,您只需在显示最终图像之前更改代码的最后一个语句。最后一句话基本上控制了 你希望徽标放在更大的图像中。
具体来说,您必须更改我们要分配给输出的索引。因此,让我们做其他三个案例,我会在每个语句中显示每个语句,然后是后面的结果图像。
jack(1:rows,end-cols+1:end,:) = uint8(alphaResize.*double(logoResize) + ...
(1-alphaResize).*double(jack(1:rows,end-cols+1:end,:)));
jack(end-rows+1:end,1:cols,:) = uint8(alphaResize.*double(logoResize) + ...
(1-alphaResize).*double(jack(end-rows+1:end,1:cols,:)));
jack(end-rows+1:end,end-cols+1:end,:) = uint8(alphaResize.*double(logoResize) + ...
(1-alphaResize).*double(jack(end-rows+1:end,end-cols+1:end,:)));
您可能想要混合到较大图像中的图像可能没有Alpha通道。这方面的例子是JPEG图像。如果您无法访问Alpha通道,那么您可以执行@liangbright建议的操作,只需为alpha通道指定一个常量即可。因此,只需执行以下操作即可。我上面显示的大多数代码都会消失,因为没有alpha通道。因此,代码将简化为:
%// Load in MATLAB logo without alpha channel
logo = imread('Matlab_Logo.png');
%// Load in Jack Bauer
jack = imread('Kiefer-Sutherland-in-24.jpg');
%// Resize the MATLAB logo
logoResize = imresize(logo, 0.1, 'bilinear');
%// Get the size of the resized logo - we need this
%// to properly mix the stuff in
rows = size(logoResize, 1);
cols = size(logoResize, 2);
%// Specify alpha here
alpha = 0.9;
%// Mix in the logo with the image
jack(1:rows,1:cols,:) = uint8(alpha.*double(logoResize) + ...
(1-alpha).*double(jack(1:rows,1:cols,:)));
figure;
imshow(jack);
......这是我得到的图像:
请注意,像这样放入MATLAB徽标并不会使徽标看起来像它自然那样。这是因为我们假设徽标的所有alpha值都是相同的,其中alphas应该在徽标边缘除之外。此外,实际徽标像素(不是沿边缘或背景)的alpha值应为1,因为您希望它显示在较大图像的顶部。所有这一切,这大致定义了alpha通道应该如何表现,从而使徽标和更大的图像之间的过渡更自然。
我还决定不使用简化的alpha显示徽标在其他角落位置的样子,因为代码与左上角的情况基本相同。只需将alpha
指定为常量,然后在显示图像之前修改代码的最后一个语句,无论您想要哪种情况(右上角,左下角,右下角)。
希望这有帮助!
答案 1 :(得分:2)
I
:图片
M
:徽标
I(a:b, c:d) = (1-Alpha)*I(a:b, c:d)+ Alpha*M
(设置Alpha = 0.9)
a:b c:d
与左上角有关
然后你显示图像I
你不能一个一个地绘制两个图像,因为第二个将覆盖第一个