-
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]); выбивает.
Не знаю; нужно думать как сохранить видео.