Конференция "Media" » Обработка видеосигнала [D7, WinXP]
 
  • BREND © (06.10.08 15:02) [0]
    Помогите решить проблему:
    Есть видео файл. Нужно написать программу для обработки шумов в видео.
    Вот например - через такую функцию:
    -----------------

    type
     TVector = array of Double;   // Представление данных для процедур модуля

    // Удаление шума из сигнала с использованием вейвлет-преобразования.
    // Функция выполняет разложение исходного сигнала Signal с использованием
    // вейвлета Mode порядка Order. Возвращаемое значение - сигнал,
    // восстановленный по коэффициентам аппроксимации на уровне Level.
    function Denoise(
     const Signal: TVector; // Исходный сигнал
     const Mode: Integer;   // Тип вейвлета
     const Order: Integer;  // Порядок вейвлета
     const Level: Integer   // Глубина разложения
     ): TVector;            // Обработанный сигнал
     overload;


    Проблема в том, что я не знаю как мне представить видеосигнал через array of double?
    А затем еще и наоборот???
    Все что я нашел - это вывод видео через Directshow, и то в несколько строк ((
  • Сергей М. © (06.10.08 15:07) [1]

    > Все что я нашел - это вывод видео через Directshow


    Ну так и напиши свой DS-фильтр, в чем проблема ?
  • BREND © (07.10.08 10:54) [2]
    Знал бы как ни спрашивал бы.

    Я нашел что можно использовать Avifile API и Directshow.
    Еще вроде есть VFW.
    Но конркетного примера нет.
  • Сергей М. © (07.10.08 10:59) [3]
  • BREND © (07.10.08 13:53) [4]
    Спасибо за пример.
    А если я открываю не зжатый RIFF файл?
    Должно как-то быть проще. Все нужно записать в структуру - типа IAVIStream.
  • Sapersky (07.10.08 15:04) [5]
    Я нашел что можно использовать Avifile API и Directshow.
    Еще вроде есть VFW. Но конркетного примера нет.


    AviFile и VFW это скорее всего одно и то же.
    Пример:
    http://www.programania.com/avi2bmp.zip
  • Сергей М. © (07.10.08 20:41) [6]

    > если я открываю не зжатый RIFF файл?


    А по барабану что тты открываешь - технология DS имеет соотв инструменты.
  • BREND © (08.10.08 11:05) [7]
    avi2bmp.zip - хорошый пример.
    Можно сделать массив из картинок - фреймов через Avistreamgetframe(gapgf, iframenumber);

    А воспроизвести в чем-то PAVIStream можно?
  • Сергей М. © (08.10.08 12:15) [8]

    > BREND ©   (08.10.08 11:05) [7]


    Ты статью проштудировал ?
  • Sapersky (08.10.08 14:58) [9]
    А воспроизвести в чем-то PAVIStream можно?

    Можно выводить полученные через Avistreamgetframe битмапы, нужная частота кадров определяется через AVIStreamInfo.
    Cпециальных средств воспроизведения в духе "запустил и забыл" в VFW, похоже, нет. Во всяком случае, в справке по VFW (которая, кстати, идёт в составе стандартного хелпа Delphi) ничего такого не увидел.
  • BREND © (09.10.08 10:28) [10]
    Я понял, что есть 2 варианта: или через Directshow или через VFW.
    Сейчас разбираюсь с этим:
    http://www.libray.narod.ru/Program/DirectX/Chapter6.html

    Только вот с DS-фильтром тяжелее будет. Его наверное нужно регистрировать в системе, а надо ли это?
  • Sapersky (09.10.08 18:34) [11]
    Получить отдельные кадры видео в DirectShow можно и без написания фильтра, вроде бы через ISampleGrabber.
  • BREND © (10.10.08 11:01) [12]

    > Sapersky   (09.10.08 18:34) [11]
    > Получить отдельные кадры видео в DirectShow можно и без
    > написания фильтра, вроде бы через ISampleGrabber.

    Кадры нужно будет потом как-то вывести.

    Допустим, я написал фильтр (трансформ или рендер).
    Открываю файл через DSPACK, автоматически строится цепочка фльтров (Filtergraph.RenderFile) и выводится (Filtergraph.Play).
    Как мнет вставит свой фильтр в цепочку?
  • Sapersky (10.10.08 16:04) [13]
    Я не специалист по DirectShow, посмотри http://directshow.wonderu.com/
    Официальная справка по DirectShow есть в составе DirectX SDK (в online-варианте - MSDN).
  • BREND © (13.10.08 10:53) [14]
    Написал два варианта: один по avi2bmp, второй - по DSPACK\Demos\D6-D7\SampleGrabber.
    Вывожу картинки через таймер.
    В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига.
    2-й варинат лучше - поддерживает все форматы.
    В SampleGrabber - через SampleGrabber.GetBitmap(Image.Picture.Bitmap). Для примера - поменял местами два цвета.
    В Samplegrabber когда бросаю массив из картинки на фильтр Denoise, то все начинает очень глючить!
    Как в GetBitmap получить определенный кадр (по номеру)?.
  • Sapersky (13.10.08 16:43) [15]
    В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига.

    На выходе - это где?
    По DShow (тем более DSPack) ничего сказать не могу.
  • BREND © (13.10.08 17:54) [16]

    > На выходе - это где?

    В Image : Image.Picture.Assign(TmpBmp);
    Где, TmpBmp : TBitmap;
  • BREND © (13.10.08 18:02) [17]
    От так:
    type
     TRgb = array[0..2] of Byte;
     PRgb = ^TRgb;
    ...
    var
    Scanline,tmpColor: PRgb;
    ...
    for i := 0 to TmpBmp.Height-1 do
    begin
       Scanline := TmpBmp.ScanLine[R];

       for j := 0 to TmpBmp.Width-1 do
       begin
           tmpColor := Scanline[1];
           Scanline[1] := Scanline[2];
           Scanline[2] := tmpColor;
           Inc(Scanline);
       end;
    end;



    Правда, не со всеми bmp выйдет, там еще разный PixelFormat.
  • Sapersky (13.10.08 19:40) [18]
    В Image : Image.Picture.Assign(TmpBmp);

    Может, нужно его дополнительно пнуть, чтобы перерисовался? Ну там Image.Repaint...
    Или просто нарисовать битмап на канве формы.

    for i := 0 to TmpBmp.Height-1 do begin
      Scanline := TmpBmp.ScanLine[R];


    TmpBmp.ScanLine[i], tmpColor должен быть типа Byte - если это не опечатки.
  • BREND © (13.10.08 22:06) [19]
    Сорри, действительно ошибся.
    Refresh не работает. Я сначала подумал, что надо задать PixelFormat, но не помогло.
    Выводил через Form1.Canvas.BrushCopy - тот же эффект (.
    Да еще из-за цикла 1 кадр рисуется 1.5 сек.
    С реврешом ~2 сек (((.
    +1 на пользу Direct Show.

    GetBitmap возвращает всегда pf24bit. Еще +1.
    А вот и весь код:
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
     і,j,k : integer;
     Line : PRgb;
     arr : TVector;
    begin
     SampleGrabber.GetBitmap(bmp);

     if(bmp.PixelFormat = pf24bit) then
     begin
     if(bmp.Width = 0) then exit;
     if(Length(arr)=0) then
       SetLength(arr,bmp.Width*3);

     for и := 0 to bmp.Height - 1 do
     begin
       Line := bmp.ScanLine[i];
       к := 0;
       for j := 0 to bmp.Width - 1 do
       begin
          arr[k]:= Line[0];
          inc(k);
          arr[k]:= Line[1];
          inc(k);
          arr[k]:= Line[2];
          inc(k);
          inc(Line);
       end;

       //arr := Denoise(arr,0,1,1);
       к := 0;
       for j := 0 to bmp.Width - 1 do
       begin
          Line[0]:= round(arr[k]);
          inc(k);
          Line[1]:= round(arr[k]);
          inc(k);
          Line[2]:= round(arr[k]);
          inc(k);
          inc(Line);
       end;
     end;
     end;
     Image.Picture.Bitmap := bmp;
    end;


    Почему-то на некоторых сжатых фильмах на первом Line[0]:= round(arr[k]); выбивает.
    Не знаю; нужно думать как сохранить видео.
 
Конференция "Media" » Обработка видеосигнала [D7, WinXP]
Есть новые Нет новых   [134431   +10][b:0][p:0.002]