Что это: uint8((double(weather1618) ./ maxv) .* 50);?
Этот код (почти) делает то, что я хочу, но я не понимаю, как это может быть так просто. Так может кто-нибудь, пожалуйста, объясните мне, как работает этот код?
FIY, weather1618 - это массив размером 384х384 с диапазоном от -76 до -30. И maxv имеет значение -30.
mapped_array = uint8((double(weather1618) ./ maxv) .* 50);
image(mapped_array);
И почему.*50 .*100 дают разные изображения, но. * 100. * 500. * 1000 идентичны?
Если бы я должен был сделать прямо,
image(weather1618);
Я бы получил только синее изображение.
1 ответ
Этот код (почти) делает то, что я хочу, но я не понимаю, как это может быть так просто. Так может кто-нибудь, пожалуйста, объясните мне, как работает этот код?
Обратите внимание, что подобные вопросы обычно не подходят для переполнения стека. Однако, поскольку вы сузили строку кода, которую вы не понимаете, я объясню вам.
Вы упомянули, что:
FIY,
weather1618
является массивом 384x384 с диапазоном от -76 до -30. А такжеmaxv
имеет значение -30.
Первая строка кода:
mapped_array = uint8((double(weather1618) ./ maxv) .* 50);
Вызывает следующие функции / операторы:
double
(функция) - конвертировать в двойную точность./
(оператор) - Поэлементное деление.*
(оператор) - Поэлементное умножениеunit8
(функция) - конвертировать в 8-битное целое число без знака
В чем дело:
double(weather1618)
преобразуетweather1618
от матрицы к формату с плавающей запятой двойной точности, поэтому значения матрицы теперь являются десятичными числами. В MATLAB двойное число может представлять числа в диапазоне от -1,79769e+308 до -2,22507e-308 для отрицательных значений и от 2,22507e-308 до 1,77969e + 308 для положительных значений ( источник). Вероятная причина для этого преобразования состоит в том, чтобы избежать целочисленного деления на шаге 2 (объяснено далее)../ maxv
делит каждый элемент матрицы на -30. Это перевернет знак каждого элемента матрицы и масштабирует данные с коэффициентом 1/30. Поскольку матрица была преобразована в double на предыдущем шаге, массив, полученный после деления, также будет иметь тип double и будет содержать десятичные числа..* 50
умножает каждый элемент матрицы на 50. Это позволит масштабировать данные в 50 раз. Массив, полученный после умножения, по-прежнему будет иметь тип double, как и раньше.uint8(...)
преобразует матрицу из типа double в тип uint8 ( целое число без знака), поэтому значения матрицы теперь будут в диапазоне от 0 до 255.
Вторая строка кода:
image(mapped_array);
Вызывает image
функция для отображения изображения массива, полученного на шаге 4.
Если бы я должен был сделать прямо,
image(weather1618);
Я бы получил только синее изображение.
Хорошее открытие! Причина, по которой вы видите только синее изображение, заключается в том, что image
функция по умолчанию не использует полный диапазон цветов в colormap
Таким образом, даже если информация присутствует в изображении, ее невозможно различить, поскольку она не отображается с использованием полного диапазона цветов. С другой стороны, imagesc
Функция использует полный спектр цветов по умолчанию.
Посмотрите на этот пример, который я сделал:
img = rand(50); % Random image with values from 0 to 1.
subplot(1, 2, 1); % Left plot.
image(img); % Display image from array.
colorbar; % Colorbar showing color scale.
subplot(1, 2, 2); % Right plot.
imagesc(img); % Display image with scaled colors.
colorbar; % Colorbar showing color scale.
Они оба являются одним и тем же изображением, но цветовая шкала различна (посмотрите на цветные полосы).
И почему
.*50
а также.*100
дать разные образы, но.*100
,.*500
а также.*1000
идентичны?
Потому что максимальное значение, которое uint8
Можно сохранить 255, поэтому любое значение, превышающее 255, будет усечено до 255. Поэтому умножение на 100, 500 и 1000 вообще не имеет значения, поскольку все полученные значения превышают 255.