从白色背景中提取旋转的对象 [英] Extract rotated object from a white background
问题描述
我有一个带有白色背景的图像,并尝试使用MATLAB提取其中的对象。我尝试了不同的技术(有界框),但我没有得到理想的结果。我已经尝试过这个StackOverflow帖子,但它不太起作用:
我建议以下工作流程:
- 二值化图像
- 获取主对象的质心和方向
- 裁剪图像以设置中心图像中心的对象
- 相对于中心旋转对象以补偿倾斜
- 再次裁剪以获取对象
在实践中,由于阴影和不太明确的边界之间的界限,步骤1变得相当复杂。物体的白色部分和背景。我使用的技巧依赖于这样一个事实,即由于对象内部的许多细节(以及jpg压缩),它上面都有很多噪音。因此,寻找边缘与BW扩张相结合产生了非常好的二值化图像。然后我使用 regioprops
来过滤小异常值并获取对象的属性。
以下是代码:
%---加载图片
Img = imread('Tilted.jpg');
%--- Binarisation
%找到边缘和扩张以获得一个集团
BW =边缘(均值(Img,3),'sobel');
BW = imdilate(BW,strel('disk',5));
%获取BW图像
RP = regionprops(BW,'Area','PixelIdxList','Centroid','Orientation');
[〜,i] = max([RP(:)。Area]);
BW = Img(:,:,1)* 0;
BW(RP(i).PixelIdxList)= 1;
x = RP(i).Centroid(1);
y = RP(i).Centroid(2);
theta = -RP(i).Orientation;
%imshow(BW)
%plot(x + [0 500 * cos(theta * pi / 180)],y + [0 500 * sin(theta * pi / 180)]) ;
%返回
%---第一季
w = min(x-1,大小(Img,2)-x);
h = min(y-1,size(Img,1)-y);
C = Img(ceil(y-h):floor(y + h),ceil(x-w):floor(x + w),:);
%---旋转图像
R = imrotate(C,theta);
R(R == 0)= 255;
%---第二季作物
%参数(调整)
th = 70;
保证金= 25;
%删除灰度级
Rwg = std(double(R),0,3)。^ 2;
%获取x-bounds
sx = sum(Rwg,1);
x1 = max(find(sx> prctile(sx,th),1,'first') - margin,1);
x2 = min(find(sx> prctile(sx,30),1,'last')+ margin,size(Rwg,1));
%获得y-bounds
sy = sum(Rwg,2);
y1 = max(find(sy> prctile(sy,th),1,'first') - margin,1);
y2 = min(find(sy> prctile(sy,th),1,'last')+ margin,size(Rwg,1));
Res = R(y1:y2,x1:x2,:);
%---显示
imshow(Res)
当然,如果要处理许多不同的图像,这可能每次都不起作用。此代码只是一个起点,您现在必须对其进行修改以满足您的确切需求。
最佳,
I have an image with a white background and trying to extract the object within it using MATLAB. I tried different techniques (bounded box) but I am not getting desired results. I have tried this StackOverflow post but it isn't quite working: MATLAB Auto Crop
How I can extract the object? Any idea which technique is suitable?
The image is shown below:
I propose the following workflow:
- Binarize the image
- Get the centroid and orientation of the main object
- Crop the image to set the center of the object at the center of the image
- Rotate the object with respect to the center to compensate for the tilt
- Crop again to get the object
In practice, step 1 turned out to be rather complicated to perform because of the shadow and of the not-so-well-defined boundaries between the white part of the object and the background. The trick I used relies on the fact that, because of the many details inside the object (and the jpg compression) there is a lot of "noise" all over it. So looking for edges combined with a BW-dilation produced a very decent binarized image. I then used regioprops
to filter the small outliers and get the properties of the object.
Here is the code:
% --- Load image
Img = imread('Tilted.jpg');
% --- Binarisation
% Find edges and dilate to get a bloc
BW = edge(mean(Img,3),'sobel');
BW = imdilate(BW, strel('disk',5));
% Get BW image
RP = regionprops(BW, 'Area', 'PixelIdxList', 'Centroid', 'Orientation');
[~, i] = max([RP(:).Area]);
BW = Img(:,:,1)*0;
BW(RP(i).PixelIdxList) = 1;
x = RP(i).Centroid(1);
y = RP(i).Centroid(2);
theta = -RP(i).Orientation;
% imshow(BW)
% plot(x+[0 500*cos(theta*pi/180)], y+[0 500*sin(theta*pi/180)]);
% return
% --- First crop
w = min(x-1, size(Img,2)-x);
h = min(y-1, size(Img,1)-y);
C = Img(ceil(y-h):floor(y+h), ceil(x-w):floor(x+w),:);
% --- Rotate image
R = imrotate(C, theta);
R(R==0) = 255;
% --- Second crop
% Parameters (to adjust)
th = 70;
margin = 25;
% Remove grey levels
Rwg = std(double(R),0,3).^2;
% Get x-bounds
sx = sum(Rwg,1);
x1 = max(find(sx>prctile(sx,th), 1, 'first')-margin, 1);
x2 = min(find(sx>prctile(sx,30), 1, 'last')+margin, size(Rwg,1));
% Get y-bounds
sy = sum(Rwg,2);
y1 = max(find(sy>prctile(sy,th), 1, 'first')-margin, 1);
y2 = min(find(sy>prctile(sy,th), 1, 'last')+margin, size(Rwg,1));
Res = R(y1:y2, x1:x2, :);
% --- Display
imshow(Res)
Of course, if you have many different images to process this may not work every time. This code is only a starting point and you now have to modify it to meet your precise needs.
Best,
这篇关于从白色背景中提取旋转的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!