Matlab: Как устранить черный фон и сохранить интересующую область в моем изображении? - PullRequest
2 голосов
/ 22 апреля 2011

У меня есть следующее ИК (инфракрасное) изображение человеческого кулака, сделанное веб-камерой, преобразованной для работы в ИК.На снимке запечатлены вены под кожей.Что я хочу сделать, так это просто сохранить кулак и избавиться от окружающей черной области.Как мне сделать это в MATLAB?

enter image description here

Вот что я сделал до сих пор, но я просто получаю черное изображение для этого

a=imread('1.jpg'); 
figure; imshow(a); 
b=rgb2gray(a); 
figure; 
imshow(b); 
[j,k]=size(b); 
for g=1:j 
for f=1:k 
if b(j,k)>0.06 
c(j,k)=0; 
else c(j,k)=1; 
end 
end
 end 
figure,imshow(c);

Может кто-нибудь сказать, пожалуйста, чтоЯ делаю неправильно, и как мне добиться того, чего я хочу?Также, когда я имею в виду, что хочу избавиться от фона, я имею в виду, что я хочу белый фон вместо черного> Потому что цель этого проекта - сохранить только вены, вены будут сохранены как черные.и тогда я возьму координаты этих точек. Так что я не хочу, чтобы фон также генерировался как координаты ...!Так что я хочу фон как белый ..!как это сделать?

Ответы [ 2 ]

3 голосов
/ 23 апреля 2011

То, что вы хотите сделать, называется сегментация и является большой темой в обработке изображений.Ваше изображение довольно хорошее, поэтому, если у вас есть набор инструментов для обработки изображений, это довольно просто.И даже если вы этого не сделаете, все равно это не так сложно.

Как упоминает Крис, вы должны преобразовать свое изображение в двойное, прежде чем что-либо делать с ним.Если у вас есть набор инструментов для обработки изображений, вы можете использовать функцию graythresh , чтобы найти лучший пороговый уровень.Обратите внимание, что вам не нужно использовать циклы для выполнения пороговых значений, в MATLAB вы можете портировать всю матрицу в одну строку.

b = im2double(b);              %convert to double
thresh_level = graythresh(b);  %find best threshold level
c = b > thresh_level;          %do thresholding
imshow(c)

segmented image

Это дает вамбинарное изображение, где ваш кулак имеет значение 1 и фоновую метку 0. Чтобы сохранить кулак таким, какой он был, мы умножаем бинарную версию на исходную версию.Теперь весь фон равен нулю, и кулак сохраняет свои исходные значения.

d = im2double(c).*b;           %c is binary, so we need to convert it first
imshow(d,[])

fist

Если у вас нет набора инструментов для обработки изображений, вам нужно выбрать пороговый уровеньвручную.Это может быть немного сложно.Вы использовали 0,06, но Graythresh предполагает, что 0,2980 является лучшим.Я считаю, что хороший способ найти пороговое значение - взглянуть на гистограмму изображения.

hist(b(:),256);

histogram

Из гистограммы ясно видно, что у нас есть двакластеры точек и что любое значение от 2 до 3 будет хорошо разделять кластеры.Таким образом, мы должны использовать значение в этом интервале, чтобы сделать пороговое значение.

1 голос
/ 23 апреля 2011

пару проблем вижу:

В вашем коде вы используете g и f в качестве счетчиков циклов, но вы всегда получаете доступ к массиву b как b (j, k).

Кроме того, imread читает uint8, так что вы не можете сравнить это с двойным (0,06). Так что конвертируйте в двойное число с помощью:

b=im2double(b);

Кроме того, в этом случае нет ничего сложного, но вы динамически растете с каждой итерацией цикла. Если изображение большого размера, это значительно ухудшит производительность вашего кода. За выделение его через:

c=ones(j,k);

После этих изменений он производит нечто похожее на ваш кулак. Однако, поскольку фон не является однородным цветом, он работает не слишком хорошо. Эта часть находится за пределами моего опыта ...

...