PureBasic Interface to OpenCV

Developed or developing a new product in PureBasic? Tell the world about it.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Hi, JHPJHP!

The example cv_cam_logo.pb is very very nice!
But there is one drawback: the image of the logo fades on bright scenes.
I think that if you replace your original procedure on the following, logo will be better seen.

Code: Select all

Procedure OpenCV(ImageFile.s, *capture)
  If ImageFile
    *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
    *logo.IplImage
    *resize.IplImage
    *border.IplImage
    *image.IplImage   
    *mask.IplImage
    
    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(1, "Open")
      MenuBar()
      MenuItem(2, "Exit")
    EndIf
    *param\uMsg = PeekS(*window_name, -1, #PB_Ascii) + ": "
    *param\uValue = window_handle
    cvSetMouseCallback(*window_name, @cvMouseCallback(), *param)
    hWnd = GetParent_(window_handle)
    ExtractIconEx_("shell32.dll", 1, #Null, @phiconSmall, 1)
    SendMessage_(hWnd, #WM_SETICON, 0, phiconSmall)
    wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
    SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
    *logo = cvLoadImage(ImageFile, #CV_LOAD_IMAGE_ANYDEPTH | #CV_LOAD_IMAGE_ANYCOLOR)
    
    If *logo\nChannels > 1
      If *logo\width > 100
        iRatio.d = 100 / *logo\width
        iWidth = *logo\width * iRatio
        iHeight = *logo\height * iRatio
        *resize = cvCreateImage(iWidth, iHeight, #IPL_DEPTH_8U, *logo\nChannels)
        cvResize(*logo, *resize, #CV_INTER_AREA)
      Else
        *resize = cvCloneImage(*logo)
      EndIf
      cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
      offset = 5
      *border = cvCreateImage(*resize\width + offset - 1, *resize\height + offset - 1, #IPL_DEPTH_8U, *resize\nChannels)
      cvCopyMakeBorder(*resize, *border, (offset - 1) / 2, (offset - 1) / 2, #IPL_BORDER_CONSTANT, 0, 255, 255, 0)
      
      *mask = cvCloneImage(*border)
      cvSet(*mask, 0, 0, 0, 0, #Null)      
      
      Repeat
        *image = cvQueryFrame(*capture)

        If *image
          cvSetImageROI(*image, 20, 20, *border\width, *border\height)
          cvAnd(*image,*mask,*image,0)
          cvAdd(*image, *border, *image, #Null)
          cvResetImageROI(*image)
          cvShowImage(#CV_WINDOW_NAME, *image)
          keyPressed = cvWaitKey(1)
        EndIf
      Until keyPressed = 27 Or ExitCV
    Else
      MessageBox_(0, ImageFile + Chr(10) + Chr(10) + "... does not meet the channel requirements, please try another image.", #CV_WINDOW_NAME, #MB_ICONERROR)
      GetCV = #True
    EndIf
    cvDestroyWindow(#CV_WINDOW_NAME)
    cvReleaseImage(@*border)
    cvReleaseImage(@*resize)
    cvReleaseImage(@*logo)
    cvReleaseImage(@*mask)

    If GetCV
      GetCV = #False
      ExitCV = #False
      OpenCV(GetImage(), *capture)
    Else
      cvReleaseCapture(@*capture)
    EndIf
  EndIf
EndProcedure
P.S. My examples was simpler :)

Good luck!
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Hi,

The example cv_cam_logo.pb gave me a good idea: to show the video from second camera instead of the logo - the effect of the PIP. And it really works!
Thanks, JHPJHP! :)
Short film captured from the screen:: http://rghost.ru/50831615 (available 30 days)

cv_cam_PIP.pb

Code: Select all

IncludeFile "includes/cv_functions.pbi"

#CV_WINDOW_NAME = "Two webcams - PiP effect"

Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
  *capture2 = cvCreateCameraCapture(1)  
  Delay(500)
Until nCreate = 5 Or *capture
Debug("Capture1 = "+Str(*capture))

If Bool(*capture2 = #False) 
  nCreate = 0
  Repeat
    nCreate + 1
    *capture2 = cvCreateCameraCapture(1)  
    Delay(500)
  Until nCreate = 10 Or *capture2
EndIf
Debug("Capture2 = "+Str(*capture2))

If Bool(*capture2 = #False) 
  MessageRequester("Error!", "Second cam not detected",#PB_MessageRequester_Ok )
  cvReleaseCapture(@*capture)
  End
EndIf

If *capture
  *frame2.IplImage
  *resize.IplImage
  *border.IplImage
  *frame1.IplImage 
  *smallimg.IplImage 
  *mask.IplImage
  
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH, 640)
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT, 480)  
  
  cvSetCaptureProperty(*capture2, #CV_CAP_PROP_FRAME_WIDTH, 160)
  cvSetCaptureProperty(*capture2, #CV_CAP_PROP_FRAME_HEIGHT, 120)     
    
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_NORMAL)
  cvMoveWindow(#CV_WINDOW_NAME, -1000, -1000)
  cvResizeWindow(#CV_WINDOW_NAME, 640, 480)
  window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
  hWnd = GetParent_(window_handle)
  ShowWindow_(hWnd, #SW_HIDE)
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  
  *frame2 = cvQueryFrame(*capture2)  
  *smallImg = cvCreateImage(160, 120, #IPL_DEPTH_8U, *frame2\nChannels)
  cvResize(*frame2, *smallImg, #CV_INTER_AREA)  
   
   *mask = cvCloneImage(*smallImg)
   cvSet(*mask, 0, 0, 0, 0, #Null)
   
   cntr.c = 0 
     
  If OpenWindow(0, 0, 0, 640, 480, #CV_WINDOW_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    SetParent_(window_handle, WindowID(0))  
    
    Repeat
      *frame1 = cvQueryFrame(*capture)
      
      If *frame1
        cntr + 1
        If cntr%4 = 1
          *smallImg = cvQueryFrame(*capture2)          
        EndIf        
        cvSetImageROI(*frame1, 10, 10, 160, 120)
        cvAnd(*frame1, *mask, *frame1, 0)
        cvAdd(*frame1, *smallimg, *frame1, #Null)
        cvResetImageROI(*frame1)
        cvShowImage(#CV_WINDOW_NAME, *frame1)
        keyPressed = cvWaitKey(1)
      EndIf      
      
    Until WindowEvent() = #PB_Event_CloseWindow
  EndIf
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)  
  cvReleaseCapture(@*capture2)   
  cvReleaseImage(@*mask)  
  cvReleaseImage(@*smallImg)  
  cvReleaseImage(@*frame2)  
  cvReleaseImage(@*frame1)
EndIf
Good luck!
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Hi AAT,

The change you suggested to cv_cam_logo.pb is a personal choice, as I intended the transparency, but I see your point and will include it in the next update...

NOTE:
The same result can be accomplished with the addition of a single function: cvAndS(*image, 0, 0, 0, 0, *image, #Null).
P.S. My examples was simpler
But you had to format every logo to fit the screen resolution; and considering your PIP example, aren't you glad I followed my own direction? :wink:

The PIP example is going to be a great addition to the OpenCV package. I won't be adding it right away as I need a way to "fake" a second webcam - to demonstrate the example for those of us with only 1 to test with. I'm sure everyone who is following this thread is grateful for your contributions.

Cheers!
Last edited by JHPJHP on Tue Dec 17, 2013 5:54 am, edited 1 time in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Added some Functions, modified the cv_cam_logo.pb example to include a black background, if you prefer the transparency just REM out this line: cvAndS(*image, 0, 0, 0, 0, *image, #Null)... or modify to change the color.

The new example: cv_cam_angle.pb - is something I wanted to bring to the package ever since I saw this video (link includes original source).

Image

Cheers!
Last edited by JHPJHP on Sat Jan 18, 2014 10:30 pm, edited 6 times in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Added some Constants and Functions, and one example: cv_face.pb.

This example tries to detect frontal-faces of different sizes using Haar Cascades.

I've optimized the setting to suit photos I had on hand, but there may be setting that will fit your requirements better; see the following article for more information: http://fewtutorials.bravesites.com/entr ... -detection

I've also included in the binaries folder other Haar-cascade classifiers (may also improve detection).
- haarcascade_frontalface_alt.xml
- haarcascade_frontalface_alt_tree.xml
- haarcascade_frontalface_alt2.xml
- haarcascade_frontalface_default.xml

NB*: Danilo scripted a similar example months ago: http://www.purebasic.fr/english/viewtop ... 13&t=53868

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

*** UPDATED ***
- updated cv_face.pb: now cv_face_1a.pb

Added another 6 examples:
- cv_equalize.pb
- cv_pyrdown.pb
- cv_pyrup.pb
- cv_face_1b.pb
- cv_cam_face_1a.pb
- cv_cam_face_1b.pb

The cv_equalize.pb, cv_pyrdown.pb, and cv_pyrup.pb examples were only added because I was testing various methods to speed up and improve accuracy for the face detection examples; seems to have worked.
- two techniques
-- downsampling (this one works better for my environment)
-- equalizing the histogram

Here is a great article on how to improve the process and also add some functionality: http://www.shervinemami.info/faceRecognition.html

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

*** UPDATED ***
- added a simple Abs function to make the Face Detection on the webcam less jumpy
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Wow! It's very impressive!
It seemed to me that the example of cv_cam_face_1b.pb is steadier against face turns, isn't it?
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Thanks AAT,
It seemed to me that the example of cv_cam_face_1b.pb is steadier against face turns, isn't it?
That's a good observation...
- just tested on my system (low resolution webcam): cv_cam_face_1a.pb seems to be more accurate, but it's hard to tell; they're very close
-- you may be getting more accurate results with your high resolution webcam

It really comes down to a mix and match of setting to classifier to suit your needs and environment; what fits your requirements may not work for someone else.

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

Added Constants, Structures, Functions, and updated cv_cam_face_1a.pb & cv_cam_face_1b.pb (adding a break to the Sequence loop improved performance).
- added the rest of the functions located in: opencv_objdetect247.lib
- added a couple groups of Dynamic Structures, but have not tested them

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

Observation
I wrote the Face Detection (webcam) examples late last night, and while testing - the results were really good, but this morning there is a noticeable reduction in performance. The brighter the room the more "noise" the webcam picks up, and the less accurate the results are; maybe one of the several filters from the other examples will address this.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

JHPJHP,
I could not get the example "cv_cam_angle.pb" to work.
How do you set up the parameters of the program?
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

I could not get the example "cv_cam_angle.pb" to work.
How do you set up the parameters of the program?
Because I don't have a blue and red marker, I used a folded blue RJ45 cable and a folded red RJ45 cable.
- point the ends at the camera, the script and OpenCV driver will do the rest
- hold red in your right hand (would be obvious once it activated)

Let me know.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Observation
I wrote the Face Detection (webcam) examples late last night, and while testing - the results were really good, but this morning there is a noticeable reduction in performance. The brighter the room the more "noise" the webcam picks up, and the less accurate the results are; maybe one of the several filters from the other examples will address this.
Combined and modified examples to optimize effect:
- cv_cam_face_1a.pb & cv_cam_face_1b.pb to cv_cam_face.pb
- cv_face_1a.pb & cv_face_1b.pb to cv_face.pb.

Also something to note (fixed in all examples): ClearMemStorage
The function resets the top (free space boundary) of the storage to the very beginning. This function does not deallocate
any memory. If the storage has a parent, the function returns all blocks to the parent.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Updated, and optimized all the examples...

Includes face detection accuracy, speed improvements to rotation, flipping the webcam image to mirror perspective, as well as numerous other changes.

cv_face.pb
I was testing the accuracy of this example on a personal photo of twelve people. With the existing size parameters: 40, 40 - it returned 2 matches, by adjusting the size parameter to: 0, 0 - it returned 10 matches; the two people missed were wearing glasses.

Code: Select all

cvHaarDetectObjects(*resize2, *cascade, *storage, 1.1, 2, #CV_HAAR_DO_CANNY_PRUNING, 40, 40, 0, 0)
------------------------------------------------

Added 1 example: cv_cam_PIP.pb (jointly contributed by AAT); with mixed results...
- when I tested it with one webcam it worked as it should
- when AAT tested it with two webcams it worked as it should, but when he tested it with a single webcam it returned nothing

I made a small change to the code, but until I get additional conformation one way or the other, I can't say for certain whether it will work correctly.

Cheers!
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Added Constants, Structures, and Functions, modified 3 examples, and added 5 examples.

Modified:
cv_cam_PIP.pb
pb_cam_effects_1.pb
pb_cam_effects_2.pb

Added:
cv_hough_1a.pb: finds lines in a binary image using the standard Hough transform
cv_hough_1b.pb: finds lines in a binary image using the probabilistic Hough transform
cv_hough_2.pb: finds circles in a grayscale image using the Hough transform
cv_pow.pb: raises every array element to a power
cv_swap_3.pb: divides a multi-channel array into several single-channel arrays, then recreates a multi-channel array by combining them

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

Added a new include file: pb_procedures.pbi, and added a tooltip to all the examples.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Added Constants, Functions, and updated 1 Structure.

Added binaries
-- opencv_photo247.dll
-- opencv_photo247.lib

Updated the example cv_border.pb: added the ability to draw on the image; it was originally used to test a Mouse Callback feature needed in the new example, but decided not to remove it.

Added 1 example: cv_inpaint.pb
- restores the selected region in an image using the region neighborhood

If there are imperfections on an image such as scratches that you would like to blend-out, this example demonstrates how it can be accomplished using OpenCV.
- use the mouse to draw over a scratch, then press the Spacebar to apply the repair, press any other key to reset the image back to default

NB*: No changes are made to the image, as the example does not include a Save option.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Added Constants, Functions, and 1 Procedure, including a Save option to the context menu of all relevant examples.
-- if the image was resized to fit the screen, the resized (modified) version is saved

I figured after the last example...
Added 1 example: cv_inpaint.pb
- restores the selected region in an image using the region neighborhood

If there are imperfections on an image such as scratches that you would like to blend-out, this example demonstrates how it can be accomplished using OpenCV.
- use the mouse to draw over a scratch, then press the Spacebar to apply the repair, press any other key to reset the image back to default
... it would be useful to have the ability to save the example effects.
Last edited by JHPJHP on Wed Dec 18, 2013 11:22 am, edited 1 time in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Updated the OpenCV binaries from v2.4.7 to v2.4.7.2.
- updated manual.pdf
- added tutorials.pdf

I've tested most of the examples, and they're working as expected; made some minor changes, but nothing worth mentioning.

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

Added 11 default test images to the \binaries\images folder.
- chessboard.jpg, faces.jpg, hand.png, nebula.jpg, planets.jpg, rubix.jpg
- chip1.jpg, chip2.jpg, chip3.jpg, chip4.jpg, contour.bmp (provided by AAT)

Some of the examples have predefined uses, and require a certain type of image to better demonstrate the effect; for these I've added a default image that will load on open. I've also updated the description, and modified some settings.
- cv_contours_1a.pb, cv_contours_1b.pb, cv_contours_1c.pb, cv_contours_2.pb, cv_contours_3a.pb, cv_contours_3b.pb, cv_contours_4.pb, cv_contours_5.pb
- cv_hough_1a.pb, cv_hough_1b.pb, cv_hough_2.pb

The following examples have also been updated to include a default image (my test files for the new changes).
- cv_border.pb, cv_face.pb
Locked