我有两套不同大小的图像。第一组是具有真实图片对象的400x400像素的图像。
第二组是319x319,图像轮廓与实际图片对象的比例不同。
我想要实现的,基本上是将轮廓替换为第一组的真实图片对象(即海狸)。因此,最终结果将是具有真实图片对象的319x319分辨率图像。这是一个例子:
第一组图像不能简单地调整为319x319,因为海狸与剪影不匹配。大约有100张不同的" 海狸大小 到 海狸的轮廓尺寸 & #34;关系。有没有办法自动化这个程序?
到目前为止,我已经尝试了@cxw建议到第2步。这是我使用的EllipseDirectFit的代码。这是我的code用椭圆拟合绘制图像。我不知道如何继续执行步骤3-5 ..我想从EllipseDirectFit函数 - > 2 * abs(A(1))应该是ellipsi的主轴。 (注意:' a1.bmp'是真实的图像,而b1.bmp'是剪影)。
答案 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)
我没有这方面的代码,但这是我将如何进行,只是副手。几乎肯定有更好的方法:)。
对于每个真实图像和轮廓图像:
获取不是背景的像素的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是因为图像可能与任何颜色分量中的背景不同。
imresize
)的大小。现在它们的大小应该相同。找到中心。使用上述适合的例程,
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)
将实像数据移动到三维矩阵中,使椭圆居中 重合。例如,
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.
使用背景颜色(或黑色轮廓 - 相同的差异)作为遮罩,将经过调整大小的移动实景图像中的像素复制到轮廓图像中。
希望这有帮助!