2017-10-04 126 views
2

我有一個圖像(帶有1-5個黑點的白色背景),稱爲main.jpg(主圖像)。將圖像放置在另一個圖像的黑色像素中

我想在主圖像中找到的每個黑點中放置另一個圖像(secondary.jpg)。

爲了做到這一點:

  1. 我發現在主圖像
  2. 黑色像素調整爲,我想在每一個
  3. 情節圖像特定尺寸的二次圖像座標,我發現在步驟1。 (黑色像素應該是次要圖像的中心座標)

不幸的是,我不知道如何做第三步。

例如:

主圖像是:

enter image description here

副圖像是:

enter image description here

輸出:

enter image description here

(點在椅子後面。他們是圖像中心點)

這是我的代碼:

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 

任何幫助表示讚賞!

回答

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); 

我們得到:

enter image description here


編輯

我就不講了,你的圖像具有透明性。因此,您需要做的是使用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... 
% ... 

上面的代碼已被修改的籃球圖像中讀取:確保這個被放置在你的代碼的最頂部,更換圖像加載。其餘代碼保持不變,因此我們得到:

enter image description here

+0

非常感謝您的幫助! 不幸的是,它不能在這個圖像上工作:i.imgur.com/qYJSzEZ.png –

+0

有黑色背景的球:https://i.imgur.com/bteofvh.jpg雖然圖像沒有... –

+0

這是因爲你的圖像有一個alpha通道。我將不得不改變我的代碼。 – rayryeng

1

您可以使用convolution來達到預期的效果。這將在imz的任何地方都有一個黑點的im副本。

% 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); 

enter image description here

此外,你可能想避免保存main.jpg作爲.jpg,因爲它會導致有損壓縮,並可能會與依賴於精確的像素值的任何方法引起的問題。我會推薦使用.png這是無損的,並且對於合成圖像可能壓縮比.jpg好,其中相同顏色重複多次。

+0

Hi @jodag。 我試過這個圖片:https://i.imgur.com/qYJSzEZ.png輸出背景是黑色而不是白色..(我試圖將png轉換爲JPG) –

相關問題