Cam Question - Escapi

Just starting out? Need help? Post your questions and find answers here.
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Cam Question - Escapi

Post by cbrooks999gggbbb »

Can anyone help me adjust the code below so that all it does is save a single snapshot picture to file? (jpg etc.)
Without opening up a screen window is preferred.

Code: Select all

;WORKS WITH ESCAPI
;UPDATED 8/28/2017
;PRESS CTL-Q TO QUIT
;INCORPORATES PROC AMP

ExamineDesktops()

gamma.f = 1.34 ;WEBCAM OUTPUT IS ALREADY GAMMA CORRECTED
#PEDESTAL = 16
gain.f = (235-16)/235
gain * 0.97

factor.f = 255/Pow(255,gamma)

;SET WEBCAM TO DEFAULTS AND SHARPNESS TO 255

;MAKE LUTS
Dim gammaTable.f(256)
For cnt = 0 To 255
cnf.f = cnt
gammaTable.f(cnt)=cnt;(Pow(cnf,gamma) * factor * gain) + #PEDESTAL
Next

Dim x3table.l(1921)
For cnt = 0 To 1920
x3table(cnt) = cnt * 3
Next

LoadFont(1,"Arial",24)

IncludeFile "c:\program files\purebasic\escapi.pbi"
Global WIDTH = 640;DesktopWidth(0)
Global HEIGHT = 360;DesktopHeight(0)
Global WIDTHM1 = WIDTH - 1
Global HEIGHTM1 = HEIGHT - 1
Global pixCount = (WIDTH * HEIGHT) - 2

Global Dim pixcolor.l(WIDTH, HEIGHT): Global Dim unsmoothedY.d(WIDTH, HEIGHT)
Global Dim Cr.d(WIDTH, HEIGHT): Global Dim Y.d(WIDTH, HEIGHT): Global Dim Cb.d(WIDTH, HEIGHT)
Global imHeight, imWidth, xCoord, yCoord,Rd,Gd,Bd

#DEVICE = 0    
If setupESCAPI() = #Null
      MessageRequester("Error", "Unable to initialize ESCAPI.")
    End
