Форум: "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