Matlab从图像中裁剪多边形。

时间:2022-11-14 13:08:21

I have an image of a product on a solid background that I would like to crop as close as possible to the product.

我有一个产品在坚实的背景下的形象,我想要尽可能接近产品。

Matlab从图像中裁剪多边形。

I brighten it and find the edges with the following code:

我用下面的代码点亮它并找到它的边缘:

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

Which give me the following image:

这给了我如下图:

Matlab从图像中裁剪多边形。

The following code gives me rectangles on every blob/line detected:

下面的代码给我在每个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

I'm able to then draw a bounding rectangle and crop with all these points collected with the following code:

然后,我可以画出一个边界矩形和裁剪,所有这些点都是用下面的代码收集的:

% 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);

Which gives me the following result:

这给了我以下的结果:

Matlab从图像中裁剪多边形。

My question is how can I get a polygon as close as possible to the product and crop it with the polygon or, alternatively, just crop as close as possible to the product and its cap?

我的问题是,我怎样才能使一个多边形尽可能接近产品,并将其与多边形或,或者,仅仅是尽可能接近产品和它的帽子?

2 个解决方案

#1


0  

If you don't want to get a bounding box but a polygon, I think you need to generate a mask - a matrix with the same size of your image, value 1 if the pixel in on your object, 0 if not.

如果你不想得到一个边界框,但是一个多边形,我认为你需要生成一个掩码——一个与你的图像大小相同的矩阵,如果在你的对象上的像素值为1,如果不是,则为1。

I heard about an algorithm (sorry I can't find the name, I'll edit this post if I find it) which works with a lasso :

我听说过一个算法(不好意思,我找不到这个名字,如果找到了,我会编辑这篇文章)。

  • step 0 : your lasso is your bounding box.
  • 第0步:你的套索是你的包围盒。
  • step i : segment the lasso and for each part, you retract it if the color (or any other) gradient in the image is less than a fixed value.
  • 步骤i:将套索分割成段,如果图像中的颜色(或其他)梯度小于固定值,就会收回。
  • step n (last) : you cannot retract any part of the lasso, it is finished. Inside your lasso : your object. Outside : the background.
  • 步骤n(最后):你不能收回套索的任何部分,它完成了。在你的套索里:你的目标。外:背景。

As I remember there is a lot of work with this method : the definition of the lasso, the retractation step, the solidity of your lasso (to avoid too much deformation of the lasso).

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

Beside the lasso method you can search about the watershed transform, it can also work with your problem.

除了拉索方法,你可以搜索分水岭变换,它也可以解决你的问题。

Finally, if you generate the pictures, take shots with a plained background (green, pink, blue, etc) and use a simple chromakey.

最后,如果你生成了图片,你可以拍一些背景色(绿色、粉色、蓝色等),然后使用简单的颜色。

#2


0  

Using active contours also looks like a good approach but getting a nice mask is troublesome.

使用主动轮廓看起来也是一个不错的方法,但是得到一个漂亮的面具是很麻烦的。

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);

#1


0  

If you don't want to get a bounding box but a polygon, I think you need to generate a mask - a matrix with the same size of your image, value 1 if the pixel in on your object, 0 if not.

如果你不想得到一个边界框,但是一个多边形,我认为你需要生成一个掩码——一个与你的图像大小相同的矩阵,如果在你的对象上的像素值为1,如果不是,则为1。

I heard about an algorithm (sorry I can't find the name, I'll edit this post if I find it) which works with a lasso :

我听说过一个算法(不好意思,我找不到这个名字,如果找到了,我会编辑这篇文章)。

  • step 0 : your lasso is your bounding box.
  • 第0步:你的套索是你的包围盒。
  • step i : segment the lasso and for each part, you retract it if the color (or any other) gradient in the image is less than a fixed value.
  • 步骤i:将套索分割成段,如果图像中的颜色(或其他)梯度小于固定值,就会收回。
  • step n (last) : you cannot retract any part of the lasso, it is finished. Inside your lasso : your object. Outside : the background.
  • 步骤n(最后):你不能收回套索的任何部分,它完成了。在你的套索里:你的目标。外:背景。

As I remember there is a lot of work with this method : the definition of the lasso, the retractation step, the solidity of your lasso (to avoid too much deformation of the lasso).

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

Beside the lasso method you can search about the watershed transform, it can also work with your problem.

除了拉索方法,你可以搜索分水岭变换,它也可以解决你的问题。

Finally, if you generate the pictures, take shots with a plained background (green, pink, blue, etc) and use a simple chromakey.

最后,如果你生成了图片,你可以拍一些背景色(绿色、粉色、蓝色等),然后使用简单的颜色。

#2


0  

Using active contours also looks like a good approach but getting a nice mask is troublesome.

使用主动轮廓看起来也是一个不错的方法,但是得到一个漂亮的面具是很麻烦的。

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);