• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 798
  • Last Modified:

Video for Windows: Compressed Image Capture

Hello,

I'm working on a webcamera video stream processing program, and I'm having some trouble with the internals of actually just modifying the stream.
My main issue is that the only webcam I have uses a compressed IYUV format - which ends up being something like 12 bits per pixel.

Here is the code I was told to use to decompress that:

//the Frame Callback function set with capSetOnFrameCallback (or something like that)
LRESULT CALLBACK Edge_Processor(HWND hwnd, LPVIDEOHDR lpVHdr)
{
      if(!lpVHdr->lpData) //Note that "lpData" is the actual frame data - whether it's compressed or decompressed.
            return 0;
      
                BITMAPINFO frameinfo;
      capGetVideoFormat(hwnd, &frameinfo, sizeof(frameinfo));

//Find the appropriate decompressor for this frame... of course this doesn't need to be done every frame.
      if(!theApp.dlg->decompressor){  //declared as "HIC decompressor"
            ICINFO icinfo;
            
            //thank you CodeGuru Guy!

            //walk over all codecs, find desired
            for (int i=0; ICInfo(ICTYPE_VIDEO, i, &icinfo); i++)
            {
                  theApp.dlg->decompressor=ICLocate(icinfo.fccType, icinfo.fccHandler, &frameinfo.bmiHeader,
                  NULL, ICMODE_FASTDECOMPRESS);
      
                  if (theApp.dlg->decompressor) {
                                theApp.dlg->decomp_handler=icinfo.fccHandler; //declared as "DWORD decomp_handler".. this is a function pointer.
                                break;
                  }
            }      
      }

                //THIS RETURNS A VALID DIB HANDLE... however I have no idea how big it is.... but hopefully it decompressed it to 24-bit, in the dimensions of the camera.
      HANDLE dib_to_process=ICImageDecompress(theApp.dlg->decompressor, 0, &frameinfo, lpVHdr->lpData, NULL);


.... ok ... that's pretty much what I got as far as translating the stream goes.

However - I do not know how to edit that DIB. I've tried just modifying the input version outright (I have another capture device that supports RGB 24 (uncompressed)), that doesn't exactly work either.

Someone please help me with this. I need to access pixels in the video.

Also I would like a tip to make this a little faster. Going in and processing every pixel in the captured image proves to be slow - just because of the processing I'm doing. I noticed that in the VIDEOHDR struct, it has variables like "bytes used", and "seconds captured" - or something like that. I was hoping to find out how I can process a smaller portion of the video capture so that this function runs faster.

I know that's asking alot - but I'm going to offer a good point value for this. Please offer good explanations...
0
RageDBL
Asked:
RageDBL
  • 8
  • 7
  • 2
2 Solutions
 
Dariusz DziaraProgrammerCommented:
I am not sure if this is what you wanted but (I guess):

HANDLE dib_to_process=ICImageDecompress(theApp.dlg->decompressor, 0, &frameinfo, lpVHdr->lpData, NULL);

LPBYTE lpByte, lpImage;
LPBITMAPINFOHEADER lpbmih;

lpByte = GlobalLock(dib_to_process);

if(lpByte != NULL) {
  lpbmih = (LPBITMAPINFOHEADER)lpByte;      // header describing image format
  lpImage = lpByte + lpbmih->biSize;              // pointer to bitmap bits

  // ... access image pixels here

  GlobalUnlock(dib_to_process);
};

[...]

GlobalFree(dib_to_process);         // finally release buffer
0
 
Dariusz DziaraProgrammerCommented:
"I was hoping to find out how I can process a smaller portion of the video capture so that this function runs faster."

I think you could use some Intel Image Processing library (one is free, the other costs ab. 200 $). You could map your bitmap data to Intel structures & simply use ROI (rectangular region of interest) as input parameters to Intel library functions.
0
 
RageDBLAuthor Commented:
Ok - I'll try it out soon. I don't have my camera with me right now - so I can't test it yet.

By the way - exactly what is the stride I need to use in the array if I'm accessing 24-bit pixels? Is it 3 (1 byte per pixel?)?
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
Dariusz DziaraProgrammerCommented:
Stride is usually number of bytes you need to add/subtract to move pointer by one line. For example when you have RGB24 format
stride=line_len*3 + some_bytes_for_DWORD_align.
There's usefull macro (WIDTHBYTES()) to calculate line stride from bitmap header.
It is:
stride = WIDTHBYTES(width_in_pixels * bits_per_pixel)
0
 
RageDBLAuthor Commented:
... right... Yeah I meant to say 3 bytes per pixel...

Ok thanks - I will try it soon.

On the note of processing the image quicker - does the camera settings (such as FPS) have anything to do with how much is in that buffer lpdata?
0
 
Dariusz DziaraProgrammerCommented:
FPS (frames per second) means only that frames comes more frequently, format decides about frame width & height, bit depth what implies frame size in bytes.
0
 
RageDBLAuthor Commented:
Well .... I was looking to get smaller chunks of a frame so that I could process it quicker - I will definitely look into that Intel Image Processing Library - because that ROI thing will definitely aid me here.
0
 
danielssonCommented:
Um. I have done a lot of Video for Windows programming, and I don't quite get it here... first, if you need less data to process, tell the camera to give you less data. This is though highly depending on the type of input device. Most USB web cams can do resolutions from approx 80x60 pixels up to 640x480 pixels. DV cameras for example can only give you a single resolution, but those won't work with Video for Windows anyway. Most Web cams (if they're not complete crap) are additionally able to deliver RGB24 data directly, so that you needn't convert from the IYUV format. Check out capSetVideoFormat and capDlgVideoFormat. Note: capDlgVideoCompression only works if you let VfW compress the video (using capCaptureSequence, not capCaptureSequenceNoFile).

Second, why are you using VfW at all? VfW is a deprecated technology which is being phased out since a couple of years. The way to go right now is definitely by using DirectShow. You'll have to dig quite a lot deeper than with VfW, but you will not need to convert any bitmaps to and fro any formats; by using the "intelligent connect" mechanisms, you can have DirectShow automatically generate uncompressed formats from most other formats.

If this is just a question on how to access the video data, well, you have them, right there, after the BITMAPINFOHEADER structure. Add the biSize to the pointer (cast to a char *), and you have the data. Manipulation of pixel data directly in memory looks quite tiresome, though. What is it you want to do, effectively?
0
 
RageDBLAuthor Commented:
WOW Thanks for the suggestion-  I'll definitely look into DirectShow. Yeah - the processing I'm doing on the video is quite tedious - so I needed less data to process (just a "piece" of a frame rather than the whole thing). Also, I'm afraid my camera is crap, but I still need compatability in my program. I'll try out DShow soon. This question will be closed soon - I won't cheat the VFW experts who helped me.
0
 
RageDBLAuthor Commented:
aah...

Where can I get the REAL OpenCV???? I keep getting links to download stuff that need "Ch" and the files I download are not useful! - and other stuff as well. Can someone point me to a Win32 version online?
0
 
danielssonCommented:
Wrong forum?
0
 
Dariusz DziaraProgrammerCommented:
I never heard about "OpenCV". I suggest you to ask new question 'cause this one is old and probabely not read by many experts.
0
 
RageDBLAuthor Commented:
It's the open-source version of the Intel Image Processing library - openCV is Open Computer Vision library. It's developed by intel as well.
0
 
Dariusz DziaraProgrammerCommented:
I haven't found much about OpenCV library on www.intel.com.

What I found is OpenCV implementation using IPL (Intel Image Processing Library) for performance optimization - download is here:

http://sourceforge.net/projects/opencvlibrary/
0
 
RageDBLAuthor Commented:
which file is for whinnedoze? I've been there before. Did you get the right file?
 
0
 
Dariusz DziaraProgrammerCommented:
"whinnedoze" ? Do you mean "Windows" (kind of stupid question) ?
I don't know OpenCV but
I think it is "opencv-win".
"ch-opencv" is also for Windows (I have now idea what it is)
and "openAVCSR-win" also

0
 
RageDBLAuthor Commented:
HEY!

good job!

thanks again!

I got the right file!
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

  • 8
  • 7
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now