-
Помогите решить проблему: Есть видео файл. Нужно написать программу для обработки шумов в видео. Вот например - через такую функцию: -----------------
type
TVector = array of Double;
function Denoise(
const Signal: TVector; const Mode: Integer; const Order: Integer; const Level: Integer ): TVector; overload;
Проблема в том, что я не знаю как мне представить видеосигнал через array of double? А затем еще и наоборот??? Все что я нашел - это вывод видео через Directshow, и то в несколько строк ((
-
> Все что я нашел - это вывод видео через Directshow
Ну так и напиши свой DS-фильтр, в чем проблема ?
-
Знал бы как ни спрашивал бы.
Я нашел что можно использовать Avifile API и Directshow. Еще вроде есть VFW. Но конркетного примера нет.
-
-
Спасибо за пример. А если я открываю не зжатый RIFF файл? Должно как-то быть проще. Все нужно записать в структуру - типа IAVIStream.
-
Я нашел что можно использовать Avifile API и Directshow. Еще вроде есть VFW. Но конркетного примера нет.AviFile и VFW это скорее всего одно и то же. Пример: http://www.programania.com/avi2bmp.zip
-
> если я открываю не зжатый RIFF файл?
А по барабану что тты открываешь - технология DS имеет соотв инструменты.
-
avi2bmp.zip - хорошый пример. Можно сделать массив из картинок - фреймов через Avistreamgetframe(gapgf, iframenumber);
А воспроизвести в чем-то PAVIStream можно?
-
> BREND © (08.10.08 11:05) [7]
Ты статью проштудировал ?
-
А воспроизвести в чем-то PAVIStream можно?
Можно выводить полученные через Avistreamgetframe битмапы, нужная частота кадров определяется через AVIStreamInfo. Cпециальных средств воспроизведения в духе "запустил и забыл" в VFW, похоже, нет. Во всяком случае, в справке по VFW (которая, кстати, идёт в составе стандартного хелпа Delphi) ничего такого не увидел.
-
-
Получить отдельные кадры видео в DirectShow можно и без написания фильтра, вроде бы через ISampleGrabber.
-
> Sapersky (09.10.08 18:34) [11] > Получить отдельные кадры видео в DirectShow можно и без > написания фильтра, вроде бы через ISampleGrabber.
Кадры нужно будет потом как-то вывести.
Допустим, я написал фильтр (трансформ или рендер). Открываю файл через DSPACK, автоматически строится цепочка фльтров (Filtergraph.RenderFile) и выводится (Filtergraph.Play). Как мнет вставит свой фильтр в цепочку?
-
Я не специалист по DirectShow, посмотри http://directshow.wonderu.com/Официальная справка по DirectShow есть в составе DirectX SDK (в online-варианте - MSDN).
-
Написал два варианта: один по avi2bmp, второй - по DSPACK\Demos\D6-D7\SampleGrabber. Вывожу картинки через таймер. В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига. 2-й варинат лучше - поддерживает все форматы. В SampleGrabber - через SampleGrabber.GetBitmap(Image.Picture.Bitmap). Для примера - поменял местами два цвета. В Samplegrabber когда бросаю массив из картинки на фильтр Denoise, то все начинает очень глючить! Как в GetBitmap получить определенный кадр (по номеру)?.
-
В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига.
На выходе - это где? По DShow (тем более DSPack) ничего сказать не могу.
-
> На выходе - это где?
В Image : Image.Picture.Assign(TmpBmp); Где, TmpBmp : TBitmap;
-
От так: 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.
-
В 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 - если это не опечатки.
-
Сорри, действительно ошибся. 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;
к := 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]); выбивает. Не знаю; нужно думать как сохранить видео.
-
Полагаю, при фильтрации не нужно смешивать компоненты RGB - скорее их следует обрабатывать по отдельности. Ещё сомневаюсь, что следует загонять в фильтр сразу всю строку. Обычно фильтруют в некоторой окрестности текущего пикселя, например, -2..+2. Впрочем, это надо смотреть исходники Denoise. По VFW - посмотрел avi2bmp.zip, каким-то кривым он мне показался. Написал свой: http://sapersky.narod.ru/files/AviPlayer_VFW.rarТоже неидеально работает, у некоторых роликов не читает кадры в конце - но это, похоже, проблема VFW. Всегда возвращает 24-битный битмап (правда, преобразование сделано только из 8-битного формата, не знаю, бывают ли какие-то другие).
-
Есть нормальный модуль для записи видео с TBitmap, так, чтоб в 3 ф-ии: 'создать' - 'записать кадр' - 'закрыть' ? Все примеры, какие я нашел - это запись из bmp файлов.
Или хотя бы скажите как получить PBitmapInfoHeader из TBitmap?
-
Есть нормальный модуль для записи видео с TBitmap, так, чтоб в 3 ф-ии: 'создать' - 'записать кадр' - 'закрыть' ? Все примеры, какие я нашел - это запись из bmp файлов.Есть модуль: http://www.programania.com/aviwriter_2.zipхотя там гораздо больше чем 3 функции, и может ли он писать из битмапов - толком не помню. Я делал упрощённую версию, но для TFastDIB, a не TBitmap. Прямо сейчас мне конвертировать некогда, может, через пару дней. Это всё опять-таки с VFW, насчёт DShow не в курсе. Или хотя бы скажите как получить PBitmapInfoHeader из TBitmap?GetDIBits
-
Относительно фильтрации - то наверное действительно нужно сделать три массива всей картинки, а затем подавать на фильтр. Если интересно, как работает фильтр, то ехе здесь: http://brend-777.narod.ru/WaveDemo.exe
-
-
Я добавил запись в видео. http://brend-777.narod.ru/AviPlayer_VFW.rarПока еще без кодека, но пишет! Использовал модуль VFW.pas (где-то нашел), вроде он новее за Avifile32.pas. Если увидите, что я что-то неправильно сделал, или не дописал что-то, пишите.
-
Подскажите, как лучше добавить шум. Randomize;
for j := 0 to 1000 do
FrameBitmap.Canvas.Pixels[random(FrameBitmap.Width - 1),random(FrameBitmap.Height - 1)] := clGray А то как то неправильно выходит.
-
Ну вот мой вариант, с заданием кодека, качества и проч. Также он несколько проще, без GlobalAlloc, GlobalLock и прочих "страшных слов" (и AVIStreamInit там, кстати, лишний - это то же самое, что AVIFileInit, который вызывается в конструкторе). Хотя переделывать на новые заголовки (VFW.pas) я поленился - вроде и со старыми работает. http://sapersky.narod.ru/files/AviHandler_VFW.rar
-
Подскажите, как лучше добавить шум. А то как то неправильно выходит.
Могу предложить не менять цвет на серый, а добавлять/вычитать к каждому цветовому компоненту (R, G, B) некую случайную величину.
-
Я тоже добавил поддержку кодеков, но несколько иначе: dwRate := FFramesPerSecond;
strhdr.dwScale := 1;
strhdr.dwSuggestedBufferSize := FramePtr^.biSizeImage; TAVICOMPRESSOPTIONS: я задаю только fccHandler и dwQuality. И все. Не знаю нужен ли FKeyFrameEvery, все и так работает. И еще, я нигде не вижу результатов параметра Quality - ни в размере, ни в качестве.
-
Не знаю нужен ли FKeyFrameEvery, все и так работает.
Ключевые кадры, теоретически, должны улучшать скорость позиционирования видео на произвольном месте (для кодеков, у которых текущий кадр рассчитывается с учётом предыдущих). Практически - не проверял, возможно, особой разницы нет.
И еще, я нигде не вижу результатов параметра Quality - ни в размере, ни в качестве.
Некоторые стандартные кодеки (напр. MSVC) используют Quality, хотя большинство продвинутых настраиваются через конфигурационное окно и поэтому стандартное "качество" игнорируют.
-
> Могу предложить не менять цвет на серый, а добавлять/вычитать > к каждому цветовому компоненту (R, G, B) некую случайную > величину.
Везде в нете натыкаюсь на процедуру AddNoise, из библиотеки FastLIB: http://www.soft32.ru/delphi.shtml?topic=graphic&title=bmp_add_noiseНормальный равномерный шум. Я пока что сделал так: рисую на изображении много квадратов - задаю количество и размер, размещение - рандомом. Плюс выбор цвета заполнения, рамки, и стиль. Самый лучший вроде bsDiagCross, с ним фильтр хорошо справляется. Нужно еще как-то сгладить края.
-
Это аддетивный Гаусовский шум. Нормальное распределение оно же Гаусовское. Соответствует тому шуму который обычно имеем при съемки изоброжения камерой.
Шум он бывает разный.
> Тоже неидеально работает, у некоторых роликов не читает > кадры в конце - но это, похоже, проблема VFW.
Видео может начинаться как с 0 кадра так и спервого, в структуре возращается номер начального кадра.
> Всегда возвращает 24-битный битмап (правда, преобразование > сделано только из 8-битного формата, не знаю, бывают ли > какие-то другие).
Бывают. VFW можно попросить выдать нужный формат или использовать то цветовое пространство в котором представленно изоброжение YUV и RGB самые распростроненные .
> VFW.pas
Помню когда начинал разбираться корректировал этот файл.
|