EndIf

    bufSize = WIDTH * HEIGHT * 4
    scp.SimpleCapParams
    scp\mWidth = WIDTH
    scp\mHeight = HEIGHT
    scp\mTargetBuf = AllocateMemory(bufSize)
    *buf = scp\mTargetBuf

    If initCapture(#DEVICE, @scp)
     
image = CreateImage(1, WIDTH, HEIGHT, 24)
OpenWindow(1, 0, 0, WIDTH, HEIGHT,"",#PB_Window_BorderLess)
AddKeyboardShortcut(1, #PB_Shortcut_Control|#PB_Shortcut_Q, 113);CTL Q TO QUIT
ImageGadget(0, 0, 0, WIDTH, HEIGHT, ImageID(1))
Quit = #False

StartDrawing(ImageOutput(1))
*writeBuffer = DrawingBuffer()
pitch = DrawingBufferPitch()
StopDrawing()

Repeat
If WindowEvent() = #PB_Event_Menu ;KEYBOARD INPUT
If EventMenu() = 113
  Quit = #True
EndIf
EndIf       
     
doCapture(#DEVICE)

Repeat: Delay(1):Until isCaptureDone(#DEVICE) <> #False

;If isCaptureDone(#DEVICE) <> #False
;If isCaptureDone(#DEVICE) = #False

;PIXEL-BY-PIXEL READING AND WRITING
hm1 = *writebuffer + (HEIGHTM1 * pitch)
*bufoff = *buf

;Goto skip
For y = 0 To HEIGHTM1
For x = 0 To WIDTHM1
x3 = hm1 + x3table(x)

p1.l = PeekL(*bufoff)

PokeA(x3,gammaTable(p1 & 255))
PokeA(x3+1,gammaTable(p1 >> 8 & 255))
PokeA(x3+2,gammaTable(p1 >> 16))

*bufoff + 4
Next
hm1 - pitch
Next

skip:
SetGadgetState(0, ImageID(1))

StartDrawing(WindowOutput(1))
DrawingFont(FontID(1))

now.f = ElapsedMilliseconds()
fps.f = now.f-then.f

If fps > 0:fps$ = StrF((1/fps)*1000,2) ;:EndIf
If (1/fps)*1000 < 10: fps$ = "0" + fps$: EndIf
EndIf

DrawText(100, 200, fps$+" fps",#White)
then.f = ElapsedMilliseconds()
StopDrawing()

Until Quit = #True

deinitCapture(#DEVICE)
FreeImage(1)
FreeMemory(scp\mTargetBuf)
CloseWindow(1)

    Else
      Debug "Init capture failed."
    EndIf

    End

infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

Hi,

modify it like this:

Code: Select all

...

If initCapture(#DEVICE, @scp)
  
  UseJPEGImageEncoder()
  
  image = CreateImage(1, WIDTH, HEIGHT, 24)
  OpenWindow(1, 0, 0, WIDTH, HEIGHT,"",#PB_Window_BorderLess)
  AddKeyboardShortcut(1, #PB_Shortcut_Control|#PB_Shortcut_Q, 113);CTL Q TO QUIT
  AddKeyboardShortcut(1, #PB_Shortcut_Return, 114) ; Enter for snapshot
  ImageGadget(0, 0, 0, WIDTH, HEIGHT, ImageID(1))
  Quit = #False
  
  StartDrawing(ImageOutput(1))
  *writeBuffer = DrawingBuffer()
  pitch = DrawingBufferPitch()
  StopDrawing()
  
  Repeat
    If WindowEvent() = #PB_Event_Menu ;KEYBOARD INPUT
      Select EventMenu()
        Case 113
          Quit = #True
        Case 114
          SaveImage(1, "c:\tmp\CamCapture.jpg", #PB_ImagePlugin_JPEG)
      EndSelect
    EndIf

  ...
Bernd
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Re: Cam Question - Escapi

Post by cbrooks999gggbbb »

Thanks. Clearly I don't know how this exactly works. I tried modifying the code so that all that it does is take a single snapshot, then ends.

All I'm getting is a saved .jpg file that is completely black. Did I miss something in the code? I'm trying to accomplish this without opening a image window.

Code: Select all


;WORKS WITH ESCAPI

;INCORPORATES PROC AMP

ExamineDesktops()

gamma.f = 1.34 ;WEBCAM OUTPUT IS ALREADY GAMMA CORRECTED
#PEDESTAL = 16
gain.f = (235-16)/235
gain * 0.97

factor.f = 255/Pow(255,gamma)

;SET WEBCAM TO DEFAULTS AND SHARPNESS TO 255

;MAKE LUTS
Dim gammaTable.f(256)
For cnt = 0 To 255
cnf.f = cnt
gammaTable.f(cnt)=cnt;(Pow(cnf,gamma) * factor * gain) + #PEDESTAL
Next

Dim x3table.l(1921)
For cnt = 0 To 1920
x3table(cnt) = cnt * 3
Next

LoadFont(1,"Arial",24)

IncludeFile "c:\program files\purebasic\escapi.pbi"
Global WIDTH = 640;DesktopWidth(0)
Global HEIGHT = 360;DesktopHeight(0)
Global WIDTHM1 = WIDTH - 1
Global HEIGHTM1 = HEIGHT - 1
Global pixCount = (WIDTH * HEIGHT) - 2

Global Dim pixcolor.l(WIDTH, HEIGHT): Global Dim unsmoothedY.d(WIDTH, HEIGHT)
Global Dim Cr.d(WIDTH, HEIGHT): Global Dim Y.d(WIDTH, HEIGHT): Global Dim Cb.d(WIDTH, HEIGHT)
Global imHeight, imWidth, xCoord, yCoord,Rd,Gd,Bd

#DEVICE = 0    

If setupESCAPI() = #Null
      MessageRequester("Error", "Unable to initialize ESCAPI.")
    End
EndIf

 bufSize = WIDTH * HEIGHT * 4
    scp.SimpleCapParams
    scp\mWidth = WIDTH
    scp\mHeight = HEIGHT
    scp\mTargetBuf = AllocateMemory(bufSize)
    *buf = scp\mTargetBuf

    
    
    doCapture(#DEVICE)

; Repeat: Delay(1):Until isCaptureDone(#DEVICE) <> #False

;If isCaptureDone(#DEVICE) <> #False
;If isCaptureDone(#DEVICE) = #False

;PIXEL-BY-PIXEL READING AND WRITING
hm1 = *writebuffer + (HEIGHTM1 * pitch)
*bufoff = *buf

;Goto skip
For y = 0 To HEIGHTM1
For x = 0 To WIDTHM1
x3 = hm1 + x3table(x)

p1.l = PeekL(*bufoff)



*bufoff + 4
Next
hm1 - pitch
Next





deinitCapture(#DEVICE)

FreeMemory(scp\mTargetBuf)

    
    
    
    
If initCapture(#DEVICE, @scp)
  
  UseJPEGImageEncoder()
  
  image = CreateImage(1, WIDTH, HEIGHT, 24)

 
      
          SaveImage(1, "c:\tmp\CamCapture.jpg", #PB_ImagePlugin_JPEG)
     
      
EndIf

infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

You can shrink your code to this:

Code: Select all

UseJPEGImageEncoder()

image = CreateImage(1, WIDTH, HEIGHT, 24)
SaveImage(1, "c:\tmp\CamCapture.jpg", #PB_ImagePlugin_JPEG)
That's what you are doing. You create an image and save it.
You don't save the picture you grabbed.

Does my example work? I can not test it, because I don't have a cam connected.

Bernd
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Re: Cam Question - Escapi

Post by cbrooks999gggbbb »

I got an error because width was 0 so I populated a size there.

All I get is a black image.

Your code does not call for ESCAPI, I thought that was needed.
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

cbrooks999gggbbb wrote:Your code does not call for ESCAPI, I thought that was needed.
I meant my example above, where I added a hotkey :wink:

My shrinked version is only to demonstrate what you have done.
And this results 100% in an empty picture.
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Re: Cam Question - Escapi

Post by cbrooks999gggbbb »

Gotcha and thank you!!

I've been reading and trying to appreciate how the code works.

Would the proper line be:

Code: Select all

SaveImage(1, "c:\tmp\CamCapture.jpg", image)
Or am I still misunderstanding where the image is stored in memory?
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

Hi,

the capured image is in the buffer scp\mTargetBuf
Then it is computed and copied to image 1:

Code: Select all

    hm1 = *writebuffer + (HEIGHTM1 * pitch)
    *bufoff = *buf
    
    ;Goto skip
    For y = 0 To HEIGHTM1
      For x = 0 To WIDTHM1
        x3 = hm1 + x3table(x)
        
        p1.l = PeekL(*bufoff)
        
        PokeA(x3,gammaTable(p1 & 255))
        PokeA(x3+1,gammaTable(p1 >> 8 & 255))
        PokeA(x3+2,gammaTable(p1 >> 16))
        
        *bufoff + 4
      Next
      hm1 - pitch
    Next
*writeBuffer is a pointer to image 1:

Code: Select all

  StartDrawing(ImageOutput(1))
  *writeBuffer = DrawingBuffer()
  pitch = DrawingBufferPitch()
  StopDrawing()
and *bufoff is a pointer to scp\mTargetBuf:

Code: Select all

*buf = scp\mTargetBuf
...
*bufoff = *buf
After the double 'for loop' everything is in image 1 and I can save it.

Bernd
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

The conversion is necesarry because the format of a PB image and the stored data by escapi is different.

In your example it is done by tables.
Long time ago I did it this way:

Code: Select all

            If StartDrawing(ImageOutput(image))
              mHeight = scp\mHeight - 1
              mWidth = scp\mWidth - 1
              For y = 0 To mHeight
                Offset = y * scp\mWidth
                For x = 0 To mWidth
                  PixelRGB = PeekL(scp\mTargetBuf + (Offset + x) << 2)
                  PixelBGR = (PixelRGB << 16) | (PixelRGB & $00FF00) | ((PixelRGB >> 16) & $FF)
                  Plot(x, y, PixelBGR)
                Next
              Next
              
              StopDrawing()
            EndIf
Not speed optimized :wink:
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Re: Cam Question - Escapi

Post by cbrooks999gggbbb »

Hi All. I'm still struggling with this - sorry for being such a rookie on this.

At best I get a stored black image. I've been reading up as much as I can but still can not figure this out.

Just trying to be able to store a single shot image from the webcam to a .jpg file.

Anyone here have working code that I can use?

Sincere thanks.
User avatar
blueb
Addict
Addict
Posts: 1044
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Cam Question - Escapi

Post by blueb »

Please locate 'cv_webcam_saveimage.pb' in JHPJHP's PureBasic Interface to OpenCV in the Tricks 'N' Tips forum

http://www.purebasic.fr/english/viewtop ... 12&t=57457

The program saves webcam images to your computer as jpg files. :)

NOTE: the images saved are located in the "../Frames" subdirectory! (took me a few minutes to locate them myself)
- It was too lonely at the top.

System : PB 6.10 LTS (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

This works.

Code: Select all

EnableExplicit

;WORKS WITH ESCAPI
;UPDATED 8/28/2017
;PRESS CTL-Q TO QUIT
;INCORPORATES PROC AMP

ExamineDesktops()

IncludeFile "escapi.pbi"

Define.i cnt, bufSize, image, Quit, pitch, hm1, y, x, x3, now, then, p1
Define.f gamma, gain, factor, cnf, fps
Define fps$
Define *buf, *writeBuffer, *bufoff
Define scp.SimpleCapParams


gamma = 1.34 ;WEBCAM OUTPUT IS ALREADY GAMMA CORRECTED
#PEDESTAL = 16
gain = (235-16)/235
gain * 0.97

factor = 255 / Pow(255, gamma)

;SET WEBCAM TO DEFAULTS AND SHARPNESS TO 255

;MAKE LUTS
Dim gammaTable.f(256)
For cnt = 0 To 255
  cnf = cnt
  gammaTable(cnt) = cnt ;(Pow(cnf,gamma) * factor * gain) + #PEDESTAL
Next

Dim x3table.l(1921)
For cnt = 0 To 1920
  x3table(cnt) = cnt * 3
Next

LoadFont(1,"Arial",24)



Global WIDTH = 640;DesktopWidth(0)
Global HEIGHT = 360;DesktopHeight(0)
Global WIDTHM1 = WIDTH - 1
Global HEIGHTM1 = HEIGHT - 1
Global pixCount = (WIDTH * HEIGHT) - 2

Global Dim pixcolor.l(WIDTH, HEIGHT)
Global Dim unsmoothedY.d(WIDTH, HEIGHT)
Global Dim Cr.d(WIDTH, HEIGHT)
Global Dim Y.d(WIDTH, HEIGHT)
Global Dim Cb.d(WIDTH, HEIGHT)
Global imHeight, imWidth, xCoord, yCoord,Rd,Gd,Bd

#DEVICE = 0   
If setupESCAPI() = #Null
  MessageRequester("Error", "Unable to initialize ESCAPI.")
  End
EndIf

bufSize = WIDTH * HEIGHT * 4
scp\mWidth = WIDTH
scp\mHeight = HEIGHT
scp\mTargetBuf = AllocateMemory(bufSize)
*buf = scp\mTargetBuf

If initCapture(#DEVICE, @scp)
 
  UseJPEGImageEncoder()
 
  image = CreateImage(1, WIDTH, HEIGHT, 24)
  OpenWindow(1, 0, 0, WIDTH, HEIGHT,"",#PB_Window_BorderLess)
  AddKeyboardShortcut(1, #PB_Shortcut_Control|#PB_Shortcut_Q, 113);CTL Q TO QUIT
  AddKeyboardShortcut(1, #PB_Shortcut_Return, 114) ; Enter for snapshot
  ImageGadget(0, 0, 0, 0, 0, ImageID(1))
  Quit = #False
 
  StartDrawing(ImageOutput(1))
  *writeBuffer = DrawingBuffer()
  pitch = DrawingBufferPitch()
  StopDrawing()
 
  Repeat
    If WindowEvent() = #PB_Event_Menu ;KEYBOARD INPUT
      Select EventMenu()
        Case 113
          Quit = #True
        Case 114
          SaveImage(1, "c:\tmp\CamCapture.jpg", #PB_ImagePlugin_JPEG)
      EndSelect
    EndIf
    
    doCapture(#DEVICE)
    
    Repeat
      Delay(1)
    Until isCaptureDone(#DEVICE)
    
    ;If isCaptureDone(#DEVICE) <> #False
    ;If isCaptureDone(#DEVICE) = #False
    
    ;PIXEL-BY-PIXEL READING AND WRITING
    hm1 = *writebuffer + (HEIGHTM1 * pitch)
    *bufoff = *buf
    
    ;Goto skip
    For y = 0 To HEIGHTM1
      For x = 0 To WIDTHM1
        x3 = hm1 + x3table(x)
        
        p1 = PeekL(*bufoff) & $FFFFFF
        
        PokeA(x3, gammaTable(p1 & 255))
        PokeA(x3 + 1, gammaTable(p1 >> 8 & 255))
        PokeA(x3 + 2, gammaTable(p1 >> 16))
        
        *bufoff + 4
      Next
      hm1 - pitch
    Next
    
    skip:
    SetGadgetState(0, ImageID(1))
    
    StartDrawing(WindowOutput(1))
    DrawingFont(FontID(1))
    
    now = ElapsedMilliseconds()
    fps = now - then
    
    If fps > 0:fps$ = StrF((1/fps)*1000,2) ;:EndIf
      If (1/fps)*1000 < 10: fps$ = "0" + fps$: EndIf
    EndIf
    
    DrawText(100, 200, fps$+" fps",#White)
    then = ElapsedMilliseconds()
    StopDrawing()
    
  Until Quit = #True
  
  deinitCapture(#DEVICE)
  FreeImage(1)
  FreeMemory(scp\mTargetBuf)
  CloseWindow(1)
  
Else
  Debug "Init capture failed."
EndIf
Bernd
cbrooks999gggbbb
New User
New User
Posts: 6
Joined: Thu Nov 02, 2017 2:37 am

Re: Cam Question - Escapi

Post by cbrooks999gggbbb »

Thank you!!!

I had to remove "EnableExplicit" else I PB opens up escapi.pb and gives an error "Line 49: With 'EnableExplicit', variables have to be declared: capdll.

It still worked (saved the image) - not sure what EnableExplicit is - will have to read up on that.

thank you!!!!
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cam Question - Escapi

Post by infratec »

But with all my stuff before ... you should learn how to program :wink:
Post Reply