Matlab从图像中裁剪多边形

时间:2014-06-13 08:06:47

标签: matlab polygon crop bounding-box

我在纯色背景上有一张产品图片,我希望尽可能接近产品。

Original

我照亮它并使用以下代码找到边缘:

limits = stretchlim(original, 0.01);
img1 = imadjust(original, limits, []);

img = rgb2gray(img1);

BW = edge(img,'canny',0.2);

[B,L,N,A] = bwboundaries(BW);
figure; imshow(BW); hold on;
for k=1:length(B),
    if(~sum(A(k,:)))
       boundary = B{k};
     plot(boundary(:,2),boundary(:,1),'r','LineWidth',2);hold on;
    end
end

这给了我以下图片:

EdgeDetected

以下代码为我检测到的每个blob /行提供了矩形:

blobMeasurements = regionprops(logical(BW), 'BoundingBox');
numberOfBlobs = size(blobMeasurements, 1);

rectCollection = [];
for k = 1 : numberOfBlobs % Loop through all blobs.
rects = blobMeasurements(k).BoundingBox; % Get list ofpixels in current blob.
x1 = rects(1);
y1 = rects(2);
x2 = x1 + rects(3);
y2 = y1 + rects(4);
x = [x1 x2 x2 x1 x1];
y = [y1 y1 y2 y2 y1];
rectCollection(k,:,:,:) = [x1; y1; x2; y2];
end

我能够绘制一个边界矩形并使用以下代码收集所有这些点:

% get min max
xmin=min(rectCollection(:,1))-1;
ymin=min(rectCollection(:,2))-1;
xmax=max(rectCollection(:,3))+1;
ymax=max(rectCollection(:,4))+1;

% define outer rect:
outer_rect=[xmin ymin xmax-xmin ymax-ymin];

crop = imcrop(original,outer_rect);

这给了我以下结果:

Result

我的问题是如何让多边形尽可能接近产品并用多边形裁剪,或者只是尽可能地靠近产品及其顶盖裁剪?

2 个答案:

答案 0 :(得分:0)

如果你不想得到一个边界框而是一个多边形,我认为你需要生成一个蒙版 - 一个与你的图像大小相同的矩阵,如果对象上有像素,则值为1,否则为0

我听说过一个算法(对不起,我找不到这个名字,如果我发现的话,我会编辑这个帖子),这个算法适用于套索:

  • 第0步:你的套索是你的边界框。
  • 步骤i:对套索进行分段,如果图像中的颜色(或任何其他)渐变小于固定值,则对其进行缩回。
  • 步骤n(最后):你不能收回套索的任何部分,它已经完成。你的套索里面:你的对象。外面:背景。

我记得这个方法有很多工作:套索的定义,收缩步骤,套索的坚固性(避免套索过度变形)。

除了套索方法,您可以搜索watershed transform,它也可以解决您的问题。

最后,如果您生成图片,请拍摄背景为绿色,粉红色,蓝色等的照片并使用简单的chromakey

答案 1 :(得分:0)

使用活动轮廓看起来也是一个很好的方法但是获得一个好的面具很麻烦。

original = imread('1.jpg');
level = graythresh(original);
img = rgb2gray(original);
mask = im2bw(img,level+0.1);

mask = imfill(~mask,'holes');

bw = activecontour(img,mask);

rows = numel(original(:,1,1));
columns = numel(original(1,:,1));

for i = 1:rows
    for j = 1:columns
        if (  bw(i,j,1) == 0 )
            original(i,j,:) = 255;
         end
    end
end

imshow(original);