Добавил:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

1-2 Моделирование / Matlab. Практический подход. Самоучитель

.pdf
Скачиваний:
765
Добавлен:
31.01.2021
Размер:
12.72 Mб
Скачать

Глава 2. Графика в Matlab

Рис. 2.46. График, на основе которого создается анимационный кадр

Рис. 2.47. Изображение, попавшее в кадр

91

Самоучитель Matlab

дится на расстоянии 100 пикселей по горизонтали и 50 пикселей по вертикали от левого нижнего угла рисунка. Обращаем внимание, что первым аргументом функции getframe() указано значение 1 – номер графического окна, на основе которого создается кадр. Для отображения картинки, записанной в кадр, используем команду image(F1.cdata), перед которой инструкцией figure создается новое графическое окно, в котором и отображается картинка. Картинка отображается с помощью функции image(). Аргументом указывается матрица изображения. Переменная кадра F1 является записью и имеет, как отмечалось, два поля – матрица изображения cdata и матрица цветовой палитры colormap. Аргументом функции image() указывается матрица изображения, ссылка на которую выполняется в "точечном синтаксисе": указывается имя записи и, через точку, имя поля. В данном случае это F1.cdata.

Далее выполняем такую последовательность команд (ввод пользователя выделен жирным шрифтом):

>>figure(1);h=gca

h =

170.0029

>>F2=getframe(h,[0 0 400 250])

F2 =

cdata: [250x400x3 uint8] colormap: []

>>figure;image(F2.cdata)

Результат представлен на рис. 2.48.

В данном случае командой figure(1) активным делается первое графическое окно, а командой h=gca создается ссылка на координатную систему первого графического объекта. Отсчет для области выделения картинки начинается от левого нижнего угла координатной системы.

Однако обычно для создания кадров анимации используется функция getframe() без аргументов. Например, выполним в рабочем документе, к уже выполненным, еще несколько команд:

>>figure(1);F3=getframe

F3 =

cdata: [343x435x3 uint8] colormap: []

>>figure;image(F3.cdata)

В результате создается кадр, представленный на рис. 2.49.

От исходного графика на рис. 2.47 данное изображение отличается, в общемто, только подписями вдоль координатных осей. На рис. 2.49 значения указаны в пикселях.

92

Глава 2. Графика в Matlab

Рис. 2.48. Второй кадр, созданный на основе графического изображения

Рис. 2.49. Кадр создается на основе всего изображения

93

Самоучитель Matlab

Как отмечалось выше, для создания анимации необходимо создать последовательность кадров (вектор, элементами которого являются кадры – структуры, которые создаются с помощью функции getframe()). Вектор с кадрами анимации указывается первым аргументом функции movie(). Вторым аргументом указывается целое число, которое определяет количество прокруток анимации, то есть сколько раз будет отображаться последовательность кадров, указанная в виде вектора первым аргументом функции movie(). Если анимацию предполагается прокручивать один раз, то второй (единичный) аргумент можно не указывать.

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

Оператор цикла начинается с ключевого слова for, после которого указывается индексная переменная, оператор присваивания и диапазон изменения этой переменной (если нужно, с шагом дискретности). После этого указываются команды, выполняемые в рамках каждого цикла. Заканчивается оператор цикла ключевым словом end. Рассмотрим следующую последовательность команд:

>>phi=0:0.01:2*pi;

>>N=100;

>>X=cos(phi);

>>Y=sin(phi);

>>for k=1:N alpha=phi-pi*k/N; r=max(0,3*cos(2*alpha)); x=r.*cos(phi); y=r.*sin(phi); area(x,y)

hold on area(X,Y) grid on axis equal

axis([-4 4 -4 4])

text(-0.8,3.5,['Frame N',num2str(k)],'FontSize',15,'Background Color',[.5 .8 .5])

F(k)=getframe; hold off

end

>> movie(F,2)

С помощью этого кода создается последовательность анимационных кадров, а затем эти кадры отображаются. На рис. 2.50-2.54 показаны некоторые из кадров анимации.

94

Глава 2. Графика в Matlab

Рис. 2.50. Первый кадр анимации

Рис. 2.51. Двадцать пятый кадр анимации

95

Самоучитель Matlab

Рис. 2.52. Пятидесятый кадр анимации

Рис. 2.53. Семьдесят пятый кадр анимации

96

Глава 2. Графика в Matlab

Рис. 2.54. Сотый кадр анимации

Таким образом, создан своеобразный вращающийся пропеллер. Рассмотрим подробнее программный код, с помощью которого создается анимация.

Командой phi=0:0.01:2*pi создается вектор значений полярного угла для дальнейшего использования при создании функциональных зависимостей. Командой N=100 определяется значение переменной-количества кадров анимации. С помощью команд X=cos(phi) и Y=sin(phi) создаются векторы узловых точек и значения функции в этих точках для окружности единичного радиуса. Эти векторы используются для отображения центральногокруганаанимационныхкадрах.Далееследуетоператорцикла.Инструкция for k=1:N в его начале означает, что индексная переменная k пробегает значения от 1 до N с шагом дискретности 1 (шаг дискретности по умолчанию). Командой alpha=phi-pi*k/N создается вектор значений полярного угла, повернутого по отношению к стандартному углу phi на величину pi*k/N против часовой стрелки. Командой r=max(0,3*cos(2*alpha))

создается вектор базовых точек для заданной в полярных координатах функции вида r(ϕ) = 3 cos(2(ϕ kπ N )) - то есть "лепесток" с поворотом. Командами x=r.*cos(phi) и y=r.*sin(phi) создаются соответствующие зависимости в декартовых координатах, а командой area(x,y) создается графическое окно с графиком, закрашенным цветом. Чтобы следующий график выводился в том же окне, используем инструкцию hold on.

