Реализация кода MATLAB в Java — инвариант освещения

У меня есть следующий код, написанный в MATLAB, взятый из этот документ на странице 3:

function [ ii_image ] = RGB2IlluminationInvariant( image, alpha )
ii_image = 0.5 + log(image(:,:,2)) - alpha*log(image(:,:,3)) - (1-alpha)*log(image(:,:,1));

Этот код должен преобразовывать 3-канальное изображение RGB в его инвариант освещения. Я хотел бы знать, что делает код, чтобы реализовать его на Java.

Из того, что я могу собрать, он вычисляет логарифм каждого красного/зеленого/синего пикселя и вычитает значения друг из друга, но результат не является целым числом, поэтому я не могу применить его к классу Java BufferedImage при изменении значения RGB. Как я могу эмулировать эту функцию в Java?

если значения изображения находятся в диапазоне от 0 до 1, вы все равно можете сохранить его в BufferedImage, поскольку вы можете создать новое значение цвета, используя new Color(0.1,0.2,0.3). Если вы хотите использовать оптимизированную библиотеку, взгляните на JavaCV (обертка opencv) здесь github.com/bytedeco/javacv

user8190410 29.05.2019 20:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
108
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете найти множество матричных библиотек на Java в соответствии с здесь. Я предлагаю вам выбрать EJML, чтобы преобразовать вашу логику в Java.

Ответ принят как подходящий

Не так уж сложно преобразовать функцию в JAVA.
Следующий пример кода представляет собой реализацию MATLAB, которую можно легко преобразовать в JAVA.

Следует обратить внимание на диапазон и тип входных и выходных элементов, а также на порядок памяти.

Прочитайте комментарии в следующем коде:

%function [ ii_image ] = RGB2IlluminationInvariant( image, alpha )

%Initialize input (for executing the example):
image = imread('peppers.png');
image = max(image, 1); %Replace zero values with 1, because log(0) is -Inf
image = double(image)/255; %Convert image to double in range [1/255, 1]. In JAVA, you should use double(pix)/255 if pix is a byte in range [0, 255].
alpha = 0.9;

ii_image = 0.5 + log(image(:,:,2)) - alpha*log(image(:,:,3)) - (1-alpha)*log(image(:,:,1));

%Assume elements in JAVA are stored in three 2D arrays (3 planes): R, G, B
%For example: double[][] R = new double[384][512];
%In Matlab 3 planes are:
R = image(:,:,1);
G = image(:,:,2);
B = image(:,:,3);
%II_image = 0.5 + log(G) - alpha*log(B) - (1-alpha)*log(R);
II_image = zeros(size(R));

%Equivalent for loop (simple to implement in JAVA):
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
image_width = size(image, 2);
image_height = size(image, 1);
for y = 1:image_height %Iterate rows, In JAVA: for(y = 0; y < image_height; y++)
    for x = 1:image_width %Iterate columns, In JAVA: for(x = 0; x < image_width; x++)
        r = R(y, x); %In JAVA: double r = R[y][x];
        g = G(y, x);
        b = B(y, x);

        p = 0.5 + log(g) - alpha*log(b) - (1.0-alpha)*log(r);

        II_image(y, x) = p;
    end
end

%Display ii_image
figure;imshow(ii_image, []);impixelinfo;title('ii\_image');

%Show difference (for debugging):
%figure;imshow(ii_image - II_image, []);impixelinfo

%Display minimum and maximum - values are not valid as pixel values in JAVA.
disp(['min(ii_image) = ', num2str(min(ii_image(:)))]);
disp(['max(ii_image) = ', num2str(max(ii_image(:)))]);


%Convert II_image range to [0, 1]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Find minimum and maximum (in JAVA you can do it inside the loop).
lo = min(II_image(:));
hi = max(II_image(:));

%Apply linear transformation:
II_image = (II_image - lo) / (hi - lo);

figure;imshow(II_image, []);impixelinfo;title('II\_image');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Я надеюсь, что это поможет вам в реализации JAVA.

Спасибо за ответ. Я близок к завершению, но некоторые вычисления для p не находятся в диапазоне [0,1]. Некоторые числа отрицательны или больше 1. Я получаю значение R, G, B каждого пикселя и делю каждый пиксель R, G, B на 255, убедившись, что оно не равно нулю. Затем я делаю расчет журнала, но он не находится в правильном диапазоне. Вы знаете, в чем может быть проблема?

Shan 30.05.2019 17:18

У вас установлен МАТЛАБ? Вы можете выполнить код MATLAB и увидеть результат.

Rotem 30.05.2019 17:23

Я получаю: min(ii_image) = -2.4237 и max(ii_image) = 5.2882. Нет никакой гарантии, что результаты вычислений будут в допустимом диапазоне.

Rotem 30.05.2019 17:27

Да, код работает в MATLAB, и диапазоны для моих тестовых изображений совпадают. Когда я делаю это на Java, я не могу использовать результат для установки значения RGB, потому что он не находится между [0,1]. Есть ли способ преобразовать эти числа в диапазон [0,1]?

Shan 30.05.2019 17:32

Добавил пример: найти минимум и максимум, и из каждого элемента: вычесть минимум и разделить на (максимум - минимум).

Rotem 30.05.2019 17:41

Реализуйте его в новом цикле (когда вы знаете минимум и максимум).

Rotem 30.05.2019 17:44

Другие вопросы по теме