Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Создание визуальных эффектов в режиме реального времени

Интегрирование геометрических примитивов и изображений в видеоданные с использованием EffecTV и SDL

Натан Хэррингтон, разработчик приложений, IBM
Натан Хэррингтон (Nathan Harrington) работает ведущим программистом проекта Resource Locator в IBM. Четыре года он работает с Linux и инструментальными средствами с открытым исходным кодом в целях рационализации бизнеса IBM.

Описание:  Исследуйте архитектуры EffecTV и SDL и узнайте, как использовать возможности средств видеообработки с открытым исходным кодом в Linux.

Дата:  23.04.2007
Уровень сложности:  средний
Активность:  2269 просмотров
Комментарии:  


Обработка видеоэффектов в режиме реального времени становится все более обычной в трансляциях основных спортивных событий. В NASCAR, NFL, профессиональном хоккее и других видах спорта применяются видеоэффекты реального времени, например, цветная линия первого дауна в американском футболе, основанная на точных географических данных. Продвинутые пользовательские интерфейсы и системы виртуальной реальности используют специальное аппаратное обеспечение для указания координат в 3D-пространстве с шестью степенями свободы. Эти технологии требуют инвестиций в дорогостоящую аппаратуру и специализированные программы сбора данных. Вы можете создать свою собственную систему для обработки видеоэффектов реального времени на основе простой системы слежения за перемещением и существующего программного обеспечения с открытым исходным кодом.

EffecTV - это фантастическая программа, написанная Фукучи Кентаро (Fukuchi Kentaro), которая предоставляет вам доступ к необработанным пиксельным данным, получаемым из устройства видео-захвата. Вы можете использовать эту интегрированную среду с открытым исходным кодом для модификации более чем двух дюжин эффектов или добавить свои собственные. Интегрируясь с SDL-библиотеками, EffecTV облегчает добавление ваших собственных эффектов с использованием более абстрактных интерфейсов, которые можно легко создать и интегрировать с существующим кодом.

В статье рассматриваются установка и настройка EffecTV, интеграция с API геометрических примитивов и программа простого алгоритма слежения за перемещением на компьютере с операционной системой Fedora Core V3. Вы можете использовать и другой дистрибутив Linux, поскольку программные компоненты предназначены не только для дистрибутивов Fedora. После завершения установки вы можете использовать эти основные концепции и описания архитектуры для создания ваших собственных систем виртуальной реальности, игр или интерфейсов следующего поколения.

Требования

Аппаратное обеспечение

Кроме монитора для использования EffecTV вы должны иметь три вещи:

  1. Первое требование - скоростной процессор. Код, рассматриваемый в этой статье, разрабатывался и запускался на процессоре 500-MHz Intel® Pentium® III, которого хватает для просмотра видеофильма в окне размером 320x240-пикселей. Запуск этого же кода на 2-GHz (или более быстром) Pentium 4 позволяет просматривать видеофильм в окне 800x600. Отсюда урок: более быстрый CPU дает лучшие результаты.
  2. Плата видеозахвата - это вторая важнейшая часть аппаратуры, необходимая для обработки видеоданных в режиме реального времени. Карта Hauppauge WinTV обеспечивает отличное соотношение производительности и цены, а также имеет отличную поддержку в Linux. Я использовал модель WinTV-GO PCI, которую приобрел примерно за $80 в ближайшем магазине электроники. Это самая дешевая карта видеозахвата от Hauppauge, но она удовлетворяет всем потребностям данного приложения. Вы можете найти более дорогие карты захвата и карты, которые вообще не работают с Linux. Что является абсолютным минимумом для гарантии работы вашей карты - это наличие в видеокарте набора микросхем серии Brooktree/Conexant Bt8x8. Для определения видеокарт, работающих на вашем компьютере, вы можете обратиться в раздел "Ресурсы".
  3. Последним фрагментом головоломки является камера. Я использовал видеокамеру потребительского уровня, передающую видеоданные на карту захвата видеосигнала через композитный (стандартный) видео-кабель. Вы можете использовать USB-камеру, но она определенно не обеспечивает приемлемых результатов. Исходя из моего опыта, полноэкранное видео от USB-камеры очень смазано. Тем не менее, не зависимо от имеющейся у вас камеры, если драйверы video4linux могут читать с нее, то она определенно будет работать с EffecTV, а значит подходит для целей данной статьи.

Программное обеспечение

