I have an image of a product on a solid background that I would like to crop as close as possible to the product.
我有一个产品在坚实的背景下的形象,我想要尽可能接近产品。
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:
这给了我如下图:
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:
这给了我以下的结果:
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);