У меня есть для вас решение, но это требует немного дополнительной работы. Сначала я хотел бы использовать 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');
...и наша окончательная цифра:

Если 'imfindcircles' предоставляет вам с центром и радиусами, вы не можете выработать ограничительную рамку? Нарисуйте его на листе бумаги и сделайте второй взгляд. (Независимо от того, правильно ли работает imfindcircles на этих изображениях, это другое дело). – nkjt