Ваше ядро должно включать модули video4linux. Любое ядро V2.6 будет включать эти модули по умолчанию, в том числе новые версии дистрибутивов Fedora (Core V2 и выше). Если вы используете ядро более старой версии, то должны установить программное обеспечение video4linux, иначе захват видеоданных выполняться не будет. У вас также должны быть установлены SDL-библиотеки (времени исполнения и версии для разработки). Для корректной обработки эффектов в EffecTV необходима также поддержка Netwide Assembler (NASM) (компилятор языка ассемблера).

Не бойтесь! Для понимания данной статьи не нужно знание программирования на ассемблере.


Установка

Для установки EffecTV выполните следующие действия. Местонахождение каждого ресурса приведено в разделе "Ресурсы".

  1. Установите NASM. Для Fedora Core V3 вы можете найти его в fc3/disc2/Fedora/RPMS/nasm-0.98.38-3.i386.rpm.
  2. Загрузите и разархивируйте EffecTV V3.10 с SourceForge.
  3. Перейдите в каталог effectv-3.10 и выполните команду make.
  4. Включите вашу камеру.

Если вы установили все требуемое программное обеспечение, команда make должна выполниться без ошибок. Теперь вы готовы увидеть удивительные вещи, которые может делать EffecTV. В текущем каталоге выполните команду ./effectv -channel 1 и нажимайте клавишу "стрелка вверх" для прохода по эффектам. -channel 1 в данном контексте указывает вашей плате видеозахвата принимать данные с линейного входа. Ваши параметры могут быть другими в зависимости от установленной аппаратуры.

После проверки работы EffecTV давайте добавим последний пакет, который нам нужен. SDL_gfxPrimitives Андреа Шиффлера (Andreas Schiffler) является отличным API для прорисовки окружностей и линий с альфа-смешением (кроме прочего). Мы будем использовать этот код для абстрагирования от рисования линий, окружностей и битовых образов. Имеющиеся в EffecTV эффекты управляют пикселями напрямую, но мы будем использовать существующий код и модульный подход для повторного использования того, что сделано другими.

  1. Загрузите и установите SDL_gfx и SDL_gfx-devel RPMS с ferzkopp.net (см. раздел "Ресурсы").

Создание простого эффекта

Изменение архитектуры

Наш подход к повторному использованию кода (вместо прямого изменения пикселей) потребует значительного изменения архитектуры EffecTV. Мы удалим из программы все эффекты, кроме одного, и переместим изменение отображаемых пользователю пикселей в файл screen.c.

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

  1. В main.c выполните редактирование функции effectRegisterFunc и удалите все строки *Register, кроме dumbRegister.
  2. В effects/Makefile измените EFFECTS = <effect names > на просто EFFECTS = $(DUMB).
  3. В effects/Makefile удалите все записи определения объектов, за исключением DUMB = dumb.o.
  4. В effects/effects.h удалите все записи, за исключением extern effectRegisterFunc dumbRegister.

Эффект голубого круга

В качестве нашего первого простого эффекта мы нарисуем окружность с альфа-смешением (полупрозрачную) на фиксированной позиции в видеопотоке. Первый шаг - добавление функции прорисовки в файл screen.c:

  1. В screen.c добавьте '#include "SDL_gfxPrimitives.h"' в определения.
  2. Добавьте следующую функцию в конец: screen.c:

Листинг 1. Дополнение к screen.c
                
    /* добавление голубой окружности при помощи примитивов */
    void screen_draw_blue_circle( int x, int y ){
      // screen - это SDL-поверхность, которая будет выводиться операцией SDL_Flip
      filledCircleRGBA(screen, x, y, 30, 100,155,255, 150);
    }// screen_draw_circle

  1. В screen.h добавьте определение функции:
    void screen_draw_blue_circle( int x, int y );
    

Измените Makefile для корректного компилирования добавленных GFX Primitives.

  1. В Makefile измените:
  LIBS = v4lutils/libv4lutils.a -lm `sdl-config --libs` $(LIBS.extra)   

на:

  LIBS = v4lutils/libv4lutils.a -lm `sdl-config --libs` \
  $(LIBS.extra) -L/usr/lib -lSDL -lpthread -lSDL_gfx -lSDL_image

Добавьте код для прорисовки голубой окружности на изображении в позицию 50x, 50y. Добавление его в файл main.c облегчит изменение месторасположения окружности.

В main.c в функции StartTV добавьте screen_draw_blue_circle( 50, 50 ); сразу перед screen_update();.

