2017-10-04 8 views
2

main.jpg(メインイメージ)と呼ばれるイメージ(白い背景に1-5の黒い点があります)があります。イメージを別のイメージの黒いピクセルに置きます

私は、メインイメージにあるすべての黒いドットに別のイメージ(secondary.jpg)を配置しようとしています。それを行うために

  1. Iが主画像の黒画素
  2. 私はすべてに
  3. プロットをイメージしたい特定のサイズに二次画像をリサイズ見出さ私は発見した座標第一歩。 (黒のピクセルは2次画像の中心座標である必要があります)

残念ながら、私は3番目の手順を実行する方法がわかりません。

主画像である:

enter image description here

二次画像である:

enter image description here

出力:

enter image description here 01例えば

(ドットは椅子の後ろにあります。

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

ここでは畳み込みのない別の方法があります。 1つの複雑さを考慮する必要があるのは、各画像を各ドットの中央に配置する場合は、左上隅がどこにあるかを判断し、出力画像にインデックスを付けて、左上から目的のオブジェクトを描画する必要がありますコーナーを右下隅に合わせます。これは、各黒のドットの位置を取って、横幅の半分と縦幅の半分を減算することによって行うことができます。

今実際の問題に。画像全体ではなく黒い点のセットをループする方がはるかに効率的です。これを行うには、findコマンドを使用して、0の行と列の位置を決定します。これを実行したら、行と列の座標の各ペアをループし、座標の減算を行い、出力イメージに置きます。

オブジェクトが重なる可能性があるという追加要件が課されます。これに対処するために、ピクセルを累積してから、ゼロ以外の場所の平均を求めます。

これに対応するように変更されたコードは次のとおりです。 JPEG圧縮を使用しているため、圧縮アーチファクトが発生するため、0の領域は必ずしも0でなくてもかまいません。また、オブジェクトがイメージの境界の外に出る場合もあります。したがって、これに対応するには、イメージを横幅の半分の2倍と縦の半分の2倍で十分にパッドし、オブジェクトの配置が完了した後に切り抜きます。

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ですが、確実にアルファチャンネルを読むことができます。次に、存在するかどうかを確認し、存在しない場合は、透明性のない値の背景が白に設定されるようにします。あなたは次のコードでそれを行うことができます。

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

あなたの画像にアルファチャンネルがあるからです。私は自分のコードを変更する必要があります。 – 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

また、あなたはおそらく、それは非可逆圧縮につながるので、.jpgとしてmain.jpgを保存しないようにしたいと可能性の高い正確なピクセル値に依存しているいずれかの方法で問題が発生します。 .pngを使用することをお勧めします。これは可逆であり、同じ色が何度も繰り返される合成画像には、.jpgよりも圧縮率が高い可能性があります。

+0

こんにちは@jodag。 私はこの画像を試しました:https://i.imgur.com/qYJSzEZ.pngそして出力背景は白ではなく黒です。(私はJPGにpngを変換しようとしました) –

関連する問題