PureBasic Interface to OpenCV

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi AAT, RSBasic,

Thank you for reviewing the previous example and pointing out the potential problem.

-----------------------------------------

Updated:
- fix the problem mentioned in the previous post
- renamed 1 example
-- cv_steganography.pb to cv_steganography_text.pb
- added 2 examples
-- cv_steganography_image_1.pb, cv_steganography_image_2.pb

Unlike the example cv_steganography_text.pb which requires a comparison image to decode the hidden message, the following examples use the LSB (Least Significant Bit) method.
- cv_steganography_image_1.pb: conceals an image within a larger image
- cv_steganography_image_2.pb: extracts the hidden image

NOTE:
- the first example starts with a defaulted embedded image
- use the context menu to change the hidden image or save the completed image
- if needed the imbedded image will be resized to fit the main image: Width x Height x 3 (channels) x 8 (LSB)
- PIP in the 1st example shows the embedded image, but is not included in the saved image

NB*: The Steganography examples require that the hidden binary data is saved in a lossless image format: defaulted to PNG (Portable Network Graphics).

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Optimized the examples cv_steganography_image_1.pb, cv_steganography_image_2.pb.
- added two Macros
-- REPLACE_BIT, EXTRACT_BIT

NB*: Both examples execute much faster with the above change.

-----------------------------------------------------------

Updated the examples cv_steganography_image_1.pb, cv_steganography_image_2.pb.

When embedding some images the last 100 or so pixels wouldn't transfer all three channels correctly due to an alignment issue.

I remembered the example cv_encode_decode.pb where an image is encoded into a single row of data, then decoded back into the standard format; applying this technique fixed the problem.

-----------------------------------------------------------

I figured out the previous alignment issue without having to encode / decode the image, but kept the current method because it offers better security from third party steganalysis tools.
- I've updated the code to include the changes as well as some additional optimizations

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Phantomas
User
User
Posts: 96
Joined: Wed Jul 01, 2009 12:59 pm

Re: PureBasic Interface to OpenCV

Post by Phantomas »

Can anyone help me with my code?

Code: Select all

IncludeFile "includes/cv_functions.pbi"

EnableExplicit

UseJPEGImageDecoder()
UseJPEGImageEncoder()

