我正试图找到一种方法从圆形物体(图像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]);
答案 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');
上面的代码完成了我提到的三个操作,我们看到了这个数字:
请注意,阈值图像具有需要移除的边框像素,因此我们可以专注于圆形对象。您可以使用imclearborder
功能删除边框像素。当我们这样做时:
% Clear off the border pixels and leave only the circular object
BW2 = imclearborder(BW);
figure; imshow(BW2);
...我们现在得到这张图片:
不幸的是,有一些噪声像素,但我们可以很容易地使用形态学,特别是用小圆盘结构元素打开操作来移除这些噪声像素。除了strel
之外,将imopen
与适当的结构元素一起使用应该有助于实现这一目的:
% Clear out noisy pixels
SE = strel('disk', 3, 0);
out = imopen(BW2, SE);
figure; imshow(out);
我们现在得到:
此蒙版包含我们现在需要用来裁剪原始图像的圆形对象的位置。最后一部分是使用此蒙版确定行和列位置,以找到原始图像的左上角和右下角,然后我们裁剪它:
% 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);
我们现在得到:
这并不完美,但它会让你开始。如果您想完整地复制并粘贴它并在计算机上运行,我们在这里:
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');
......我们的最终数字是:
答案 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');
获得边界框后,可以使用imcrop
裁剪原始图像
imageCrop = imcrop(A, boundedBox);
或者,你可以
imageCrop = A(cy + (-r:r-1), cx + (-r:r-1) );