Обнаружение краев и отслеживание плавления образца - PullRequest
2 голосов
/ 24 апреля 2019

Общая проблема состоит в том, чтобы найти скорость спада поверхности плавления какого-либо материала.

Я попытался реализовать встроенные фильтры обнаружения краев для обнаружения переднего края (левая сторона на изображениях), но, поскольку этот край нечеткий, фильтр обнаруживал и многие другие края на изображении.Простой максимальный поиск интенсивности или любой производной цвета RGB также не работает.

В настоящее время мой подход заключается в том, чтобы преобразовать в ноль все цвета окружающей среды вокруг образца (темно-черный и синий) и оставить толькоцвет образца.Затем на основе производной и первого локального максимума определяют передний фронт.Проблема в том, что я не знаю, как определить этот синий и темный диапазон цветов для фильтрации.Например, яркость синего цвета перед изображением изменяется вдоль видео, и я не могу отфильтровать его на всех изображениях.

Программное обеспечение: Matlab.Набор инструментов для обработки изображений

Это не проблема в коде, это скорее концепция и способ.

1-е и последнее изображение видео:

Input 1

Успешное обнаружение края (синяя линия) последнего изображения.

Input 1

Ответы [ 2 ]

2 голосов
/ 24 апреля 2019

В ваших изображениях у вас есть три фракции: образец (желто-красный), пламя (сине-белый) и фон (темный), однако образец и пламя перекрываются в той области, где вы хотите обнаружить край. Было бы неплохо отделить пламя от образца, и очевидный подход, кажется, разделяет его как-то по цвету. Я немного поиграл, и вот что я придумал.

Во-первых, преобразуйте изображение RGB в HSV, где мы имеем в основном только один цветной канал (оттенок).

hsv = rgb2hsv(img);

оттенок является периодическим, но в вашем случае красно-желтый образец, к сожалению, близок к нулю и близок к 1.

Сдвиньте границу оттенка, чтобы облако значений пикселей в пространстве HSV не было разделено.

h = hsv(:, :, 1);
h = mod(h + 0.5,1); % shift periodically
s = hsv(:, :, 2);
v = hsv(:, :, 3);

Давайте визуализируем это.

plot3(h(:), s(:), v(:), '.');
xlabel('hue');
ylabel('saturation');
zlabel('value');

enter image description here

Пламя и образец, кажется, хорошо разделены по оттенку (и частично также по насыщенности - пламя менее насыщено, чем образец).

Найдите центры скопления для пламени, образца и фона с помощью простого определения порога. Фон - это все со значением <0,2, в то время как пламя и образец имеют значение> 0,2, а пламя имеет оттенок <0,3, оттенок образца> 0,3.

T1 = 0.3; % threshold on hue (>T1 is sample)
T2 = 0.2; % threshold on value (<T2 is background)
m = h > T1 & v > T2;
sample = [mean(h(m)), mean(s(m)), mean(v(m))];
m = h < T1 & v > T2;
flame = [mean(h(m)), mean(s(m)), mean(v(m))];
m = v < T2;
background = [mean(h(m)), mean(s(m)), mean(v(m))];
C = [sample; flame; background];

Давайте посмотрим на средние векторы для образца, пламени и фона в пространстве ВПГ.

  C = 
  0.55004      0.63657      0.79573
  0.23729      0.50927      0.50652
  0.42501      0.50855     0.085589

Теперь самое интересное. Давайте выразим изображение по пикселям как линейную комбинацию этих трех элементов.

Y = [h(:), s(:), v(:)];
x = max(Y / C, 0);
x = reshape(x, size(img));

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

Давайте визуализируем это.

figure;
labels = {'sample', 'flame', 'background'};
for i = 1 : 3
    subplot(1,3,i);
    imagesc(x(:, :, i));
    axis image;
    title(labels{i});
end
colormap(gray);

enter image description here

Образец перекрытия и пламя были разделены (но перед дальнейшей обработкой требуется некоторое сглаживание). Видны некоторые артефакты сжатия JPEG, что несколько снизит точность результатов. Найдем ребра разделенного образца.

sample = imgaussfilt(x(:, :, 1), 3);
e = bwareafilt(edge(sample), 1);

Здесь дополнительно был сохранен только самый длинный край. Можно также использовать область пламени в качестве индикатора переднего края.

Давайте визуализируем исходное изображение вместе с обнаруженным краем.

figure;
[x, y] = ind2sub(size(e), find(e));
imshow(img);
hold on;
plot(y, x, 'g.', 'MarkerSize', 2);

enter image description here

Что выглядит разумно.

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

enter image description here

Как итог:

Пламя и образец были разделены по цвету (оттенок), затем на отделенный образец было применено общее обнаружение края. Пламя можно использовать как указание на интересную область для переднего края. Есть некоторые внутренние параметры в разделении (пороговые значения), а также в обнаружении краев (сглаживание, пороговые значения), которые необходимо настроить.

0 голосов
/ 24 апреля 2019

Полагаю, что вы можете получить разумно повторяемые результаты, бинаризовав красный компонент изображения.

enter image description here

...