我有一张图像(带有1-5个黑点的白色背景),称为main.jpg
(主图像)。
我正在尝试在主图像中找到的每个黑点中放置另一个图像(secondary.jpg)。
为了做到这一点:
不幸的是,我不知道如何做第三步。
例如:
主要形象是:
次要图片是:
输出:
(点在椅子后面。它们是图像中心点)
这是我的代码:
mainImage=imread('main.jpg')
secondaryImage=imread('secondary.jpg')
secondaryImageResized = resizeImage(secondaryImage)
[m n]=size(mainImage)
for i=1:n
for j=1:m
% if it's black pixel
if (mainImage(i,j)==1)
outputImage = plotImageInCoordinates(secondaryImageResized, i, j)
% save this image
imwrite(outputImage,map,'clown.bmp')
end
end
end
% resize the image to (250,350) width, height
function [ Image ] = resizeImage(img)
image = imresize(img, [250 350]);
end
function [outputImage] = plotImageInCoordinates(image, x, y)
% Do something
end
任何帮助表示赞赏!
答案 0 :(得分:2)
这是一种没有卷积的替代方案。您必须考虑的一个复杂因素是,如果要将每个图像放在每个点的中心,则必须确定左上角的位置并将其索引到输出图像中,以便从左上角绘制所需的对象角落到右下角。您可以通过获取每个黑点位置并在水平方向上减去一半宽度并在垂直方向上减去一半高度来实现此目的。
现在解决你的实际问题。如果循环遍历黑色的点集,而不是整个图像,则效率会更高。您可以使用find
命令确定0的行和列位置。一旦执行此操作,循环遍历每对行和列坐标,减去坐标然后将其放在上面输出图像。
我会在物体重叠的地方施加额外的要求。为了适应这种情况,我将累积像素,然后找到非零位置的平均值。
为了适应这种情况而修改的代码如下。请注意,因为您正在使用JPEG压缩,所以您将有压缩瑕疵,因此0的区域可能不一定是0.我将以128的强度阈值,以确保零区域实际上为零。您还将遇到对象可能超出图像边界的情况。因此,为了适应这种情况,请将图像充分填充两倍,水平宽度的一半,垂直高度的一半,然后在放置物体后将其裁剪掉。
mainImage=imread('https://i.stack.imgur.com/gbhWJ.png');
secondaryImage=imread('https://i.stack.imgur.com/P0meM.png');
secondaryImageResized = imresize(secondaryImage, [250 300]);
% Find half height and width
rows = size(secondaryImageResized, 1);
cols = size(secondaryImageResized, 2);
halfHeight = floor(rows / 2);
halfWidth = floor(cols / 2);
% Create a padded image that contains our main image. Pad with white
% pixels.
rowsMain = size(mainImage, 1);
colsMain = size(mainImage, 2);
outputImage = 255*ones([2*halfHeight + rowsMain, 2*halfWidth + colsMain, size(mainImage, 3)], class(mainImage));
outputImage(halfHeight + 1 : halfHeight + rowsMain, ...
halfWidth + 1 : halfWidth + colsMain, :) = mainImage;
% Find a mask of the black pixels
mask = outputImage(:,:,1) < 128;
% Obtain black pixel locations
[row, col] = find(mask);
% Reset the output image so that they're all zeros now. We use this
% to output our final image. Also cast to ensure accumulation is proper.
outputImage(:) = 0;
outputImage = double(outputImage);
% Keeps track of how many times each pixel was hit by the object
% This is so that we can find the average at each location.
counts = zeros([size(mask), size(mainImage, 3)]);
% For each row and column location in the image
for i = 1 : numel(row)
% Get the row and column locations
r = row(i); c = col(i);
% Offset to get the top left corner
r = r - halfHeight;
c = c - halfWidth;
% Place onto final image
outputImage(r:r+rows-1, c:c+cols-1, :) = outputImage(r:r+rows-1, c:c+cols-1, :) + double(secondaryImageResized);
% Accumulate the counts
counts(r:r+rows-1,c:c+cols-1,:) = counts(r:r+rows-1,c:c+cols-1,:) + 1;
end
% Find average - Any values that were not hit, change to white
outputImage = outputImage ./ counts;
outputImage(counts == 0) = 255;
outputImage = uint8(outputImage);
% Now crop and show
outputImage = outputImage(halfHeight + 1 : halfHeight + rowsMain, ...
halfWidth + 1 : halfWidth + colsMain, :);
close all; imshow(outputImage);
% Write the final output
imwrite(outputImage, 'finalimage.jpg', 'Quality', 100);
我们得到:
我没有被告知你的图像有透明度。因此,您需要做的是使用imread
,但要确保您在alpha通道中读取。然后我们检查是否存在,如果存在,我们将确保没有透明度的任何值的背景设置为白色。您可以使用以下代码执行此操作。确保将其置于代码的最顶层,替换正在加载的图像:
mainImage=imread('https://i.stack.imgur.com/gbhWJ.png');
% Change - to accommodate for transparency
[secondaryImage, ~, alpha] = imread('https://i.imgur.com/qYJSzEZ.png');
if ~isempty(alpha)
m = alpha == 0;
for i = 1 : size(secondaryImage,3)
m2 = secondaryImage(:,:,i);
m2(m) = 255;
secondaryImage(:,:,i) = m2;
end
end
secondaryImageResized = imresize(secondaryImage, [250 300]);
% Rest of your code follows...
% ...
上面的代码已被修改为在篮球图像中读取。其余的代码保持不变,因此得到:
答案 1 :(得分:1)
您可以使用convolution来达到预期的效果。这将在EXAMPLE
中的任何地方放置im
的副本。
imz
此外,您可能希望避免将% load secondary image
im = double(imread('secondary.jpg'))/255.0;
% create some artificial image with black indicators
imz = ones(500,500,3);
imz(50,50,:) = 0;
imz(400,200,:) = 0;
imz(200,400,:) = 0;
% create output image
imout = zeros(size(imz));
imout(:,:,1) = conv2(1-imz(:,:,1),1-im(:,:,1),'same');
imout(:,:,2) = conv2(1-imz(:,:,2),1-im(:,:,2),'same');
imout(:,:,3) = conv2(1-imz(:,:,3),1-im(:,:,3),'same');
imout = 1-imout;
% output
imshow(imout);
保存为main.jpg
,因为它会导致有损压缩,并且可能会导致任何依赖于精确像素值的方法出现问题。我建议使用无损的.jpg
,并且对于相同颜色重复多次的合成图像,也可能比.png
压缩得更好。