裁剪圆形对象内的最大正方形 - Matlab

时间:2016-07-03 06:39:33

标签: image matlab image-processing geometry image-segmentation

我正试图找到一种方法从圆形物体(图像A)中裁剪出最适合它的方形。

有人可以解释/告诉我如何找到圆圈内的空白区域(图像I)的最大方形拟合参数,并根据它们裁剪原始图像中的方块(图像A)。

脚本:

A = imread('E:/CirTest/Test.jpg');
%imshow(A)
level = graythresh(A);
BW = im2bw(A,level);
%imshow(BW)
I = imfill(BW, 'holes');
imshow(I)

d = imdistline;
[centers, radii, metric] = imfindcircles(A,[1 500]);

imageCrop=imcrop(A, [BoxBottomX BoxBottomY NewX NewY]);  

enter image description here

2 个答案:

答案 0 :(得分:5)

我有一个解决方案,但它需要一些额外的工作。我首先要做的是使用imfill,但直接使用灰度图像。这样,均匀区域中的噪声像素得到相同强度的修复,因此阈值处理更容易。您仍然可以使用graythresh或Otsu的阈值处理,并在修复后的图像上执行此操作。

以下是一些可以帮助您入门的代码:

figure; % Open up a new figure

% Read in image and convert to grayscale
A = rgb2gray(imread('http://i.stack.imgur.com/vNECg.jpg'));
subplot(1,3,1); imshow(A); 
title('Original Image');

% Find the optimum threshold via Otsu
level = graythresh(A);

% Inpaint noisy areas
I = imfill(A, 'holes');
subplot(1,3,2); imshow(I);
title('Inpainted image');

% Threshold the image
BW = im2bw(I, level);
subplot(1,3,3); imshow(BW);
title('Thresholded Image');

上面的代码完成了我提到的三个操作,我们看到了这个数字:

enter image description here

请注意,阈值图像具有需要移除的边框像素,因此我们可以专注于圆形对象。您可以使用imclearborder功能删除边框像素。当我们这样做时:

% Clear off the border pixels and leave only the circular object
BW2 = imclearborder(BW);
figure; imshow(BW2);

...我们现在得到这张图片:

enter image description here

不幸的是,有一些噪声像素,但我们可以很容易地使用形态学,特别是用小圆盘结构元素打开操作来移除这些噪声像素。除了strel之外,将imopen与适当的结构元素一起使用应该有助于实现这一目的:

% Clear out noisy pixels
SE = strel('disk', 3, 0);
out = imopen(BW2, SE);
figure; imshow(out);

我们现在得到:

enter image description here

此蒙版包含我们现在需要用来裁剪原始图像的圆形对象的位置。最后一部分是使用此蒙版确定行和列位置,以找到原始图像的左上角和右下角,然后我们裁剪它:

% Find row and column locations of circular object
[row,col] = find(out);

% Find top left and bottom right corners
top_row = min(row);
top_col = min(col);
bottom_row = max(row);
bottom_col = max(col);

% Crop the image
crop = A(top_row:bottom_row, top_col:bottom_col);

% Show the cropped image 
figure; imshow(crop);

我们现在得到:

enter image description here

这并不完美,但它会让你开始。如果您想完整地复制并粘贴它并在计算机上运行,​​我们在这里:

figure; % Open up a new figure

% Read in image and convert to grayscale
A = rgb2gray(imread('http://i.stack.imgur.com/vNECg.jpg'));
subplot(2,3,1); imshow(A); 
title('Original Image');

% Find the optimum threshold via Otsu
level = graythresh(A);

% Inpaint noisy areas
I = imfill(A, 'holes');
subplot(2,3,2); imshow(I);
title('Inpainted image');

% Threshold the image
BW = im2bw(I, level);
subplot(2,3,3); imshow(BW);
title('Thresholded Image');

% Clear off the border pixels and leave only the circular object
BW2 = imclearborder(BW);
subplot(2,3,4); imshow(BW2);
title('Cleared Border Pixels');

% Clear out noisy pixels
SE = strel('disk', 3, 0);
out = imopen(BW2, SE);

% Show the final mask
subplot(2,3,5); imshow(out); 
title('Final Mask');

% Find row and column locations of circular object
[row,col] = find(out);

% Find top left and bottom right corners
top_row = min(row);
top_col = min(col);
bottom_row = max(row);
bottom_col = max(col);

% Crop the image
crop = A(top_row:bottom_row, top_col:bottom_col);

% Show the cropped image
subplot(2,3,6);
imshow(crop);
title('Cropped Image');

......我们的最终数字是:

enter image description here

答案 1 :(得分:3)

您可以使用bwdist L_inf距离(又名'chessboard')来获得与区域边缘的轴对齐距离,从而得出最大有界框的尺寸:

bw = imread('http://i.stack.imgur.com/7yCaD.png');
lb = bwlabel(bw);
reg = lb==2;  %// pick largest area
d = bwdist(~reg,'chessboard');  %// compute the axis aligned distance from boundary inward
r = max(d(:));  %// find the largest distance to boundary
[cy cx] = find(d==r,1); %// find the location most distant
boundedBox = [cx-r, cy-r, 2*r, 2*r];

结果是

figure;
imshow(bw,'border','tight');
hold on;
rectangle('Position', boundedBox, 'EdgeColor','r');

enter image description here

获得边界框后,可以使用imcrop裁剪原始图像

imageCrop = imcrop(A, boundedBox);

或者,你可以

imageCrop = A(cy + (-r:r-1), cx + (-r:r-1) );