Выполните команду make и запустите ./effectv -channel 1. Вы увидите видеоизображение с голубой окружностью в позиции 50,50. Позже мы покажем, как загрузить изображение и наложить его на видеопоток. Это полезно для добавления в ваш видеофайл границ, надписей или других типов статической информации.


Система слежения за перемещением

Алгоритм слежения за перемещением, реализованный в этом проекте, разработан упрощенным. В разделе "Ресурсы" приведены ссылки на приложения, использующие системы слежения за лицом, человеческой фигурой, геометрической фигурой, или другие типы продвинутых систем слежения и распознавания содержимого.

В нашем случае мы будем просто определять координаты ячейки пикселей, ближайшей к вершине захваченного изображения, и их изменение по сравнению с предыдущим фреймом. Из-за различных проблем цифровых камер, в том числе связанных с шумом, пиксели редко сохраняют свои точные цветовые значения между фреймами. Чтобы увидеть это явление, возьмите увеличительное стекло и попробуйте снимать вашей камерой белую поверхность. Необходимо выбирать некоторый порог для игнорирования цветовых изменений, вызванных электронным шумом. Понизьте этот порог, если ваша камера имеет более высокую цветовую устойчивость пикселей. Повысьте порог при использовании USB-камеры или при работе в зашумленной среде.

В существующей архитектуре, которую мы изменили, функция draw в dumb.c копирует область памяти с исходными пикселями в предопределенную область памяти. Мы будем использовать эту функцию для проверки каждой порции исходной области на движение.

  1. В effects/dumb.c в раздел определения функции добавьте следующее:

Листинг 2. Дополнение к effects/dumb.c
                
  /* для обнаружения движения */
  static int get_last_motion_x(void);  // возвратить последнее место движения по x
  static int get_last_motion_y(void);  // возвратить последнее место движения по y

  #define MOTION_THRESHOLD  3000000
  int last_motion_x = 0;               // последняя координата проекции  движения по x
  int last_motion_y = 0;               // последняя координата проекции  движения по y

  // пиксели предыдущего фрейма для обнаружения движения
  int previous[DEFAULT_VIDEO_HEIGHT][DEFAULT_VIDEO_WIDTH]; 

  // текущий фрейм пикселей
  int motion[DEFAULT_VIDEO_HEIGHT][DEFAULT_VIDEO_WIDTH];

  // фрагменты размером 5x5 пикселей для обнаружения движения
  // Увеличьте размер фрагмента для ускорения обработки движения за счет 
  // точности перемещения в фрейме.
  // Уменьшите размер фрагмента для точного измерения величины перемещения
  // за счет увеличения времени обработки каждого фрейма.
  int x_chunk = 5;  
  int y_chunk = 5;

  1. В effects/dumb.c для извлечения координат перемещения добавьте следующие функции:

Листинг 3. Извлечение координат перемещения
                
  int get_last_motion_x(){ 
    int newx = last_motion_x;
    last_motion_x = 0;
    return(newx);
  }
  int get_last_motion_y(){
    int newy = last_motion_y;
    last_motion_y = 0;
            
    return(newy);
  }         

  1. В effects/dumb.c измените функцию dumbRegister и добавьте следующее:
    entry->get_last_motion_x = get_last_motion_x;
    entry->get_last_motion_y = get_last_motion_y;

  1. В EffecTV.h измените _effect struct и добавьте следующее:
    int (*get_last_motion_x)(void);
    int (*get_last_motion_y)(void);

Теперь добавьте наш новый код обнаружения движения, закомментировав существующую функцию draw и добавив в effects/dumb.c следующий код:


Листинг 4. Простое обнаружение движения в draw
                