97

Самоучитель Matlab

Этот следующий график (закрашенная окружность) создается командой area(X,Y). Командой grid on отображается координатная сетка. Для установки одного масштаба по координатным осям используем инструкцию axis equal, а командой axis([-4 4 -4 4]) задается диапазон значений по каждой из координатных осей. Следующая команда нужна для того, чтобы отобразить на графике текст с номером кадра. Для этого используем функцию text(). Первые два аргумента функции text() – значения координат точки на графике, определяющих место вывода текста. Третий аргумент – текстовая строка, которая выводится на графике. В данном случае это вектор, состоящий из двух элементов. Первый – текстовая строка 'Frame N'. Второй аргумент – результат преобразования числа k (индексная переменная) к текстовому формату. Для перевода числа в текст используем функцию num2str(). Далее в функции text() идут аргументы, определяющие параметры текста. Аргументы указываются в формате опция-значение. Сначала в одинарных кавычках указывается имя устанавливаемой опции (параметра) текста, а после запятой – применяемое значение для опции. Так, размер шрифта (опция FontSize) устанавливается равным 15, а цвет фона области вывода текста (опция BackgroundColor) задается в формате RGB. Для этого используется вектор из трех числовых значений (содержание красного, зеленого и синего цветов).

Командой F(k)=getframe создается кадр и записывается в качестве k-го элемента вектора F. Команда hold off нужна для того, чтобы выйти из режима удержания графики (то есть выйти из режима отображения новых графиков без замещения уже существующих). В противном случае при создании последующих кадров новая картинка накладывалась бы на уже существующую. Инструкция end свидетельствует о том, что тело оператора цикла закончилось. Наконец, посредством команды movie(F,2) анимационные кадры отображаются один за другим два раза.

Использование изображений

Мы продолжаем то, что мы уже много наделали.

В. Черномырдин

Растровое графическое изображение в Matlab – это трехмерный массив (доступ к элементам осуществляется по трем индексам). Размер по первым двум размерностям определяется количеством пикселей в изображении. Третий индекс может принимать всего три значения (1, 2 и 3). Цвет каждого пикселя в изображении определяется в формате RGB. Если изображение записано в массив A, то значение для содержания красного цвета в формате RGB для пикселя, находящегося на пересечении i-й строки и j-го столбца,

98

Глава 2. Графика в Matlab

определяется элементом A(i,j,1), для зеленого – элементом A(i,j,2), а для синего – элементом A(i,j,3) соответственно. Таким образом, растровое изображение состоит из трех двумерных матриц, каждая из которых задает содержание соответственно красного, зеленого и синего цветов.

Чтобы отобразить растровое изображение, массив, в который записано изображение, указывают аргументом функции image(). Рассмотрим следующий программный код:

>>for i=1:300 for j=1:500

A(i,j,1)=rem(i,30)/30;

A(i,j,2)=rem((i^2+j^2),200)/200;

A(i,j,3)=rem(j,50)/50;

end

end

>> image(A)

В результате создается изображение, представленное на рис. 2.55.

Рис. 2.55. Отображение созданного изображения

В данном случае изображение создается попиксельно, с помощью вложенных операторов цикла. Индексная переменная i пробегает значение от 1 до 300. Индексная переменная j пробегает значения от 1 до 500. Изображение формируется поэлементным заполнением массива A, и его размеры – 300 на

99

Самоучитель Matlab

500 пикселей. Содержание красного цвета для пикселя с координатами i и j задается командой A(i,j,1)=rem(i,30)/30, в которой использована функция rem() вычисления остатка от деления. Получаемые значения не больше нуля и не превышают единицы и чередуются через каждые 30 пикселей вдоль вертикали. Для определения содержания синего цвета используется команда A(i,j,3)=rem(j,50)/50. Значения чередуются через каждые 50 пикселей по горизонтали. Содержание зеленого цвета определяется командой A(i,j,2)=rem((i^2+j^2),200)/200. В этом случае получаются периодические структуры из серии "круги на воде". Для отображения созданной таким образом картинки используем команду image(A).

Намного чаще изображения не создаются, а считываются из файла. Для считывания графического файла используют функцию imread(). Аргументом функции указывают полное имя считываемого файла (аргумент заключается в одинарные кавычки). Результатом вызова функции является трехмерный массив растрового изображения файла. Обычно его присваивают в качестве значения какой-нибудь переменной. Рассмотрим следующий код:

>>P=imread('F:\Книги\В работе\Matlab\Docs\tiger.jpg');

>>image(P)

Командой считывается файл tiger.jpg, расположенный в каталоге F:\ Книги\В работе\Matlab\Docs. Результат записывается в переменную P. Командой image(P) считанное изображение отображается в графическом окне. Результат показан на рис. 2.56.

По умолчанию изображение масштабируется под размер графического окна. В данном случае эффект искажения изображения не заметен, поскольку пропорции в исходном изображении близки к пропорциям графического окна. Однако такое счастливое совпадение имеет место далеко не всегда. Считаем другой файл с изображением:

>>B=imread('bee.jpg');

>>image(B)

>>axis image

В частности, считывается файл bee.jpg, размещенный в рабочем каталоге Matlab (в этом случае аргументом функции imread() достаточно указать только имя файла, без полного пути к нему). Результат выполнения первых двух команд представлен на рис. 2.57.

Поскольку, в отличие от предыдущего случая, соотношение сторон для рисунка далеко от единицы, при отображении рисунка возникает значительное, видимое на глаз, искажение пропорций. Устранить его можно, воспользовавшись командой axis image. В результате окно с изображением изменится так, как показано на рис. 2.58.

100