Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2003.03.17;
Скачать: [xml.tar.bz2];

Вниз

UYVY -> RGB   Найти похожие ветки 

 
Noname_   (2002-12-04 12:14) [0]

Как преобразовать битмап, получаемый при помощи ISampleGrabber, из формата UYVY в формат RGB?


 
pasha676   (2002-12-05 10:10) [1]

Слушай, не занимайся ерундой. Помоему надо просто подобрать фильты и их настройки в графе.
Можешь рассказать что у тебя за граф, устройства и фильтры какие используются. У меня такая хрень была когда юзал AverTV. Потом подобрал фильтр и все заработало.


 
Владимир Васильев   (2002-12-05 10:22) [2]

О теории предмета можно побольше узнать здесь: http://www.efg2.com/Lab/Graphics/Colors/YUV.htm
и , разумеется, здесь :- MSDN

А теперь практика:

это - так называемые LUT - Look Up Table - здесь храним заранее вычисленные значения для преобразования

Y16 : ARRAY[0..255] OF Integer;
V0128 : ARRAY[0..255] OF Integer;
V1128 : ARRAY[0..255] OF Integer;
U0128 : ARRAY[0..255] OF Integer;
U2128 : ARRAY[0..255] OF Integer;

где-нибудь до преобразования вычисляем значения выражений

for i:=0 to 255 do begin
Y16[i] := Trunc(1.164*(i-16) );
V0128[i] := Trunc(0.813*(i-128));
V1128[i] := Trunc(1.596*(i-128));
U0128[i] := Trunc(0.392*(i-128));
U2128[i] := Trunc(2.017*(i-128));
end;

И, собственно, сами процедуры

function Set255(Clr : Integer) : Byte;
asm
MOV EAX,Clr // store value in EAX register (32-bit register)
CMP EAX,254 // compare it to 254
JG @SETHI // if greater than 254 then go set to 255 (max value)
CMP EAX,1 // if less than 255, compare to 1
JL @SETLO // if less than 1 go set to 0 (min value)
RET // otherwise it doesn"t change, just exit
@SETHI: // Set value to 255
MOV EAX,255 // Move 255 into the EAX register
RET // Exit (result value is the EAX register value)
@SETLO: // Set value to 0
MOV EAX,0 // Move 0 into EAX register - Result is in EAX
end;

// Buffer: PByte; - указатель на начало буфера с UYVY
// BufferLen : longint ; - размер буфера с UYVY
// pBits: PByte - указатель на начало буфера с RBG


Procedure UYVYBuffer2RGB_( Buffer: PByte; BufferLen : longint ; pBits: PByte );
Var
U,V,Y0,Y1 : byte;
Begin

if (Buffer = nil) or (BufferLen = 0) or (pBits=nil) then Exit;
while BufferLen>0 do begin

U:=Buffer^;////U1:=U0;
inc(Buffer);
Y0:=Buffer^;
inc(Buffer);

V:=Buffer^;//V1:=V0;
inc(Buffer);
Y1:=Buffer^;
inc(Buffer);

//{
pBits^:= Set255( Y16[Y0] + U2128[U] ); //B
inc(pBits);
pBits^:= Set255( Y16[Y0] - U0128[U] - V0128[V] );//G
inc(pBits);
pBits^:= Set255( Y16[Y0] + V1128[V] ); //R
inc(pBits);
inc(pBits);

pBits^:= Set255( Y16[Y1] + U2128[U] ); //B
inc(pBits);
pBits^:= Set255( Y16[Y1] - U0128[U] - V0128[V] );//G
inc(pBits);
pBits^:= Set255( Y16[Y1] + V1128[V] ); //R
inc(pBits);
inc(pBits);

dec(BufferLen,4);
end;
end;

Юзать это можно так:
пример для DSPack в качестве обёртки вокруг DirectShow и DelphiX или Bitmap32 для вывода картинки

procedure TVideoForm.SampleGrabberBuffer(sender: TObject; SampleTime: Double; pBuffer: PByte; BufferLen: Integer);
const
LastTickCount : DWord=0;
Var
TickCount : DWord;
Time : DWord;
GrabberBufferTime : DWord;
TheSurfaceDesc : TDDSurfaceDesc2;
begin

//if GraphBusy then Exit;
if not CallBack.Checked then Exit;

SampleGrabber.OnBuffer:=nil;
//FilterGraph.Pause;

//GraphBusy:=true;

//TickCount:=GetTickCount;
//GrabberBufferTime:=TickCount-LastTickCount;

//Image321.Bitmap.BeginUpdate;

//SampleGrabber.UYVYBuffer2RGB_(pBuffer,BufferLen, Pointer(Image321.Bitmap.Bits) );

TheSurfaceDesc.dwSize:=SizeOf(TDDSurfaceDesc2);
if FSurface.ISurface7.Lock(nil,TheSurfaceDesc,DDLOCK_SURFACEMEMORYPTR+DDLOCK_WAIT,0)=DD_OK then begin

