2015-08-13 4 views
2

У меня есть данные 3D-изображения, полученные из 3D-сканирования OCT. Данные могут быть представлены как I (x, y, z), что означает, что в каждом вокселе есть значение интенсивности.Градиент 3D-изображения в OpenCV

Я пишу алгоритм, который включает в себя поиск градиента изображения в направлениях x, y и z в C++. Я уже написал код на C++, используя OpenCV для 2D, и хочу расширить его до 3D с минимальными изменениями в моем существующем коде для 2D.

Я знаком с 2D-градиентами с использованием операторов Sobel or Scharr. Мой поиск привел меня к this post, ответы на которые рекомендуют ITK и Point Cloud Library. Однако эти библиотеки имеют гораздо больше функциональных возможностей, которые могут не потребоваться. Поскольку я не очень опытен с C++, эти библиотеки требуют немного чтения, и это время мне не позволяет. Более того, эти библиотеки не используют объект cv :: Mat. Если я использую что-либо другое, кроме cv :: Mat, весь код, возможно, придется изменить.

Может ли кто-нибудь помочь мне с этим, пожалуйста?

Update 1: Возможное решение с использованием ядра разделяемости

На основе @ ответ фотона, я обновляю вопрос.

Из того, что @Photon говорит, я получаю представление о том, как построить ядро ​​Sobel в 3D. Однако, даже если я построю куб 3x3x3, как его реализовать в OpenCV? Операции свертки в OpenCV с использованием filter2d предназначены только для 2D.

Может быть один способ. Поскольку ядро ​​Собела сепарабельно, это означает, что мы можем разбить трехмерную свертку на свертку в более низких размерностях. Комментарии 20 и 21 из this link также говорят то же самое. Теперь мы можем отделить 3D-ядро, но даже тогда filter2D не может использоваться, поскольку изображение все еще находится в 3D. Есть ли способ сломать изображение? Существует interesting post, который намекает на что-то вроде этого. Какие-нибудь дальнейшие идеи по этому поводу?

+1

Просто напишите свою собственную реализацию фильтра, это не так сложно. Для каждого вокселя (возможно, кроме краев, до вас) вычислите его Gx, Gy, Gz и сохраните вывод. Должно быть несколько десятков строк кода в лучшем случае. – Photon

+0

Для вычисления Gx, Gy или Gz существует 2 варианта. Один из них - перебирать все вокселы, которые были бы неэффективными. Другой способ - свертка. Но свертка с использованием filter2D возможна только с 2D-изображениями. Итак, вы имеете в виду, что я следую петлевому подходу? – Ruchir

+0

Свертка выполняет ту же самую петлю внутри. Возможно, немного более эффективно, чем вы можете сделать с первой попытки, но это в основном то же самое. Если это критически важно, вы можете позже попытаться оптимизировать использование SIMD или GPU. – Photon

ответ

1

Поскольку оператор Sobel является разделимым, легко представить, как добавить 3-мерное измерение.

Например, если вы посмотрите на определение фильтра для Gx в опубликованной вами ссылке, вы увидите, что умножает окружающие пиксели на коэффициенты, имеющие знак, зависящий от относительной позиции X, и величину по отношению к смещению в Y.

Когда вы переходите к 3D, градиент Gx должен вычисляться одинаково, но вам нужно работать с кубом 3x3x3, а знак коэффициента остается тем же самым определением, и величина теперь зависит от изменения либо Y или Z или оба.

Другие градиенты (Gy, Gz) одинаковы, но вокруг их оси.

+0

Спасибо @Photon. Я обновил свой вопрос, основываясь на вашем ответе. Давайте посмотрим, можем ли мы пойти дальше к решению. – Ruchir

Смежные вопросы