這是一個沒有卷積的替代方案。您必須考慮的一個複雜問題是,如果要將每個圖像放在每個點的中心,則必須確定左上角的位置並將其索引到輸出圖像中,以便從左上角繪製所需的對象角落到右下角。您可以通過取每個黑點位置並將水平寬度的一半和高度的一半垂直減去來完成此操作。
現在到你的實際問題。如果循環遍歷一組黑色的點而不是整個圖像,效率會更高。您可以通過使用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...
% ...
上面的代碼已被修改的籃球圖像中讀取:確保這個被放置在你的代碼的最頂部,更換圖像加載。其餘代碼保持不變,因此我們得到:
非常感謝您的幫助! 不幸的是,它不能在這個圖像上工作:i.imgur.com/qYJSzEZ.png –
有黑色背景的球:https://i.imgur.com/bteofvh.jpg雖然圖像沒有... –
這是因爲你的圖像有一個alpha通道。我將不得不改變我的代碼。 – rayryeng