/* draw с самой верхней точкой перемещения на экране */
static int draw(RGB32 *src, RGB32 *dest){

  int highest_y = video_width;  // значение Y самой верхней точки перемещения
  int highest_x = video_height; // значение X самой верхней точки перемещения
  int x=0;  // переменные цикла
  int y;
  int i;
  int temp_cell = 0;

  // цикл по каждой строке фрейма
  for( i=0; i < video_height; i+= y_chunk ){

    // цикл по каждому столбцу фрейма
    for( x=0; x < video_width; x++ ){

      // создать ячейку данных 5x5, то есть вычислить сумму цветов всех 25 пикселей
      for( y=i; y < (i+y_chunk); y++ ){

        RGB32 pixel_value;    // временное значение цвета пикселя, color value
        pixel_value = *(src+x+y*video_width);  // текущий пиксель фрейма
        *(dest+x+y*video_width) = pixel_value; // обновить целевую поверхность
        temp_cell += pixel_value;              // увеличить сумму цвета ячейки

      }//for y

      // если ячейка 5x5 обработана
      if( x % x_chunk == 0 ){

        // вычислить среднее значение цвета ячейки 5x5
        temp_cell = temp_cell / (x_chunk * y_chunk);
        motion[i][x] = temp_cell;

        // если разница между предыдущим и текущим фреймами 
        // больше порога, значит было движение
        if( abs(previous[i][x] - motion[i][x]) > MOTION_THRESHOLD ){

          // если движение было в позиции выше любого другого записанного ранее 
          // движения - обновить текущие координаты наивысшего фрагмента
          if( i < highest_y ){
            highest_y = i;
            highest_x = x;
          }// highest x part

        }//обнаружение движения

  //перезаписать пиксели в previous для следующего фрейма, 
  //независимо от того, было ли перемещение
        previous[i][x] = motion[i][x];
        temp_cell = 0;

      }// если ячейка уже обработана

    }// for x

  }// for i
}// конец функции draw

Теперь у нас есть функция слежения за перемещением, которая выполняется для каждого фрейма поступающих видеоданных. Давайте извлечем координаты и нарисуем окружность там, где произошло движение. В main.c обновите функцию StartTV, заменив вызов функции screen_draw_blue_circle( 50,50 ) на:

    int motion_x = currentEffect->get_last_motion_x();
    int motion_y = currentEffect->get_last_motion_y();
    screen_draw_blue_circle( motion_x, motion_y);

Выполните команду make и запустите ./effectv -channel 1. Вы увидите ваше видеоизображение с нарисованной голубой окружностью в месте, где произошло движение. Перейдите в зону видимости камеры и потрясите вашей рукой. Она не отвалится.


Рисунок 1. Голубая окружность с системой слежения за перемещением
Рисунок 1. Голубая окружность с системой слежения за перемещением

Разработка интерактивной логики

Текущие возможности среды

Теперь у вас имеется рабочая среда и простой пример, позволяющий выполнить чтение фрейма видеоданных, обработать его на уровне пикселей и нарисовать что-нибудь как на SDL Surface. Все, что можно сделать с SDL Surface, вы теперь можете сделать с вашим следящим голубым кругом. Запустите 3-D SDL-библиотеки, отобразите нарисованную поверхность на плоскость, и вы можете получить полноэкранное видео с вашим 3-D миром. Добавьте распознавание некоторых специальных жестов, и вы получите начало увлекательной игры, как на PlayStation2. Следите за полноцветными объектами (например, за концом маркера) через ваш видеоинтерфейс, интегрируйте библиотеку с открытым исходным кодом Sphinx от Carnegie Mellon University (см. раздел "Ресурсы") для выполнения заклинаний на основе положения вашего маркера (волшебной палочки) и сказанного слова. Все, что можно сделать с SDL, вы можете сделать с этой интегрированной средой. Продолжайте чтение и узнаете, как создать виртуальную реальность.

Почему радуги и бабочки?

Моей первоначальной идеей была организация дуэлей на лазерных лучах между друзьями, находящимися перед камерой. Я планировал сделать снимок фона перед тем, как игроки попадают в поле зрения камеры. Неровные отверстия, взятые из этого фонового снимка, накладывались бы затем на изображения игрока, когда лазерный луч оппонента достигал бы цели. Я предусмотрел систему простых жестов (например, движение в квадранте 1 - для активизации щита, движение в квадранте 2 - для выстрела лучом) в качестве метода управления, завершающихся элементарными эффектами - пульсирующие лазерные щиты и звуковые эффекты, взятые из предыдущей практики работы с SDL. Я призываю вас развить эти мысли дальше для создания каких-либо увлекательных игр, использующих уникальные возможности видеоинтерфейса.

В то же время, я хотел создать нечто "магическое" для моей трехлетней дочери, связанное с моей работой с SDL. Лазерные лучи и дырки в теле немного не подходили для этого. Я решил сделать интерфейс, который позволил бы ей просто подойти к камере и "нарисовать" вокруг себя радуги и бабочек.


Радуги

Начнем с детального описания эффекта:

  • Если в текущем фрейме обнаружено движение, добавляем радугу между концом предыдущего участка и текущей позицией.
  • Фрагменты радуги имеют определенное время жизни, для того чтобы можно было постепенно потушить их и заменить новыми фрагментами.