Procedure.i get_frame(quality.i)
  Protected rtrn.i
  Protected *capture.CvCapture
  ;cvSetCaptureProperty(*capture.CvCapture, #CV_CAP_PROP_FRAME_WIDTH, 320)
  ;cvSetCaptureProperty(*capture.CvCapture, #CV_CAP_PROP_FRAME_HEIGHT, 240)
  *capture.CvCapture = cvCreateCameraCapture(0)
  If *capture
    Protected *image.IplImage
    *image = cvQueryFrame(*capture)
    If *image
      ;cvFlip(*image, #Null, 1)
      ;cvSaveImage("D:\img.jpg", *image, @params)
      Protected params.SAVE_INFO
      params\paramId = #CV_IMWRITE_JPEG_QUALITY
      params\paramValue = quality
      Protected *mat.CvMat = cvEncodeImage(".jpg", *image, @params)
      If CatchImage(0, *mat\ptr, *mat\cols)
        Protected *imgbuf = EncodeImage(0, #PB_ImagePlugin_JPEG)
        If *imgbuf
          rtrn = *imgbuf
        Else
          Debug "Encode Image Failure!"
          rtrn = -4
        EndIf
      Else
        Debug "Catch Image Failure!"
        rtrn = -3
      EndIf
      cvReleaseMat(@*mat)
      ;cvReleaseImage(@*image)
    Else
      Debug "Query Frame Failure!"
      rtrn = -2
    EndIf
    cvReleaseCapture(@*capture)
  Else
    Debug "Create Camera Capture Failure!"
    rtrn = -1
  EndIf
  ProcedureReturn rtrn
EndProcedure

Define counter
For counter = 0 To 2
  Define *img = get_frame(85)
  ;Debug MemorySize(*img)
  If *img > 0
    Debug *img
    ;If CreateFile(0, "D:\file.jpg")
    ;  WriteData(0, @*img, MemorySize(@*img))
    ;  CloseFile(0)
    ;EndIf
    FreeMemory(*img)
  Else
    Debug "error:"
    Debug *img
  EndIf
Next
This code make 3 frames from WebCam, but why on different memory adresses?
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi Phantomas,

The reason for separate memory addresses is because you're creating and releasing the web cam and query-image in the main loop.
- releasing the web cab also releases the query-image (releasing both can cause a memory fault)

Take a look at the example cv_pb_cam_database.pb (includes/pb_procedures -- Procedure: ImportImage).
- most of the web cam examples use the same format and should provide some insite

Also, there are 4 default templates to help you get started creating various type examples: binaries/default (cv_cam_default.pb, pb_cam_default.pb, etc.).
- copy a template to the "main examples" folder before using it

Let me know if you have any trouble moving forward; if so please provide additional details to what you would like to accomplish, and I will try to help.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Stefou
User
User
Posts: 19
Joined: Thu May 29, 2008 8:40 am

Re: PureBasic Interface to OpenCV

Post by Stefou »

Hello JHPJHP

Thank you for all of that. It's help me so much to access to my camera stream. :D

I need to work on image with purebasic command.

I find to save image on HD but i'd like to work in memory.

Something like that :
*image = cvQueryFrame(*capture)
CatchImage(0, *image)

I'm not good enough to understand how to do this correctly :(
If you have few minutes to help me...

In anyway, thank a lot again :D
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, Stefou
If I understood your question correctly, you should take a look this http://www.purebasic.fr/english/viewtop ... 21#p433921
and next posts.

Example:

Code: Select all

IncludeFile "includes/cv_functions.pbi"
UseJPEGImageEncoder()
UseJPEGImageDecoder()
Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture
If *capture
  Repeat
    *image.IplImage = cvQueryFrame(*capture)
  Until *image 
  params.SAVE_INFO
  params\paramId = #CV_IMWRITE_JPEG_QUALITY
  params\paramValue = 90
  *mat.CvMat = cvEncodeImage(".jpg", *image, @params)
  Result = CatchImage(1, *mat\ptr, *mat\cols)
  *imgbuf = EncodeImage(1, #PB_ImagePlugin_JPEG);
  bufsize = MemorySize(*imgbuf)
  OpenFile(2,"c:\catched.jpg")
  For j=0 To bufsize-1
    WriteByte(2,PeekB(*imgbuf+j))
  Next
  CloseFile(2)
  cvReleaseCapture(@*capture)
EndIf
Good luck!
Stefou
User
User
Posts: 19
Joined: Thu May 29, 2008 8:40 am

Re: PureBasic Interface to OpenCV

Post by Stefou »

Thank you AAT :D

It' exactly what i wan't to do! :D

I'm happy :D
Phantomas
User
User
Posts: 96
Joined: Wed Jul 01, 2009 12:59 pm

Re: PureBasic Interface to OpenCV

Post by Phantomas »

JHPJHP wrote:The reason for separate memory addresses is because you're creating and releasing the web cam and query-image in the main loop.
- releasing the web cab also releases the query-image (releasing both can cause a memory fault)
Thanks for reply. But I should creating and releasing WebCam like this. Because I want make application which working in background, then get event* and do: open camera > make shot > store it in memory > close camera > wait next event.
* Event can come randomly, for example, 3 times per hour or 10 times per 5 minutes.
I don't want keep camera "opened" (cvCreateCameraCapture()) all time while application running...
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi Stefou,

I'm glad AAT was there to lend a helping hand, he was an invaluable support creating "Purebasic Interface to OpenCV".

----------------------------------------------

Hi Phantomas,

In your case working with multiple memory addresses is unavoidable, but maybe the following provides an alternative?
- create a Global image: *image.IplImage
- clone the query-image: *query.IplImage to the global image: *image.IplImage
- release the webcam (also releasing the query-image)
- work with the cloned image

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Phantomas
User
User
Posts: 96
Joined: Wed Jul 01, 2009 12:59 pm

Re: PureBasic Interface to OpenCV

Post by Phantomas »

JHPJHP wrote:In your case working with multiple memory addresses is unavoidable, but maybe the following provides an alternative?
It's strange, but not luck:

Code: Select all

IncludeFile "includes/cv_functions.pbi"

EnableExplicit

UseJPEGImageDecoder()
UseJPEGImageEncoder()

Global *g_image.IplImage

Procedure.i get_frame(quality.i)
  Protected ret.i
  Protected *capture.CvCapture = cvCreateCameraCapture(0)
  If *capture
    Protected *image.IplImage
    *image = cvQueryFrame(*capture)
    If *image
      *g_image = cvCloneImage(*image)
      ret = 1
    Else
      Debug "Query Frame Failure!"
    EndIf
    cvReleaseCapture(@*capture)
  Else
    Debug "Create Camera Capture Failure!"
  EndIf
  ProcedureReturn ret
EndProcedure

Define counter
For counter = 0 To 2
  If get_frame(85)
    Debug *g_image
    cvReleaseImage(@*g_image)
  EndIf
Next
Different adresses again.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi Phantomas,

Releasing the Global image inside a loop will force a new memory address... try the following:
- I switched cvCloneImage with cvCopy for better memory management

Code: Select all

IncludeFile "includes/cv_functions.pbi"

EnableExplicit
Global *gImage.IplImage

Procedure GetFrame(nQuality.a)
  Protected FrameWidth, FrameHeight, ReturnImage = #False
  Protected *capture.CvCapture, *image.IplImage
  
  *capture.CvCapture = cvCreateCameraCapture(0)
  
  If *capture
    If Not *gImage
      FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
      FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
      *gImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 3)
    EndIf
    *image = cvQueryFrame(*capture)
    
    If *image
      cvCopy(*image, *gImage, #Null)
      ReturnImage = #True
    Else
      Debug "Query Frame Failure!"
    EndIf
    cvReleaseCapture(@*capture)
  Else
    Debug "Create Camera Capture Failure!"
  EndIf
  ProcedureReturn ReturnImage
EndProcedure

UseJPEGImageDecoder()
UseJPEGImageEncoder()
Define nCounter

For nCounter = 0 To 2
  If GetFrame(85) : Debug *gImage : EndIf
Next
cvReleaseImage(@*gImage)

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Phantomas
User
User
Posts: 96
Joined: Wed Jul 01, 2009 12:59 pm

Re: PureBasic Interface to OpenCV

Post by Phantomas »

Great! Thank you very much JHPJHP :).

Let me one more question:
I can set custom resolution after cvCreateCameraCapture():

Code: Select all

  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH, 1280)
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT, 720)
But this will "reopen" camera again. Can I bypass it and open camera immediately with custom resolution?
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi Phantomas,

Using native OpenCV commands you're limited, but an alternative would be to resize the returned frame:
- this could be written multiple ways: passing the resize image to the Procedure, returning the new image, without global variables, etc.

Code: Select all

UseJPEGImageDecoder()
UseJPEGImageEncoder()
Define nCounter, *resize.IplImage

*resize = cvCreateImage(320, 180, #IPL_DEPTH_8U, 3)

For nCounter = 0 To 2
  If GetFrame(85)
    cvResize(*gImage, *resize, #CV_INTER_AREA)
    Debug *resize
  EndIf
Next
cvReleaseImage(@*resize)
cvReleaseImage(@*gImage)

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated the examples to be Unicode compliant (enabled by default).
- OpenCV_32, OpenCV_64, OpenCV_3.0

NOTE:
- most examples require user input to initiate the effect
-- a popup message will display the Description / Options when the mouse pointer is over the window
- most examples include a context menu
-- Open / Save / Exit

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP,
hi, guys.

This is an example how to correct webcam's image distortions. The example is based on JHPJHP's example cv_cam_chessboard_2.pb.
You have to use binaries/images/chessboard.jpg during the calibration process.
You have to slightly move and rotate webcam along chessboard (or chessboard along webcam) during calibration.

It looks like this:
raw image
Image
corrected image
Image

Save code as cv_cam_undistort.pb in main folder with JHPJHP's examples.
Then you have to set "Compiler Options":
Image

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME  = "PureBasic Interface to OpenCV"
#CV_WINDOW2_NAME = "Corrected image"

#CV_DESCRIPTION = "Calibrating of the webcam with 10 x 7 chessboard pattern then shows corrected image." + Chr(10) + Chr(10) +
                  "Press S key to save the pair of raw and corrected images" + Chr(10) + Chr(10) +
                  "Press Esc key to exit"

#CORNER_ROW = 6
#CORNER_COL = 9
#IMAGE_SIZE = 25
#PATTERN_SIZE = #CORNER_ROW * #CORNER_COL
#ALL_POINTS = #IMAGE_SIZE * #PATTERN_SIZE

ProcedureC WindowCallback(hWnd, Msg, wParam, lParam)
  Shared exitCV.b

  Select Msg
    Case #WM_COMMAND
      Select wParam
        Case 10
          exitCV = #True
      EndSelect
    Case #WM_DESTROY
      exitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure

ProcedureC CvMouseCallback(event, x.l, y.l, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\uValue)
    Case #CV_EVENT_LBUTTONDBLCLK
  EndSelect
EndProcedure

Repeat
  nCreate + 1
  *capture.CvCapture = cvCreateCameraCapture(#CV_CAP_ANY)
Until nCreate = 5 Or *capture

If *capture
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
  window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
  *window_name = cvGetWindowName(window_handle)
  lpPrevWndFunc = SetWindowLongPtr_(window_handle, #GWL_WNDPROC, @WindowCallback())

  If CreatePopupImageMenu(0, #PB_Menu_ModernLook)
    MenuItem(10, "Exit")
  EndIf
  hWnd = GetParent_(window_handle)
  opencv = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
  SendMessage_(hWnd, #WM_SETICON, 0, opencv)
  wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
  SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  ToolTip(window_handle, #CV_DESCRIPTION)  
  *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
  *param\uValue = window_handle
  cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)
  
  font.CvFont : cvInitFont(@font, #CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, #Null, 1, #CV_AA) 
  
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  
  Dim corners.CvPoint2D32f(#ALL_POINTS)
  Dim points(#IMAGE_SIZE)
  *source.IplImage
  *image.IplImage
  *gray.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 1)  
  
  DBL_EPSILON.d = 2.2204460492503131 * Pow(10, -16)

  While found_num < #IMAGE_SIZE
    *image = cvQueryFrame(*capture)

    If *image
      cvReleaseImage(@*source)
      *source = cvCloneImage(*image)
      cvCvtColor(*source, *gray, #CV_BGR2GRAY, 1)     
      If cvCheckChessboard(*gray, #CORNER_COL, #CORNER_ROW)
        found = cvFindChessboardCorners(*source, #CORNER_COL, #CORNER_ROW, @corners(found_num * #PATTERN_SIZE), @corner_count, #CV_CALIB_CB_ADAPTIVE_THRESH | #CV_CALIB_CB_FILTER_QUADS)
        If found
          cvFindCornerSubPix(*gray, @corners(found_num * #PATTERN_SIZE), corner_count, 3, 3, -1, -1, #CV_TERMCRIT_ITER | #CV_TERMCRIT_EPS, 20, 0.03)
          cvDrawChessboardCorners(*source, #CORNER_COL, #CORNER_ROW, @corners(found_num * #PATTERN_SIZE), corner_count, found)
          points(found_num) = corner_count
          found_num + 1
        EndIf       
      EndIf
      cvPutText(*source, "Found "+Str(found_num)+"/"+Str(#IMAGE_SIZE)+" chessboard images", 10, 30, @font, 0, 0, 255, 0)         
      cvShowImage(#CV_WINDOW_NAME, *source)
      keyPressed = cvWaitKey(100)      
    EndIf
      
    If keyPressed = 27 Or exitCV : Break : EndIf
  Wend

  If found_num = #IMAGE_SIZE
    cvPutText(*image, "The camera calibration, wait a little...", 10, 30, @font, 0, 0, 255, 0)         
    cvShowImage(#CV_WINDOW_NAME, *image)
    keyPressed = cvWaitKey(100)
    
    Dim objects.CvPoint3D32f(#ALL_POINTS)
    #CHESS_LENGTH = 24

    For i = 0 To #IMAGE_SIZE - 1
      For j = 0 To #CORNER_ROW - 1
        For k = 0 To #CORNER_COL - 1
          objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\x = j * #CHESS_LENGTH
          objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\y = k * #CHESS_LENGTH
          objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\z = 0.0
        Next
      Next
    Next
    object_points.CvMat
    image_points.CvMat
    point_counts.CvMat
    cvInitMatHeader(@object_points, #ALL_POINTS, 3, CV_MAKETYPE(#CV_32F, 1), @objects(), #CV_AUTOSTEP)
    cvInitMatHeader(@image_points, #ALL_POINTS, 2, CV_MAKETYPE(#CV_32F, 1), @corners(), #CV_AUTOSTEP)
    cvInitMatHeader(@point_counts, #IMAGE_SIZE, 1, CV_MAKETYPE(#CV_32S, 1), @points(), #CV_AUTOSTEP)
    *camera_matrix.CvMat = cvCreateMat(3, 3, CV_MAKETYPE(#CV_32F, 1))
    *distortion_coeffs.CvMat = cvCreateMat(4, 1, CV_MAKETYPE(#CV_32F, 1))  
    cvCalibrateCamera2(@object_points, @image_points, @point_counts, FrameWidth, FrameHeight, *camera_matrix, *distortion_coeffs, #Null, #Null, 0, #CV_TERMCRIT_ITER | #CV_TERMCRIT_EPS, 50, DBL_EPSILON)             
    
    *mapx.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 1) 
    *mapy.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 1)    
    cvInitUndistortMap(*camera_matrix, *distortion_coeffs, *mapx, *mapy)
    
    cvNamedWindow(#CV_WINDOW2_NAME, #CV_WINDOW_AUTOSIZE)    
    cvMoveWindow(#CV_WINDOW2_NAME, *image\width+30, 20)
    Repeat
      *image = cvQueryFrame(*capture)    
      If *image       
        cvReleaseImage(@*imgundist)         
        *imgundist = cvCloneImage(*image)    
        cvUndistort2(*image, *imgundist, *camera_matrix, *distortion_coeffs, #Null)         
        cvShowImage(#CV_WINDOW_NAME, *image)
        cvShowImage(#CV_WINDOW2_NAME, *imgundist)   
      EndIf
      keyPressed = cvWaitKey(10)    
      
      If keyPressed = 83 Or keyPressed = 115
        If FileSize("ImagePairs") <> -2 : CreateDirectory("ImagePairs") : EndIf
        cvSaveImage("./ImagePairs/"+FormatDate("%yyyy-%mm-%dd %hh-%ii-%ss", Date()) + ".jpg" , *image, #Null)
        cvSaveImage("./ImagePairs/"+FormatDate("%yyyy-%mm-%dd %hh-%ii-%ss", Date()) + "_Undistorted.jpg", *imgundist, #Null)
        Debug "Saved"
      EndIf      
      
    Until keyPressed = 27 Or exitCV
    cvReleaseMat(@*distortion_coeffs)
    cvReleaseMat(@*camera_matrix)
  EndIf
  FreeMemory(*param)
  cvReleaseImage(@*gray)
  cvReleaseImage(@*source)
  cvReleaseImage(@*mapx)
  cvReleaseImage(@*mapy)    
  cvDestroyAllWindows()
  cvReleaseCapture(@*capture)
Else
  MessageBox_(0, "Unable to connect to a webcam - operation cancelled.", #CV_WINDOW_NAME, #MB_ICONERROR)
EndIf
Have fun!
Locked