Помогите решить проблему: Есть видео файл. Нужно написать программу для обработки шумов в видео. Вот например - через такую функцию: ----------------- Код (Text): 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, и то в несколько строк ((
BREND Что касается Directshow то обработку нужно делать через написание фильтера. Я пока не разбирался да и желания нет. А вот в VFW попроще. Открываешь файл пример есть в MSDN на выходе у тебя будет картинка. У кортинок есть два основных формата RGB и YUV. Остальные являются производными или невтричаются, встречаются редко. Можно сделать реализацию для обработки этих двух форматов или попросить систему чтобы он преобреобразовала в нуный или самому преобразовать. Что касается получения массива вещественных чисел то это делается при помощи цикла.
в сэмплах directshow есть фильтр, непомню как называется.., как то rgb... вобщем найдешь (ненайдешь завтра скажу). Это трасформ фильтр, на пять секунд меняет цвет видео. Начни с него
Мне подсказали хороший пример по VFW - avi2bmp. Там такой порядок: AVIFileInit; // Открываем AVI - файл AVIFileOpen(tekFile, PChar(FileName), 0, nil); // Открывыем видеопоток AVIFileGetStream(tekFile, tekAVIStream, streamtypeVIDEO, 0); А дальше идет чтение по кадрам: // Подготовка к декомпрессии видео кадра gapgf := AVIStreamGetFrameOpen(AVIStream, nil); lpbi := AVIStreamGetFrame(gapgf, iFrameNumber); В результате получается картинка.
ну и вот... Фильтр в сэмплах directshow называется EZRGB24, вот кусок кода Код (Text): // // Transform (in place) // // 'In place' apply the image effect to this sample // HRESULT CEZrgb24::Transform(IMediaSample *pMediaSample) { BYTE *pData; // Pointer to the actual image buffer long lDataLen; // Holds length of any given sample unsigned int grey,grey2; // Used when applying greying effects int iPixel; // Used to loop through the image pixels int temp,x,y; // General loop counters for transforms RGBTRIPLE *prgb; // Holds a pointer to the current pixel AM_MEDIA_TYPE* pType = &m_pInput->CurrentMediaType(); VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat; ASSERT(pvi); CheckPointer(pMediaSample,E_POINTER); pMediaSample->GetPointer(&pData); lDataLen = pMediaSample->GetSize(); // Get the image properties from the BITMAPINFOHEADER int cxImage = pvi->bmiHeader.biWidth; int cyImage = pvi->bmiHeader.biHeight; int numPixels = cxImage * cyImage; // int iPixelSize = pvi->bmiHeader.biBitCount / 8; // int cbImage = cyImage * cxImage * iPixelSize; switch (m_effect) { case IDC_NONE: break; // Zero out the green and blue components to leave only the red // so acting as a filter - for better visual results, compute a // greyscale value for the pixel and make that the red component case IDC_RED: prgb = (RGBTRIPLE*) pData; for (iPixel=0; iPixel < numPixels; iPixel++, prgb++) { prgb->rgbtGreen = 0; prgb->rgbtBlue = 0; } break; IDC_RED - это идентификатор эффекта, показывать только красную составляющую. А тебе нужно только собрать этот фильтр и применить свой эффект.
Я понял, что есть 2 варианта: или через Directshow или через VFW. Сейчас разбираюсь с этим: http://www.libray.narod.ru/Program/DirectX/Chapter6.html letopisec В таком случае, нужно будет писать DS-фильтр, регистрировать его в системе, а затем подключать через DSPACK.
фильтр писать не надо, он уже написан). Запихни внутрь CEZrgb24::Transform(IMediaSample *pMediaSample) свой алгоритм и тесть при помощи grapheditor. Это саоме простое что можно придумать. При этом получишь все преимущества дирекшоу Тоесть независимость от форматов входных файлов, независимость выходных - хочешь пиши в файл, а хочешь рендерь.
Все бы было хорошо, но Ezrgb24 не компилиццо! Просто линкер выдает ошибки, что не может связать имена. Такая же судьба и для http://vlafy.iulabs.com/rus/progds.htm (ошибка линкера) Зато в делвях все хорошо ). Открыл DSPACK234\Demos\D6-D7\Filters\Alpha Renderer\. Зменил несколько строк на Код (Text): for x := 0 to FWidth * FHeight - 1 do begin d.rgbRed := Byte((Source.rgbRed * Source.rgbReserved div 256 + Checkers.rgbRed * (256 - Source.rgbReserved) div 256)); d.rgbGreen := 0; d.rgbBlue := 0; CopyMemory(Source, @d, SizeOf(RGBQUAD)); Inc(Source); Inc(Checkers); end; И фльтр уже выводил в красных тонах. Все компилиться, регистрируется и пашет в Graphedit. Теперь вопрос: я открываю файл через DSPACK, автоматически строится цепочка фльтров (FilterGraph.RenderFile) и выводится (FilterGraph.Play). Как мне вставить свой фильтр (или трансформ, или рендер) в цепочку?
Написал два варианта: один по avi2bmp, второй - по DSPACK\Demos\D6-D7\SampleGrabber. Вывожу картинки через таймер. В avi2bmp - через AVIStreamGetFrame получаю Tbitmap. Но я не могу его изменить! Меняю Bitmap, на выходе - нифига. 2-й варинат лучше - поддерживает все форматы. В SampleGrabber - через SampleGrabber.GetBitmap(Image.Picture.Bitmap). Для примера - поменял местами два цвета. В Samplegrabber когда бросаю массив из картинки на фильтр Denoise, то все начинает очень глючить! Как GetBitmap получить определенный кадр (по номеру)?.
Кто небудь имеет нормальный модуль для записи видео с TBitmap, так, чтоб в 3 ф-ии: 'создать' - 'записать кадр' - 'закрыть' ? Все примеры, какие я нашел - это запись из bmp файлов. Или хотя бы скажите как получить PBitmapInfoHeader из TBitmap?