Как только вы начинаете хорошо представлять, что хотите увидеть, добавление кода к существующей архитектуре станет простой задачей.

  1. Скопируйте файлы rainbow.h и rainbow.c из указанного ниже места (или загрузите весь пакет - см. раздел "Ресурсы"). Содержимое этих файлов говорит само за себя и служит просто для анимации постепенного исчезновения участка радуги и управления переменными для гарантирования корректного отображения новых компонентов.
  2. Добавьте в screen.c строку #include "rainbow.h".
  3. Добавьте в screen.c следующую функцию:

Листинг 5. Прорисовка радуги
                
void screen_draw_rainbow(){

  int i;
  // для каждого фрагмента радуги, если он на экране, получить координаты,
  // нарисовать все цветные полоски и подтвердить начало исчезновения
  for(i=0;i < =RAINBOW_PIECES;i++){
    int end_x = get_rainbow_end_x(i);
    // если end_x = -200, значит полоска не используется и не будет рисоваться
    if(   end_x != -200 ){
      int start_x = get_rainbow_start_x(i);
      int start_y = get_rainbow_start_y(i);
      int end_y = get_rainbow_end_y(i);
      int c;
      // для каждой полоски радуги, 
      for( c=0;c <=RAINBOW_SIZE;c++ ){
        int fade = get_rainbow_life(i);
        fade = fade *4;
        int r;
        int g;
        int b;
        if( c<4 ){
          r=255; g=102; b=0;    // красный
        }else if( c < 8 ){
          r= 255; g=204; b=0;   // оранжевый
        }else if( c < 12 ){
          r=255; g = 255; b=0;  // желтый
        }else if( c < 16 ){
          r=51; g=255; b=0;     // зеленый 
        }else if( c < 20 ){
          r=0; g=0; b= 255;     // синий
        }else{
          r=153; g=0; b=255;    // фиолетовый
        }
        lineRGBA(screen, start_x, start_y+c, end_x, end_y+c, r,g,b, 50+fade);
      }//for chunkiness

    }//если не фиктивная прорисовка
  }//цикл для каждого фрагмента радуги
}// screen_draw_rainbow

  1. В main.c добавьте #include "rainbow.h".
  2. В main.c замените:
    screen_draw_blue_circle( motion_x, motion_y);
    screen_update();
    

    на:
    screen_draw_rainbow();
    screen_update();
    if( motion_y != 240 ){
      add_rainbow_piece(motion_x, motion_y);
    }// если не за пределами экрана
    animate_rainbow_pieces();
    

  3. В Makefile добавьте rainbow.o к COREOBJS = main.o screen.o video.o frequencies.o palette.o.

Выполните команду make и запустите ./effectv -channel 1. Вы увидите видеоизображение с радугой, следующей за движением.


Бабочки

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

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

  1. Скопируйте butterfly.h, butterfly.c и каталог images из указанного ниже места (или загрузите весь пакет - см. раздел "Ресурсы"). Содержимое этих файлов говорит само за себя и служит просто для анимации "трепетания" бабочек (выполняя цикл по версиям одного и того же изображения с разными размерами) и перемещения их в верхнюю часть экрана путем уменьшения координаты Y.
  2. Добавьте в screen.c строку #include "butterfly.h".
  3. В screen.c добавьте #include sdl/sdl_image.h.
  4. Бабочки будут выводиться на SDL-поверхность как прозрачные битовые изображения. Я решил, что проще всего сделать это в файле screen.c.
  5. В screen.c добавьте функцию load_butterfly_anims:

Листинг 6. Прорисовка бабочки
                
void load_butterfly_anims(){

  int i=0;
  for( i=0;i <=11;i++ ){
    char filename[50] ;
    sprintf(filename, "images/bf%d.png", i);
    anims_0[i] = IMG_Load(filename);

    sprintf(filename, "images/bf%d.2.png", i);
    anims_1[i] = IMG_Load(filename);

    sprintf(filename, "images/bf%d.4.png", i);
    anims_2[i] = IMG_Load(filename);

    sprintf(filename, "images/bf%d.6.png", i);
    anims_3[i] = IMG_Load(filename);
  }// для 12 бабочек

}// load_butterfly_anims

  1. В screen.c добавьте функцию draw_butterflies:

Листинг 7. Прорисовка бабочек
                
