"Вычисления, визуализация и программирование в среде MATLAB 5.x" - читать интересную книгу автора (Мартынов Н. Н., Иванов А. П.)

которые вводятся с клавиатуры в командном окне, или выполнить команду меню Edit I CopyFigure. В документ редактора Microsoft Word изображение вставля-
78 Глава 2. Визуализация результатов вычислений
ется командой его главного меню Edit | Paste. Далее вместе со всем документом это изображение можно будет распечатать на принтере.
Очень важное замечание: перед сохранением изображения в файле или в буфере обмена Windows осуществите в рамках пакета MATLAB необходимое масштабирование, то есть добейтесь необходимого физического размера картинки. После сохранения изображения в форматах растровой графики дальнейшее масштабирование осуществляется с неприемлемыми искажениями.
Итак, мы уже научились сохранять растровые изображения, соответствующие графическим окнам системы MATLAB, в буфере обмена Windows и в файлах некоторых графических форматов. Существует еще третий способ «запечатлеть на память» картинку из графического окна. Для этого достаточно вызвать функцию capture, которая позволит сохранить информацию о растровой картинке из графического окна системы MATLAB в двух числовых массивах:
[ X, тар ] = capture( 1 );
Входным параметром для функции capture является номер графического окна. Выходными значениями для функции capture являются матрица X, соответствующая матрице пикселов изображения (в ней столько же рядов, сколько пикселовых строк в изображении, и столько же столбцов, - сколько реальных пикселовых столбцов), и матрица цветов тар (три столбца в формате RGB), использованная для построения изображения. При этом каждый элемент матрицы X равен номеру одной из строк матрицы тар. Каждый элемент матрицы цветов тар представляет собой положительное число от 0 до 1 - оно характеризует интенсивность соответствующей составляющей цвета (красной, зеленой или синей). Итак, этих двух матриц достаточно для запоминания информации о цветах всех пикселов в растровом изображении.
Прежде чем продолжить детальное изучение этих матриц, кратко перечислим основные варианты их практического использования. Во-первых, располагая этими матрицами, можно записать изображение в JPEG-файлы, удобные для использования в среде Internet. Это делается вызовом функции imwrite:
imwrite( X, map, 'MyOwnName.jpg' );
Здесь создается сжатый графический файл MyOwnName.jpg, который удобен для передачи по сети Internet и предназначен для просмотра в среде браузеров типа Microsoft Internet Explorer.
Во-вторых, располагая матрицами X и тар, можно либо сразу же восстановить исходное изображение в рамках графического окна системы MATLAB, применив следующий код:
colormap( map ); image( X );
либо, предварительно обработав исходное изображение (произведя вычисления над элементами полученных функцией capture матриц), вывести в графическое окно системы MATLAB уже новое изображение.
MATLAB 5.x. Вычисления, визуализация, программирование 79
Очень важно понимать, что функция image не воссоздает всю исходную информацию, характерную для векторной графики. Она лишь формирует массив пикселов с правильными цветами, и больше ничего. Она создает объект растровой графики по имени image. Этот объект можно масштабировать, изменяя обычным образом размеры графического окна, но картинка при этом будет искажаться. Это отличительная черта растровой графики, и с этим ничего нельзя поделать. Такова природа вещей.
Теперь продолжим подробное изучение строения матриц, возвращаемых функцией capture и являющихся основой растровой графики системы MATLAB.
Еще раз напомним, что произвольное изображение на экране компьютера представляет собой массив пикселов, каждый из которых характеризуется своим цветом. Цвет пиксела определяется тремя составляющими: красным, зеленым и синим (Red, Green, Blue - RGB). Каждая составляющая цвета, как мы уже говорили выше, кодируется вещественным числом от 0 до 1. В результате на каждый пиксел расходуется по 8 х 3 = 24 байта памяти компьютера. Это очень расточительный по отношению к памяти компьютера способ хранения информации о растровых изображениях. А неэкономный расход памяти, в свою очередь, сильно понижает производительность (быстродействие).
В то же время для задания величины одной составляющей цвета пиксела достаточно 1 байта памяти (8 бит), где можно записать целые числа от 0 до 255 (всего 256 значений). Каждому пикселу экрана в таком случае будут соответствовать три целых числа в диапазоне от 0 до 255, которые займут в памяти компьютера всего лишь 3 байта памяти. Это очень значительная экономия памяти компьютера, поэтому в системе MATLAB для таких целых чисел специально создан соответствующий тип данных, обозначаемый как uint8. Под такой тип данных отводится в памяти всего 1 байт вместо 8 байт для обычных вещественных (дробных) чисел типа double.
По умолчанию любой переменной в системе MATLAB ставится в соответствие тип double независимо от числовых значений, которые вы присваиваете переменным. Например, в результате строки кода
iVarl = 128;
создается переменная с именем iVarl и типом double, которой присваивается значение 128. Для хранения такого значения достаточно 1 байта памяти, однако для переменной iVarl типа double отводится 8 байт памяти (естественно, мы здесь говорим только о собственно данных, так как помимо данных для любой переменной MATLAB отводит еще и память под вспомогательную информацию, необходимую для управлением структурой массивов, а любой объект в системе MATLAB в своем внутреннем представлении является массивом). Налицо явный перерасход памяти компьютера.
80
Глава 2. Визуализация результатов вычислений
Чтобы избежать такого перерасхода памяти, переменную нужно явно объявлять как целую, используя модификатор uint8:
iVar2 = uint8( 128 );
Так созданная переменная iVar2 считается целой переменной (а не вещественной), и под нее отводится 1 байт памяти. Такие переменные в системе MATLAB специально предназначены для хранения целых значений от 0 до 255 (с целью экономии памяти) и не предназначены для вычислений^. По-крайней мере в версии MATLAB 5.2 это еще так. В результате для фрагмента
iVar2 = iVar2 + 1;
получаем сообщение об ошибке
??? Function '+' not defined for variables of class 'uint8'.
дословно означающее, что операция «сложение» для переменных типа uint8 не определена.
Чтобы узнать, какой тип имеет та или иная переменная из рабочего пространства системы MATLAB, нужно ввести и выполнить команду whos, в результате чего в командном окне появится сообщение, из которого видно, что iVarl является массивом размера 1x1 (то есть фактически скаляром) типа double и занимает в памяти 8 байт, a iVar2 имеет тип uint8 и занимает в памяти только 1 байт (в 8 раз меньше). При этом обе переменные имеют одинаковые значения (см. рис. 2.28).
Д1Я ГА d W sgtBff!ft!f!T!T! ITAffl ff^—1M^—— File ?dit Window Help I-IDIXI
D & 1 * Ча Ш ! " ; я t-g i ?
» whos
Name Size Bytes Class
iVarl lxl 8 double array J
iVai-2 lxl 1 tiintS array
Grand total is 2 elements using 9 byte's
«1 1 in Рисунок 2.28
Воспользуемся, наконец, типом данных uint8 для экономии памяти компьютера в задаче хранения растрового изображения. Мы уже знаем, что следующий вызов функции capture:
[X,map] = capture (1)
создает матрицу X размером юхп, где m - число рядов пикселов в изображении, an- число столбцов пикселов в нем. Обычно это очень большие числа, так что
MATLAB 5.x. Вычисления, визуализация, программирование 81
количество элементов матрицы X обычно равно нескольким десяткам тысяч и более. Именно эту матрицу система MATLAB позволяет конвертировать в тип
uint8:
X = uint8 ( X - 1 );
Теперь каждый элемент матрицы X занимает только 1 байт памяти, что приводит к восьмикратной экономии памяти компьютера. Небольшой платой за такую экономию является следующая путающая пользователя деталь: элементы матрицы X по-прежнему имеют целочисленные значения, но каждое значение теперь на единицу меньше своего прежнего значения (которое было при типе double матрицы X). Таким образом, если в случае типа double у матрицы X каждый ее элемент равен номеру некоторой строки матрицы цветов тар, то в случае типа uint8 элементы матрицы X являются смещениями этих же строк от начала матрицы цветов тар и тем самым они должны быть на единицу меньше своих предыдущих значений. Действительно, для первой строки матрицы тар ее смещение от начала равно нулю, вторая строка имеет смещение 1 и т. д.
Еще раз напомним, что тип данных uint8 предназначен для хранения информации, а не для вычислений. Если требуется произвести над изображением какие-то численные преобразования, то перед этим матрицу X типа unit8 надо конвертировать в матрицу типа double
X = doublet X ) + 1;
произвести вычисления, а затем снова можно для экономии памяти превратить результат в тип uint8. Конвертация производится в обе стороны с учетом соответствующего уменьшения или увеличения элементов матрицы X на единицу. Функция image принимает в качестве аргумента оба этих типа данных и работает с ними адекватно.