2016-02-28 99 views
1

我有兩組不同大小的圖像集合。第一組是具有真實圖像對象的400×400像素的圖像。縮放圖像對象以匹配另一個對象的比例

enter image description here

第二組是319x319,具有不同規模的圖像輪廓比所述真實畫面對象。

enter image description here

我想達到的目標,基本上是有由第一組的真實畫面對象(即海狸)取代了輪廓。所以最終的結果將是具有真實圖像對象的319x319分辨率圖像。下面是一個例子:

example of the desired result

第一組圖像不能簡單地調整爲319x319,由於海狸將不匹配的輪廓。有大約100個不同的圖像「海狸大小海狸的輪廓大小」關係。有沒有辦法讓這個程序自動化?

到目前爲止,我已經嘗試@ cxw建議到步驟2.以下是我使用的代碼EllipseDirectFit。這裏是我的code繪製橢圓擬合的圖像。我不知道如何進行步驟3-5 ..我認爲從EllipseDirectFit函數 - > 2 * abs(A(1))應該是ellipsi的主軸。 (注意:'a1.bmp'是真實圖像,'b1.bmp'是剪影)。

+1

您是否總是擁有像真實圖像或輪廓之外的問題中展現的平色背景? – cxw

+0

yes對於真實圖像和剪影都是平坦的顏色背景 – yannovios

回答

1

如果其他人遇到同樣的問題,我發佈解決我的問題的代碼。實際上,我遵循cxw的建議,併爲真實和輪廓圖片擬合了一個橢圓,然後根據輪廓 - 橢圓的長軸與實際橢圓長軸的比例調整了實際圖片的大小。這使得圖像對象的尺寸與輪廓圖像對象(即海狸)相匹配。然後我裁剪或添加邊框像素以匹配我需要的分辨率(即319x319)。

% fetching the images 
realList = getAllFiles('./real_images'); % getAllFiles => StackOverflow function 
silhList = getAllFiles('./silhouettes'); 

for qq = 1:numel(realList) 
    % Name of the file to save 
    str = realList{qq}(15:end); 

    a = imread(realList{qq}); % assign real image 
    background_Ra = a(1,1,1); % getting the background colors 
    background_Ga = a(1,1,2); 
    background_Ba = a(1,1,3); 
    % finding the points (x,y) to pass to fit_ellipse 
    [x1,y1]=find(a(:,:,1)~=background_Ra | a(:,:,2)~=background_Ga | a(:,:,3)~=background_Ba); 
    % fitting an ellipse to these points 
    z1 = fit_ellipse(x1,y1); % Mathworks file exchange function 

    b = imread(silhList{qq}); % assign silhouette image 
    background_R2b = b(1,1,1); % getting the background colors 
    background_G2b = b(1,1,2); 
    background_B2b = b(1,1,3); 
    % finding the points (x,y) to pass to fit_ellipse 
    [x2,y2]=find(b(:,:,1)~=background_R2b & b(:,:,2)~=background_G2b & b(:,:,3)~=background_B2b); 
    % fitting an ellipse to these points 
    z2 = fit_ellipse(x2,y2); 

    % ratio of silhouette's ellipse major axis to real image's ellipse 
    % major axis 
    ellaxratio = z2.long_axis/z1.long_axis; 
    % resizing based on ellaxratio, so that the real image object size will 
    % now fit the silhouette's image object size 
    c = imresize(a,ellaxratio); c = rgb2gray(c); 
    bordercolor = c(end,end); 

    % if the resulting image is smaller, add pixels around it until they 
    % match with the silhouette image resolution 
    if size(c) < 319 
     while size(c) < 319 
      % 'addborder' is a Mathworks file exchange function 
      c = addborder(c(:,:,1),1, bordercolor ,'outer'); 
     end 
    % if the resulting image is larger, crop pixels until they match 
    else size(c) > 319 
     while size(c) > 319 
      c = c(2:end-1,2:end-1); 
     end 
    end 

    % in a few cases, the resulting resolution is 318x318, instead of 
    % 319x319, so a small adjustment won't hurt. 
    if size(c) ~= 319 
     c = imresize(c,[319 319]); 
    end 
    % saving.. 
    imwrite(c,['./good_fits/' str '.bmp']) 
