Почему требуется нормализация путем деления на 255 и другие сомнения, связанные с лог-преобразованием - PullRequest
0 голосов
/ 31 августа 2018

Вот мой код для преобразования журнала в MATLAB:

clc
clear all
image = imread('image.jpg')
imaged = double(image) / 255
new_image = log(1 + imaged)
subplot(1, 2, 1)
imshow(image)
title('Before log transformation');
subplot(1, 2, 2) 
%new_image = uint8(new_image)
imshow(new_image)
title('After log transformation');
  • Зачем нам нужно конвертировать uint8 в double? (Кажется, не работает без этого)

  • Почему нормализация делением на 255 необходима? (Я написал код ранее без такой нормализации, и он работал нормально, но здесь это неисправности)

  • Почему это дает неправильное изображение, если я конвертирую изображение обратно в uint8? (То же, что и выше, он работал нормально для другой операции. Фактически, он работал со сбоями, если я не преобразовывал обратно в uint8)

код другой операции:

clear all
close all
clc
image = imread('city.jpg');
imaged = double(image);
maxI = max(max(max(imaged)));
minI = min(min(min(imaged)));
new_image = ((imaged - minI) ./ max(imaged - minI)) * 255;
subplot(1, 2, 1)
imshow(image)
title('Before min-max transformation');
subplot(1, 2, 2) 
new_image = uint8(new_image);
imshow(new_image)
title('After min-max transformation');

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

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

Начиная с вашего первого беспокойства по поводу конвертации в double в imaged = double(image)/255. Что происходит, когда вы делите значение uint8, которое составляет от 0 до 255 на 255? Вы получите значение от 0 до 1, конечно. Но что, если выходные данные все еще равны uint8, например, потому что входной массив равен uint8? Ну, тогда значение не будет между нулем или единицей. Это будет или ноль или единица (также, конечно), и при правильной настройке динамического диапазона вы увидите чисто черно-белое изображение. Преобразование в double позволяет получить значения от нуля до единицы.

Практически все остальные ваши вопросы связаны с тем, что MATLAB понимает два формата отображаемых изображений: double s в диапазоне [0, 1] и uint8 в диапазоне [0, 255].

Ваше преобразование ожидает число в диапазоне [0, e-1], чтобы произвести вывод в диапазоне [0, 1]. Фактический логарифм оказывается за числами в диапазоне [1, 2]. Это потенциальная ошибка в вашем коде. Вы должны либо сделать

imaged = (e-1) * double(image)/255

или эквивалентно

new_image = log(1 + (e-1) * imaged)

или еще лучше

new_image = log2(1 + imaged)

Любая из этих опций предотвратит ненужное усечение динамического диапазона ввода.

Если вы все еще задаетесь вопросом, почему вам нужно нормализовать на 255, посмотрите, что происходит с 255, когда вы проходите, ненормально ли оно через преобразование.

Ваше преобразование обратно в uint8 завершается неудачей, потому что вы делаете это не так, как в «другом» коде. Другой код правильно отображает диапазон [0, 1] в [0, 255]. Ваш текущий код просто конвертирует значения. Как обсуждалось ранее, uint8 может быть только нулем или единицей, а не чем-то промежуточным.

В «другом» коде вы сначала расширили свой динамический диапазон до 255 с помощью оператора new_image = ((imaged-minI)./max(imaged-minI))*255;. Помните, что, поскольку imaged - это double, в этом случае, new_image. Однако двойные значения корректно отображаются только в диапазоне [0, 1]. После преобразования в uint8 диапазон [0, 255] станет подходящим для отображения.

0 голосов
/ 01 сентября 2018

-Почему нам нужно конвертировать uint8 в double? (Кажется, не работает без этого)

Для достижения большей точности в расчетах. Целочисленные значения имеют проблемы с делением и округлением реальных значений. Например, 5/2 - это 2. Но 5.0 / 2.0 - это 2,5.

-Почему нормализация делится на 255? (Я ранее писал код без такой нормализации, и он работал нормально, но здесь он работает неправильно)

Чтобы поместить их в диапазон 0-255, который является допустимым диапазоном для значений RGB.

-Почему это дает неправильное изображение, если я конвертирую изображение обратно в uint8? (Так же, как и выше, оно работало нормально для другой операции. На самом деле, оно работало со сбоями, если я не конвертировал обратно в uint8)

Это теряет точность. Например, 7/8 - это 0. Но 7,0 / 8,0 - это 0,875.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...