UYVYBuffer2RGB_(pBuffer,BufferLen, TheSurfaceDesc.lpSurface );
//SampleGrabber.UYVYBuffer2RGB_(pBuffer,BufferLen, TheSurfaceDesc.lpSurface );

FSurface.ISurface7.Unlock(TheSurfaceDesc.lpSurface);
DXDraw1.Surface.StretchDraw(DXDraw1.Surface.ClientRect, FSurface, false);
DXDraw1.Flip;
end;


//Image321.Bitmap.EndUpdate;

//LastTickCount:=GetTickCount;
//Time:=LastTickCount-TickCount;

//Image321.Bitmap.Textout(10,10, Format("UYVYBuffer2RGB time = %d ms / GrabberBufferTime = %d ms / fps = %f",[time, GrabberBufferTime,1000/(time+GrabberBufferTime)]) );

//Image321.Bitmap.Changed;

//GraphBusy:=false;


//SampleGrabber.UYVYBuffer2RGB(pBuffer,BufferLen,BufBitmap);
//Image.Picture.Assign(BufBitmap);

//FilterGraph.Play;
SampleGrabber.OnBuffer:=SampleGrabberBuffer;

end;





 
pasha676   (2002-12-05 11:00) [3]

Мда. Сильно. Но помоему просто стоит подобрать фильтры и их настройки. Вот, например, mp4 у меня не грабиться если только в настройках не указан RGB32. Если этого нет, то он не просто дает файл с покареженным цветом, но и пишет об ошибках dll.

PS Владимир спасибо за помощь в построении графов.


 
Noname_   (2002-12-05 11:38) [4]

Граф очень простой. Capture Filter[PinOut] -> [PinIn]Grabber Filter[PinOut1]. PinOut выдает поток в формате UYVY. Поэтому, когда я пытаюсь получить битмап при помощи ISampleGrabber.GetCurrentBuffer(), я получаю его перевернутым с неверными цветами (камера вообще черно-белая). Если я изменяю формат с UYVY на RGB24(32) при помощи ISampleGrabber.SetMediaType(), то на картинке (окно, выводимое самим граббер-фильтром) возникают артефакты. Битмап при этом нормальный, но тоже с артефактами. Поэтому такой путь не подходит. Подскажите, что значит подобрать фильтры и настроить их?


 
pasha676   (2002-12-05 13:30) [5]

По моему надо еще настроить свойства Capture Filter [PinOut]
Посмотри еще чтоб пиноут был обязательно Capture. На многих устройствах два выхода Capture и Priveiw.

Чтобы твоя прога работала, тебе надо рендерить пин. Скорее всего ты рендеришь пин выхода SampleGrabbera. Надо выходной фильтр грабера присоединить к какому-нибудь фильтру. На разных железках при разных цветах и медиатайпах обычно работает один из AVI Decompressor, но некоторые устройства требуют что-ниб другое - OverlayMixer, DV Decoder или еще что либо (зависит от того что у тебя стоит в системе). Ситуация с цветами у меня уже была. Когда AverTV стала на автомат. рендере почему то ставить не AVI Decompressor, а что-то другое.
Для того чтоб все это посмотреть воспользуйся редактором графов GraphEdit. Там все поймешь.


 
Владимир Васильев   (2002-12-05 14:36) [6]

если VideoRenderer (чере видеоплату) поддерживает декомпрессию UYV аппаратно то AVI Decompressor автоматически переключится с RGB на UYV
Можно попробовать вставить SampleGrabber между ними. Возможно, так-же прийдётся добавить и ColorSpaceConverter


 
Noname_   (2002-12-05 15:02) [7]

ColorSpaceConverter Filter преобразует из одного RGB в другой RGB.

2pasha676:
Я отправил тебе проект. Посмотри. Если будут предложения, пиши сюда или на мыло. Как добавить мой граф, что бы GraphEdit видел его? В программах на С используют функцию AddGraphToRot(), но я то не могу ее использовать.


 
pasha676   (2002-12-05 15:21) [8]

Не твой граф графедит должен видеть :). Ты запускаешь графедит, строишь там граф для своего устройства, делаешь настройки, подбераешь фильтры и т.д. Потом в своей программе создаешь такой же граф, который получился у тебя наиболее "рабочим".



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2003.03.17;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.008 c
1-54084
Альф
2003-03-05 11:38
2003.03.17
Как вызвать из программы runtime error 201 (Range check error) ?


7-54338
Slap
2003-01-17 11:48
2003.03.17
Проблема с CreateProcess в под Win9x


9-53828
Константин
2002-10-13 17:22
2003.03.17
Несколько ??? о разработке игр


14-54318
Igor_thief
2003-02-28 18:45
2003.03.17
Components


14-54166
ProtoSoft
2003-02-28 02:36
2003.03.17
Во блин, а правда Россияне, что у Вас собираются МАТЮКИ сделать..





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский