缩放图像对象以匹配另一个对象的缩放比例

时间:2016-02-28 20:01:21

标签: image matlab image-processing

我有两套不同大小的图像。第一组是具有真实图片对象的400x400像素的图像。

enter image description here

第二组是319x319,图像轮廓与实际图片对象的比例不同。

enter image description here

我想要实现的,基本上是将轮廓替换为第一组的真实图片对象(即海狸)。因此,最终结果将是具有真实图片对象的319x319分辨率图像。这是一个例子:

example of the desired result

第一组图像不能简单地调整为319x319,因为海狸与剪影不匹配。大约有100张不同的" 海狸大小 海狸的轮廓尺寸 & #34;关系。有没有办法自动化这个程序?

到目前为止,我已经尝试了@cxw建议到第2步。这是我使用的EllipseDirectFit的代码。这是我的code用椭圆拟合绘制图像。我不知道如何继续执行步骤3-5 ..我想从EllipseDirectFit函数 - > 2 * abs(A(1))应该是ellipsi的主轴。 (注意:' a1.bmp'是真实的图像,而b1.bmp'是剪影)。

2 个答案:

答案 0 :(得分:2)

如果其他人遇到与我相同的问题,我会发布解决我问题的代码。我实际上遵循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. 对于每个真实图像和轮廓图像:

    1. 获取不是背景的像素的X,Y坐标。 修改在Octave中测试的示例:

      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. 将实像数据移动到三维矩阵中,使椭圆居中 重合。例如,

    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. 使用背景颜色(或黑色轮廓 - 相同的差异)作为遮罩,将经过调整大小的移动实景图像中的像素复制到轮廓图像中。

  7. 希望这有帮助!