end 
1

我沒有這方面的代碼,但這裏是我如何繼續,只是副手。幾乎肯定有更好的方法:)。

  1. 對於每一個真實的圖像和輪廓圖像的:

    1. 獲取X,Y座標是背景像素。 編輯實施例中八度測試:

      background_R = img(1,1,1) 
      background_G = img(1,1,2) 
      background_B = img(1,1,3) 
      
      [xs,ys]=find(img(:,:,1)~=background_R | img(:,:,2)~=background_G | img(:,:,3)~=background_B) 
      

      邏輯OR是因爲圖像可以以任何顏色分量的背景不同。

    2. 將橢圓擬合到您找到的X,Y座標對上。例如,使用來自File Exchange的this routine。 (其實,我想你可以使用圓形適合或任何其他適合你想要的形狀,只要尺寸和位置是圖像的非背景部分之間的唯一區別。)
  2. 現在你有橢圓真實圖像和輪廓圖像的參數。假設縱橫比相同,那些橢圓只應在中心和比例上有所不同。
  3. 根據輪廓橢圓長軸長度與實像橢圓長軸長度之比調整實像(imresize)的大小。現在他們應該是相同的大小。
  4. 查找中心。使用上述配合例程,

    A=EllipseDirectFit(...) 
    % switch to Mathworld notation from http://mathworld.wolfram.com/Ellipse.html 
    ma=A(1); mb=A(2)/2; mc=A(3); md=A(4)/2; mf=A(5)/2; mg=A(6); 
    center_x = (mc*md-mb*mf)/(mb**2-ma*mc) 
    center_y = (ma*mf-mb*md)/(mb**2-ma*mc) 
    
  5. 移動真實圖像數據在3-d矩陣,使得橢圓中心 重合。例如,

    cx_silhouette = ... (as above, for the silhouette image) 
    cy_silhouette = ... 
    cx_real = ... (as above, for the *resized* real image) 
    cy_real = ... 
    shifted = zeros(size(silhouette_image)) % where we're going to put the real image 
    deltax = cx_silhouette - cx_real 
    deltay = cy_silhouette - cy_real 
    % if deltax==deltay==0, you're done with this step. If not: 
    portion = resized_real_image(max(deltay,0):319-abs(deltay), max(deltax,0):319-abs(deltax), :); % or something like that - grab the overlapping part of the resized real image 
    shifted(max(deltay,0):min(deltay+319,319), max(deltax,0):min(deltax+319,319), :) = portion; % or something like that - slide the portion of the resized real image in x and y. Now _shifted_ should line up with the silhouette image. 
    
  6. 使用的背景顏色(或黑色輪廓—相同差)作爲掩模,複製像素從調整大小,移動實像到輪廓圖像。

希望這有助於!

+0

我嘗試了擬合橢圓或圓形,但它們總是捕捉圖像的內部部分(即使是平面內部的輪廓)..:/ – yannovios

+0

Sure , 這就說得通了。問題是他們是否抓住了圖像的內部部分。由於擬合只涉及X和Y值,而不是像素值,因此無論圖像大小或圖像大小如何,您所得到的橢圓都應該覆蓋輪廓的相同部分(而不一定是整體)。那有意義嗎?如果您願意,我會很高興 - 如果您願意,請更新問題以包含您的代碼,以及疊加在圖像上的擬合橢圓的一些屏幕截圖。 – cxw

+0

這是我使用的[EllipseDirectFit](http://pastebin.com/VGkniMbE)的代碼。這裏是我的[代碼](http://pastebin.com/F7j0N5Dp)用橢圓擬合來繪製圖像。我不知道如何繼續你的步驟3-5 ..我認爲從EllipseDirectFit函數 - > 2 * abs(A(1))應該是ellipsi的主軸。那是對的嗎?順便說一句,a1.bmp是真實的圖像和b1.bmp是剪影就像我原來的帖子。 – yannovios