Help! My bitmap looks NUTS! Using VFW VideoStreamCallback!

Windows specific forum
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Help! My bitmap looks NUTS! Using VFW VideoStreamCallback!

Post by JustinJack »

I'm having a heck of a time! I'm just trying to capture bitmaps from the web cam, without copying images to the clipboard, or even displaying a capture window. The BITMAPINFO returned by the capture driver says I have a 16bpp bit map. I've tried converting this (programmatically) to 24 bits and 32, but then I just have slightly fancier colored crap.

I'm just turning it on and capturing the video stream, but I'm doing something wrong, because all my images have very squirrley color bits. I'm pretty sure I'm not doing something with a color palette, but I can't find ANY documentation anywhere on how to process the videostream data. This is my resulting image:


Image

Here are my variables:

Code: Select all

Structure BitMapImage
  *bitmapdata
  *bitmapdataOffset
  dwSize.i
EndStructure

Global NewList myImages.BitMapImage()
Global videoBMI.BITMAPINFO
Here's my prep code which does what it's supposed to:

Code: Select all

hWndMain = OpenWindow(0, 0, 0, 700, 500, "WebCamTest", #PB_Window_SystemMenu)
hDcMain = GetDC_(hWndMain)
hWebCam = capCreateCaptureWindowA("", #WS_CHILD, 10, 10, 640, 480, hWndMain, 0)

myCapParams.CAPTUREPARAMS
With myCapParams
  \AVStreamMaster = #Null
  \dwAudioBufferSize = #Null
  \dwIndexSize = 0; Default
  \dwMCIStartTime = #Null
  \dwMCIStopTime = #Null
  \dwRequestMicroSecPerFrame = 66667
  \fAbortLeftMouse = #True
  \fAbortRightMouse = #True
  \fCaptureAudio = #False
  \fDisableWriteCache = #Null
  \fLimitEnabled = #False
  \fMakeUserHitOKToCapture = 0
  \fMCIControl = #False
  \fStepCaptureAt2x = #False
  \fStepMCIDevice = #Null
  \fUsingDOSMemory = #Null
  \fYield = 1
  \vKeyAbort = #VK_ESCAPE
  \wChunkGranularity = 0
  \wNumAudioRequested = #Null
  \wNumVideoRequested = #Null
  \wPercentDropForError = 50
  \wStepCaptureAverageFrames = 5 ;Samples to average for a frame
  \wTimeLimit = #Null
EndWith


SendMessage_(hWebcam, #WM_CAP_DRIVER_CONNECT, 0 , 0)
SendMessage_(hWebCam, #WM_CAP_GET_VIDEOFORMAT, SizeOf(BITMAPINFO), @videoBMI)
SendMessage_(hWebCam, #WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, @VideoStreamCallBack())
SendMessage_(hWebCam, #WM_CAP_SET_CALLBACK_YIELD, 0, @CaptureYield())
SendMessage_(hWebCam, #WM_CAP_SET_SEQUENCE_SETUP, SizeOf(CAPTUREPARAMS), @myCapParams)
SendMessage_(hWebCam, #WM_CAP_SEQUENCE_NOFILE, 0, 0)

Debug "Images Captured: " + Str(ListSize(myImages()))
SendMessage_(hWebcam, #WM_CAP_DRIVER_DISCONNECT, 0, 0)

ImageGadget(0, 10, 10, 640, 480, 0)
ResetList(myImages())
While NextElement(myImages())
  WindowEvent()
  OpenFile(1, "c:\users\justin\desktop\images\myImage" + Str(i) + ".bmp")
  WriteData(1, myImages()\bitmapdata, myImages()\dwSize)
  CloseFile(1)
  i + 1
Wend


And Here's my VideoStreamCallBack(), Where I think I'm missing something...

Code: Select all

Procedure VideoStreamCallBack( caphWnd.l, *lpVideo.VIDEOHDR )
  
  AddElement(myImages())
  
  PrepareBitMap( videoBMI\bmiHeader\biBitCount, videoBMI\bmiHeader\biWidth, videoBMI\bmiHeader\biHeight, @myImages(), @videoBMI)
  
  For *i.Word = (*lpVideo\lpData + (*lpVideo\dwBufferLength)) To *lpVideo\lpData Step - 2
    *reverse.Word = myImages()\bitmapdataOffset + j
    ; 16 W/ Alpha
    ;Red = *i\w >> 10
    ;Green = (*i\w & 992) >> 5
    ;Blue = *i\w & 31
    
    ; High -Intenst 16
    ;Red = *i\w >> 11
    ;Green = (*i\w & 1986) >> 5
    ;Blue = *i\w & 31
    *reverse\w = *i\w 
    j + 2
  Next
  ProcedureReturn 1
EndProcedure
The PrepareBitMap() Procedure just loads all the bitmap header info, and gets my pointers good in the linked list myImages()
DarkPlayer
Enthusiast
Enthusiast
Posts: 107
Joined: Thu May 06, 2010 11:36 pm

Re: Help! My bitmap looks NUTS! Using VFW VideoStreamCallbac

Post by DarkPlayer »

Hi,

i think this looks much better:
Image

Your problem is that most webcams do not output RGB data, but some sort of YUV data. This picture was YUY2 encoded. You need a YUV to RGB converter, which can be difficult because there are many different YUV formats: YUY2, UYVY, Y41P, YVU9, ...
If you want to create a public program, you need to care about all of them. Some webcam drivers also send JPG frames and some other unusual formats.

The biCompression field of the BITMAPINFOHEADER structure tells you the sort of Compression. If it is equal to 0, you have some sort of RGB data, otherwise it is a 4 character String. In your case it would be "YUY2". These codes are called FourCC codes. You can find some information about the YUV formats on this website: http://www.fourcc.org/yuv.php

DarkPlayer
Last edited by DarkPlayer on Thu Jun 16, 2011 2:49 am, edited 1 time in total.
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Help! My bitmap looks NUTS! Using VFW VideoStreamCallbac

Post by JustinJack »

Wow. I think I look better in the 1st picture. Man, I never would have suspected that. So there must be some sort of info telling the OS what method to use, isn't there? When you use edit_copy, it the OS pops it decoded into the clipboard, right? Where does it get that info from?

btw I was beginning to give up on that one, man, thanks! If I'd have asked how to move memory or something i would have had an answer with the quickness.
DarkPlayer
Enthusiast
Enthusiast
Posts: 107
Joined: Thu May 06, 2010 11:36 pm

Re: Help! My bitmap looks NUTS! Using VFW VideoStreamCallbac

Post by DarkPlayer »

You were a bit to fast, I edited my post to add the information about how to get the type of compression :).
If you tell VFW to copy the picture to the clipboard it decodes the image for you.
I think VFW also has some public routines to decompress the images, but i am not sure. I always used my own code to decode webcam pictures. I was writing a program for a video chat, which used VFW, DirectShow and Video4Linux in Linux, so i wrote my own code that i could use in all situations, which does not depend on the OS.
The program directly converted all the different Input formats to YcBcR, because Theora (the video codec) used it. So i can't give you code to convert them directly to RGB.
You have to write them on your own.

DarkPlayer
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Help! My bitmap looks NUTS! Using VFW VideoStreamCallbac

Post by JustinJack »

Awsome. Thank you now I can crank up that stalled project!
Post Reply