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, и то в несколько строк ((
У Вас есть исходный видеосигнал, так понимаю надо выделить из него полезный сигнал, при этом откинув помехи(шум).
Так вот пишем кусок программы, которая принимает исходные (необработанные) данные, разделяет помехи от полезного сигнала и выводим и то и другое по разным "каналам".
Формулы там конечно трёхэтажные, уже сразу не вспомнишь.
Или просто не знаешь как это реализовать?
Нодо знать формат принимаемых данных, объём(один файл или непрерывный поток) - если непрерывный поток то массив не поможет - не хватит памяти, тогда надо организовать непрерывный цикл, временный буфер фиксированного размера типа FIFO и обрабатывать его данные.
Проблема - как в ту ф-ию передать видео.
Есть 2 варианта - писать DS-фильтр через Directshow или использовать VFW.
Сейчас я читаю одну хорошую главу:
http://www.libray.narod.ru/Program/DirectX/Chapter6.html
Вывожу картинки через таймер.
В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига.
2-й варинат лучше - поддерживает все форматы.
В SampleGrabber - через SampleGrabber.GetBitmap(Image.Picture.Bitmap). Для примера - поменял местами два цвета.
В Samplegrabber когда бросаю массив из картинки на фильтр Denoise, то все начинает очень глючить!
Как в GetBitmap получить определенный кадр (по номеру)?.
Код:
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 i := 0 to bmp.Height - 1 do
begin
Line := bmp.ScanLine;
к := 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;
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 i := 0 to bmp.Height - 1 do
begin
Line := bmp.ScanLine;
к := 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]); выбивает.
Не знаю; нужно думать как сохранить видео.
Я хотел получить что-то вроде того:
Код:
function ConvertBitmap(Bitmap: TBitmap): PBitmapInfoHeader;
var
wLineLen : LongWord;
dwSize : DWORD;
wColSize : DWORD;
hdib : THANDLE;
lpbi : PBitmapInfoHeader;
lpBits : PByte;
ahdc : HDC;
begin
wLineLen := (Bitmap.Width * 24 + 31) div 32 * 4;
wColSize := 0;
dwSize := SizeOf(BITMAPINFOHEADER) + wColSize + wLineLen *
Bitmap.Height;
hdib := GlobalAlloc(GHND, dwSize); //allocate bitmap handle
lpbi := GlobalLock(hdib); // lock bitmap handle and get back pointer
lpbi^.biSize := SizeOf(BITMAPINFOHEADER);
lpbi^.biWidth := Bitmap.Width;
lpbi^.biHeight := Bitmap.Height;
lpbi^.biPlanes := 1;
lpbi^.biBitCount := 24;
lpbi^.biCompression := BI_RGB;
lpbi^.biSizeImage := dwSize - SizeOf(BITMAPINFOHEADER) - wColSize;
lpbi^.biXPelsPerMeter := 0;
lpbi^.biYPelsPerMeter := 0;
lpbi^.biClrImportant := 0;
lpbi^.biClrUsed := 0;
lpBits := Pointer(LongWord(lpbi) + lpbi^.biSize + wColSize);
ahdc := CreateCompatibleDC(0);
GetDIBits(ahdc, Bitmap.Handle, 0,
Bitmap.Height, lpBits, PBitmapInfo(lpbi)^,
DIB_RGB_COLORS);
lpbi^.biClrUsed := 0;
DeleteDC(ahdc);
GlobalUnlock(hdib);
Result := lpbi;
end;
var
wLineLen : LongWord;
dwSize : DWORD;
wColSize : DWORD;
hdib : THANDLE;
lpbi : PBitmapInfoHeader;
lpBits : PByte;
ahdc : HDC;
begin
wLineLen := (Bitmap.Width * 24 + 31) div 32 * 4;
wColSize := 0;
dwSize := SizeOf(BITMAPINFOHEADER) + wColSize + wLineLen *
Bitmap.Height;
hdib := GlobalAlloc(GHND, dwSize); //allocate bitmap handle
lpbi := GlobalLock(hdib); // lock bitmap handle and get back pointer
lpbi^.biSize := SizeOf(BITMAPINFOHEADER);
lpbi^.biWidth := Bitmap.Width;
lpbi^.biHeight := Bitmap.Height;
lpbi^.biPlanes := 1;
lpbi^.biBitCount := 24;
lpbi^.biCompression := BI_RGB;
lpbi^.biSizeImage := dwSize - SizeOf(BITMAPINFOHEADER) - wColSize;
lpbi^.biXPelsPerMeter := 0;
lpbi^.biYPelsPerMeter := 0;
lpbi^.biClrImportant := 0;
lpbi^.biClrUsed := 0;
lpBits := Pointer(LongWord(lpbi) + lpbi^.biSize + wColSize);
ahdc := CreateCompatibleDC(0);
GetDIBits(ahdc, Bitmap.Handle, 0,
Bitmap.Height, lpBits, PBitmapInfo(lpbi)^,
DIB_RGB_COLORS);
lpbi^.biClrUsed := 0;
DeleteDC(ahdc);
GlobalUnlock(hdib);
Result := lpbi;
end;
Не думал, что негде нету.
Ну, а дальше с AVIStreamWrite проблем не было.