Конференция "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]); выбивает.
    Не знаю; нужно думать как сохранить видео.
  • Sapersky (14.10.08 19:27) [20]
    Полагаю, при фильтрации не нужно смешивать компоненты RGB - скорее их следует обрабатывать по отдельности.
    Ещё сомневаюсь, что следует загонять в фильтр сразу всю строку. Обычно фильтруют в некоторой окрестности текущего пикселя, например, -2..+2. Впрочем, это надо смотреть исходники Denoise.

    По VFW - посмотрел avi2bmp.zip, каким-то кривым он мне показался. Написал свой:
    http://sapersky.narod.ru/files/AviPlayer_VFW.rar
    Тоже неидеально работает, у некоторых роликов не читает кадры в конце - но это, похоже, проблема VFW. Всегда возвращает 24-битный битмап (правда, преобразование сделано только из 8-битного формата, не знаю, бывают ли какие-то другие).
  • BREND © (15.10.08 10:40) [21]
    Есть нормальный модуль для записи видео с TBitmap, так, чтоб в 3 ф-ии: 'создать' - 'записать кадр' - 'закрыть' ?
    Все примеры, какие я нашел - это запись из bmp файлов.

    Или хотя бы скажите как получить PBitmapInfoHeader из TBitmap?
  • Sapersky (15.10.08 16:09) [22]
    Есть нормальный модуль для записи видео с TBitmap, так, чтоб в 3 ф-ии: 'создать' - 'записать кадр' - 'закрыть' ? Все примеры, какие я нашел - это запись из bmp файлов.

    Есть модуль:
    http://www.programania.com/aviwriter_2.zip
    хотя там гораздо больше чем 3 функции, и может ли он писать из битмапов - толком не помню.
    Я делал упрощённую версию, но для TFastDIB, a не TBitmap. Прямо сейчас мне конвертировать некогда, может, через пару дней.
    Это всё опять-таки с VFW, насчёт DShow не в курсе.

    Или хотя бы скажите как получить PBitmapInfoHeader из TBitmap?

    GetDIBits
  • BREND © (15.10.08 17:50) [23]
    Относительно фильтрации - то наверное действительно нужно сделать три массива всей картинки, а затем подавать на фильтр.

    Если интересно, как работает фильтр, то ехе здесь:http://brend-777.narod.ru/WaveDemo.exe
  • BREND © (16.10.08 10:36) [24]

    Sapersky
    > По VFW - посмотрел avi2bmp.zip, каким-то кривым он мне показался.
    >  Написал свой:http://sapersky.narod.ru/files/AviPlayer_VFW.rar

    Спасибо, очень хорошо переделал.
  • BREND © (17.10.08 11:17) [25]
    Я добавил запись в видео.
    http://brend-777.narod.ru/AviPlayer_VFW.rar
    Пока еще без кодека, но пишет!
    Использовал модуль VFW.pas (где-то нашел), вроде он новее за Avifile32.pas.

    Если увидите, что я что-то неправильно сделал, или не дописал что-то, пишите.
  • BREND © (20.10.08 14:50) [26]
    Подскажите, как лучше добавить шум.
    Randomize;
          for j := 0 to 1000 do

          FrameBitmap.Canvas.Pixels[random(FrameBitmap.Width - 1),random(FrameBitmap.Height - 1)] := clGray



    А то как то неправильно выходит.
  • Sapersky (20.10.08 15:14) [27]
    Ну вот мой вариант, с заданием кодека, качества и проч. Также он несколько проще, без GlobalAlloc, GlobalLock и прочих "страшных слов" (и AVIStreamInit там, кстати, лишний - это то же самое, что AVIFileInit, который вызывается в конструкторе).
    Хотя переделывать на новые заголовки (VFW.pas) я поленился - вроде и со старыми работает.
    http://sapersky.narod.ru/files/AviHandler_VFW.rar
  • Sapersky (20.10.08 15:25) [28]
    Подскажите, как лучше добавить шум.
    А то как то неправильно выходит.


    Могу предложить не менять цвет на серый, а добавлять/вычитать к каждому цветовому компоненту (R, G, B) некую случайную величину.
  • BREND © (20.10.08 22:51) [29]
    Я тоже добавил поддержку кодеков, но несколько иначе:
    dwRate := FFramesPerSecond;
    strhdr.dwScale := 1;
    strhdr.dwSuggestedBufferSize := FramePtr^.biSizeImage;



    TAVICOMPRESSOPTIONS:


    я задаю только fccHandler и dwQuality. И все.
    Не знаю нужен ли FKeyFrameEvery, все и так работает.

    И еще, я нигде не вижу результатов параметра Quality - ни в размере, ни в качестве.
  • Sapersky (21.10.08 12:10) [30]
    Не знаю нужен ли FKeyFrameEvery, все и так работает.

    Ключевые кадры, теоретически, должны улучшать скорость позиционирования видео на произвольном месте (для кодеков, у которых текущий кадр рассчитывается с учётом предыдущих). Практически - не проверял, возможно, особой разницы нет.

    И еще, я нигде не вижу результатов параметра Quality - ни в размере, ни в качестве.

    Некоторые стандартные кодеки (напр. MSVC) используют Quality, хотя большинство продвинутых настраиваются через конфигурационное окно и поэтому стандартное "качество" игнорируют.
  • BREND © (22.10.08 11:46) [31]

    > Могу предложить не менять цвет на серый, а добавлять/вычитать
    > к каждому цветовому компоненту (R, G, B) некую случайную
    > величину.

    Везде в нете натыкаюсь на процедуру AddNoise, из библиотеки FastLIB:
    http://www.soft32.ru/delphi.shtml?topic=graphic&title=bmp_add_noise
    Нормальный равномерный шум.

    Я пока что сделал так:
    рисую на изображении много квадратов - задаю количество и размер, размещение - рандомом.
    Плюс выбор цвета заполнения, рамки, и стиль.
    Самый лучший вроде bsDiagCross, с ним фильтр хорошо справляется.
    Нужно еще как-то сгладить края.
  • Pavia © (22.10.08 23:49) [32]
    Это аддетивный Гаусовский шум.
    Нормальное распределение оно же Гаусовское. Соответствует тому шуму который обычно имеем при съемки изоброжения камерой.

    Шум он бывает разный.


    > Тоже неидеально работает, у некоторых роликов не читает
    > кадры в конце - но это, похоже, проблема VFW.

    Видео  может начинаться как с 0 кадра так и спервого, в структуре возращается номер начального кадра.


    > Всегда возвращает 24-битный битмап (правда, преобразование
    > сделано только из 8-битного формата, не знаю, бывают ли
    > какие-то другие).

    Бывают. VFW можно попросить выдать нужный формат или использовать то цветовое пространство в котором представленно изоброжение YUV и RGB самые распростроненные .


    > VFW.pas

    Помню когда начинал разбираться корректировал этот файл.
 
Конференция "Media" » Обработка видеосигнала [D7, WinXP]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]