// нарисовать бабочек
void screen_draw_butterflies(){
  int i=0;
  for(i=0; i <=MAX_BUTTERFLIES; i++){
 
    int bx = get_butterfly_x(i);
    if( bx != -200 ){
      int by = get_butterfly_y(i);
      int bf = get_butterfly_frame(i);
      screen_butterfly_animate( bx, by, i, bf );
    }

  }//цикл по i бабочкам
}//animate_butterflies

  1. В screen.c добавьте функцию draw_butterflies:

Листинг 8. Добавление draw_butterflies
                
void screen_butterfly_draw( int x, int y, int butterfly_number, int frame ){

  // нарисовать соответствующее битовое изображения для стадии анимации
  SDL_Rect src, dest;
  src.x = 0;
  src.y = 0;
  dest.x = x;
  dest.y = y;
  if( frame == 0 ){
    src.w = anims_0[butterfly_number]->w;
    src.h = anims_0[butterfly_number]->h;
    dest.w = anims_0[butterfly_number]->w;
    dest.h = anims_0[butterfly_number]->h;
    SDL_BlitSurface(anims_0[butterfly_number], &src, screen, &dest);
  }else if(  frame == 1 ){
    src.w = anims_1[butterfly_number]->w;
    src.h = anims_1[butterfly_number]->h;
    dest.w = anims_1[butterfly_number]->w;
    dest.h = anims_1[butterfly_number]->h;
    SDL_BlitSurface(anims_1[butterfly_number], &src, screen, &dest);
  }else if(  frame == 2 ){
    src.w = anims_2[butterfly_number]->w;
    src.h = anims_2[butterfly_number]->h;
    dest.w = anims_2[butterfly_number]->w;
    dest.h = anims_2[butterfly_number]->h;
    SDL_BlitSurface(anims_2[butterfly_number], &src, screen, &dest);
  }else if(  frame == 3 ){
    src.w = anims_3[butterfly_number]->w;
    src.h = anims_3[butterfly_number]->h;
    dest.w = anims_3[butterfly_number]->w;
    dest.h = anims_3[butterfly_number]->h;
    SDL_BlitSurface(anims_3[butterfly_number], &src, screen, &dest);
  }// compress animation
}// screen_butterfly_draw

  1. В screen.h добавьте следующие определения функций:

Листинг 9. Добавление к screen.h
                
void screen_draw_butterfly_bitmap( int x, int y, int butterfly_number);
void screen_butterfly_animate( int x, int y, int butterfly_number, int frame);
void screen_draw_butterflies(void);
void load_butterfly_anims(void);

  1. В main.c добавьте butterfly.h к определениям функции.
  2. В Makefile добавьте butterfly.o к COREOBJS = main.o screen.o video.o frequencies.o palette.o rainbow.o.

Выполните команду make и запустите ./effectv -channel 1. Вы увидите, что на ваше видеоизображение накладываются радуги и летают бабочки.


Рисунок 2. Радуги и бабочки с системой слежения за перемещением
Рисунок 2. Радуги и бабочки с системой слежения за перемещением

Заключение

Возможности

Имея данную интегрированную среду и пример эффектов, вы вступили на путь создания увлекательных визуальных эффектов и интерфейсов. Я призываю вас идти по UNIX®-пути и подключить существующий код и программы к этой архитектуре. Найдите наиболее элегантный способ интегрирования ваших идей, и вы преуспеете в претворении их в реальность.

Дальнейшая работа

Перечисленные ниже ресурсы охватывают много примеров проектов, в которых применяются различные интерфейсы, от виртуальной 3-D реальности до взаимодействия с публикой и простых игр. Вы можете найти идеи для слежения за объектами в видеоданных, распознавании образов, а также идеи для игр. Я надеюсь, что для создания ваших собственных видеоэффектов вам пригодятся материалы данной статьи и указанные ниже ресурсы.



Загрузка

ОписаниеИмяРазмерМетод загрузки
Sample code for this articleos-viseffects.zip278KBFTP|HTTP|Download Director

Информация о методах загрузки


Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Об авторе

Натан Хэррингтон (Nathan Harrington) работает ведущим программистом проекта Resource Locator в IBM. Четыре года он работает с Linux и инструментальными средствами с открытым исходным кодом в целях рационализации бизнеса IBM.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=211531
ArticleTitle=Создание визуальных эффектов в режиме реального времени
publish-date=04232007
author1-email=haringtn@us.ibm.com
author1-email-cc=

Теги

Help
Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Используйте ползунок, чтобы отразить больше или меньше тегов.

КнопкаПопулярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere).

Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).

Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Кнопка Популярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere). Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).