Page 2 of 3

Posted: Wed Oct 05, 2005 8:43 am
by Kukulkan
do you know another method for store webcam images (without use #WM_CAP_EDIT_COPY"?
Yes, but there is needed a lot of work and effort to do so. You can take a look at this:
http://msdn.microsoft.com/library/defau ... erence.asp

There you can go through the Multimedia Functions and Structures. If you search on some of the topics there (google), you surely can get some examples about how to deal with.

Kukulkan

Posted: Wed Oct 05, 2005 9:35 am
by DoubleDutch
You can save to disk with (instead of copying to clipboard):

Code: Select all

If SendMessage_(CAMhWndC,#WM_CAP_GRAB_FRAME,0,0) 
  SendMessage_(CAMhWndC,#WM_CAP_FILE_SAVEDIBA,0,Path$+Filename$)
EndIf
Then just reload it into the image you want, it is a bit slower thought ;)

-Anthony

Posted: Wed Oct 05, 2005 12:38 pm
by zikitrake
DoubleDutch wrote:You can save to disk with (instead of copying to clipboard):

Code: Select all

If SendMessage_(CAMhWndC,#WM_CAP_GRAB_FRAME,0,0) 
  SendMessage_(CAMhWndC,#WM_CAP_FILE_SAVEDIBA,0,Path$+Filename$)
EndIf
Then just reload it into the image you want, it is a bit slower thought ;)

-Anthony
Thank you! DoubleDutch, but I tryed these code too and I don't like, because in each save file, the mouse cursor changed to arrow-wait-arrow-wait... and I do not like it much


(Sorry for my horrible English)

Posted: Wed Oct 05, 2005 12:45 pm
by Nik
Why doesn´t

Code: Select all


Repeat 
Event=WaitWindowEvent() 

SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
img.l = GetClipboardData(#PB_ClipboardImage)
StartDrawing(WindowOutput())
DrawImage(img.l, 0, 0, 640, 480)
StopDrawing() 


Until Event=#PB_EventCloseWindow
result in a moving image what o i hvae to do to get it updated?

Posted: Mon Oct 10, 2005 3:24 pm
by Nik
Nobody wants to tell me how to refresh the image correctly? Another question is how did you do the effects (not the whole formula^^) I just wonder how to draw them Point and Plot seem to be a lot to slow.
bye Nik

Posted: Tue Oct 11, 2005 7:03 am
by Kukulkan
@Nik,
Nobody wants to tell me how to refresh the image correctly?
You should advice the driver to do so:

Code: Select all

SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
Another question is how did you do the effects (not the whole formula^^) I just wonder how to draw them Point and Plot seem to be a lot to slow.
I copy the whole bitmap into an byte-array with GetBitmapBits_(). Now I can manipulate on an array of bytes (in my case 4 bytes per pixel). After manipulation, I use SetBitmapBits_() to write the pixels back to the image. Now I simply use DrawImage().
The algorithm is, in short words, a replacement-matrix. On program-start I create a matrix (2 two-dimensional arrays) which defines, where the information of the destination-pixels are coming from (positions in the source-picture). Later I can loop through this matrix in realtime. I dont have to do very much calculations while processing the image.

Kukulkan

Posted: Tue Oct 11, 2005 9:51 pm
by Nik
Oh thats really cool indeed :wink:

Posted: Tue Oct 11, 2005 9:56 pm
by Nik
Oh thats really cool indeed :wink:

Hmm but I still don#t get it working thoughPriewview seems to be activated

Code: Select all

Global hWndC

OpenWindow(0,0,0,640,480,#PB_Window_SystemMenu,"test")
;| #WS_VISIBLE
; initialize webcam
If OpenLibrary(0, "avicap32.dll")
   *capAddress = IsFunction(0, "capCreateCaptureWindowA")
 hWndC = CallFunctionFast(*capAddress, "test", #WS_CHILD , 695, 12, 40, 30, WindowID(), 1)
   Debug hWndc
  SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, KameraID.l, 0) ; connect driver
  SendMessage_(hWndC,#WM_CAP_SET_SCALE, #True, 0) ; no stretching
  SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0) ;see its activated
  SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 50, 0) ; set preview-rate (milliseconds)
  ;SendMessage_(hWndC, #WM_CAP_END, 0, 0)
; Else
;   MessageRequester("Scotty, we have a problem...","Sorry, but I cant find or open avicap32.dll...", #MB_ICONERROR)
; EndIf
; 
; retrieve picture



Repeat

Event=WindowEvent() 
If Event=#PB_Event_CloseWindow :End:EndIf
ClearClipboard() 
  
SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
img.l = GetClipboardData(#PB_ClipboardImage)
 ;SendMessage_(hWndC, #WM_CAP_END, 0, 0)
StartDrawing(WindowOutput())
DrawImage(img.l, 0, 0, 640, 480)
StopDrawing() 

Delay(10)
ForEver
EndIf
PS; Sorry but things like that arent my best area^^

Posted: Tue Oct 11, 2005 11:19 pm
by Flype
kukulkan:
i play a little and i found something for manipulating pixels,
is it a good method to do this way ? :

Code: Select all

; important: configure your web cam : 320*240*rgb24

#WM_CAP_START = #WM_USER
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10 
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51 
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50 
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52 
#WM_CAP_SET_SCALE = #WM_CAP_START + 53 

Structure VIDEOHDR
  lpData.l
  dwBufferLength.l
  dwBytesUsed.l
  dwTimeCaptured.l
  dwUser.l
  dwFlags.l
  dwReserved.l[4]
EndStructure

Procedure capFrameCallback(hWnd.l,*lpVHdr.VIDEOHDR)
  
  If hWnd
    StartDrawing(WindowOutput())
      For y=0 To 239
        For x=0 To 319
          a=*lpVHdr\lpData+3*((239-y)*320+x)
          b=PeekB(a+0)&$FF
          g=PeekB(a+1)&$FF
          r=PeekB(a+2)&$FF
          Plot(x+330,y+5,RGB(r,g,b)) ; <------
        Next
      Next
    StopDrawing()
  EndIf
  
EndProcedure

OpenWindow(0,0,0,655,250,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"cam")

If OpenLibrary(0,"avicap32.dll") 
  hWndC = CallFunctionFast(IsFunction(0,"capCreateCaptureWindowA"),"cap",#WS_CHILD|#WS_VISIBLE,5,5,320,240,WindowID(),1) 
EndIf 

SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage_(hWndC, #WM_CAP_SET_SCALE, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_OVERLAY, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 24, 0)
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, @capFrameCallback())

ActivateWindow()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, 0)
      Break
  EndSelect
ForEver

End

Posted: Wed Oct 12, 2005 8:28 am
by Kukulkan
Hi Flype,

This is great way to avoid using the clipboard. Thank you for this Idea. :)

In this case, maybe you can use SetBitmapBits_() to copy all pixels into a predefined bitmap and then simply use DrawImage(). This may be faster than using Plot() for every pixel. You have to take care about, how many bytes representing a pixel in this way (idea is untested).

Kukulkan

Posted: Wed Oct 12, 2005 8:42 am
by Flype
Cool... But i don't know at all how to use SetBitmapBits_()... :x Maybe you can show me an example using mine :?:

Remark:
Do you know the capture software DScaler4 ?
I'm a bit confused because in DScaler the video refresh-time is much faster than using our method. I don't know why... but anyway... maybe WDM drivers are slower than the others.

thanks for helping us.

Posted: Wed Oct 12, 2005 8:56 am
by Kukulkan
Try http://www.google.de/search?q=SetBitmapBits and http://www.google.de/search?q=SetDIBits. You will find everything you need in the first returned results.

Kukulkan

Posted: Wed Oct 12, 2005 9:24 am
by dige
you could do it like this:

Code: Select all

; important: configure your web cam : 320*240*rgb24

#WM_CAP_START = #WM_USER
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_SET_SCALE = #WM_CAP_START + 53

Structure VIDEOHDR
  lpData.l
  dwBufferLength.l
  dwBytesUsed.l
  dwTimeCaptured.l
  dwUser.l
  dwFlags.l
  dwReserved.l[4]
EndStructure

Procedure capFrameCallback(hWnd.l, *lpVHdr.VIDEOHDR)
  
  If hWnd
    hBmp  = UseImage( 1 )
    
    w = ImageWidth()
    h = ImageHeight()
    
    bmi.BITMAPINFO
    bmi\bmiHeader\biSize   = SizeOf(BITMAPINFOHEADER) 
    bmi\bmiHeader\biWidth  = w
    bmi\bmiHeader\biHeight = h 
    bmi\bmiHeader\biPlanes = 1 
    bmi\bmiHeader\biBitCount = 32 
    bmi\bmiHeader\biCompression = #BI_RGB 
    
    hdc = StartDrawing(ImageOutput())
    If hdc
      SetDIBits_( hdc, hBmp, 0, h, *lpVHdr\lpData, bmi, #DIB_RGB_COLORS) 
      StopDrawing()
    EndIf
    
    If StartDrawing(WindowOutput())
      DrawImage(UseImage(1), 0, 0)
      StopDrawing()
    EndIf
    
  EndIf    
EndProcedure

OpenWindow(0,0,0,655,250,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"cam")

If OpenLibrary(0,"avicap32.dll")
  hWndC = CallFunctionFast(IsFunction(0,"capCreateCaptureWindowA"),"cap",#WS_CHILD|#WS_VISIBLE,5,5,320,240,WindowID(),1)
EndIf

CreateImage(1, 320, 240)

SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage_(hWndC, #WM_CAP_SET_SCALE, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_OVERLAY, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 24, 0)
SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, @capFrameCallback())

ActivateWindow()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_FRAME, 0, 0)
      Break
  EndSelect
ForEver

End

Posted: Wed Oct 12, 2005 9:43 am
by FloHimself
interesting!

this could be a good base to do motion-, croma-, edge-detection.

Posted: Wed Oct 12, 2005 9:44 am
by Kukulkan
Hi dige,

This is exactly what I meant! Thank you!

Kukulkan