PureBasic Interface to OpenCV

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PureBasic Interface to OpenCV

Post by djes »

Ok, thank you both !
normeus
Enthusiast
Enthusiast
Posts: 414
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: PureBasic Interface to OpenCV

Post by normeus »

I used OpenCV32 to add text as an image to a jpg image and that worked well, ( it was fun ).
So I figured I would create a sample adding a different font as a PB image. When I did it with a jpeg it was just adding transparent text and the text was white so no big deal. For my sample I added color to the text and that didn't look good so I figured I have to create a mask, inverse the mask, merge the mask with ROI then add image to result but no joy.

This sample code reads the first 60 frames of ball.mp4 which is located in the /binaries/video
writes outtext.avi to /Videos
here is my test code in case someone wants to give it a go. ( it has a lot of comments of things I have tried )

Code: Select all

;OpenCV32
UseJPEGImageDecoder()
UseJPEGImageEncoder()

IncludeFile "includes/cv_functions.pbi"
EnableExplicit
Global PBfont=LoadFont(#PB_Any ,"Arial",18,#PB_Font_HighQuality|#PB_Font_Bold )
Global *writer , *capture.CvCapture,*decode.IplImage,*image.IplImage,*convert.iplImage
Global video_W=360,Video_H=288,FPS=30
Define nCreate,cnt,movex,FrameCount.d

Procedure PBPutText(text.s="add image demo")
  Protected img,w,h,*buffer,*mat.CvMat
  
  img= CreateImage(#PB_Any, 100, 30,32)
  If img And StartDrawing(ImageOutput(img))
    DrawingFont(FontID(PBfont))  
    DrawingMode( #PB_2DDrawing_Transparent  )
    DrawText(5, 4, text,$00410000)
    DrawText(1,1, text,$000C7CC5)
    StopDrawing()
  EndIf
  If IsImage(img)   
    *buffer = EncodeImage(img, #PB_ImagePlugin_JPEG)
    *mat = cvCreateMatHeader(ImageWidth(img), ImageHeight(img), CV_MAKETYPE(#CV_8U, 3))
      cvSetData(*mat, *buffer, #CV_AUTOSTEP)   
      *decode = cvDecodeImage(*mat,#CV_LOAD_IMAGE_COLOR); #CV_LOAD_IMAGE_COLOR) 
     FreeImage(img) 
  EndIf
  
EndProcedure

PBPutText("JHPJHP") 

*writer = cvCreateVideoWriter("/videos/outtext.avi", CV_FOURCC("D", "I", "V", "X"), FPS,video_W,video_H, #True); 360,300,#True);960,720, #True) 
Repeat
  nCreate + 1
  *capture = cvCreateFileCapture("binaries/videos/ball.mp4")
Until nCreate = 5 Or *capture
FrameCount = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_COUNT) 
movex=1

Repeat
  *image = cvQueryFrame(*capture)
  If *image
    
    cvSetImageROI(*image,movex,10,100,20) ; Location of moving text
    Define        *iroi.IplImage = cvCreateImage(100, 20, *image\depth, *image\nChannels) ;section of image to transform 
    cvcopy(*image, *iroi,#Null) 
    *convert = cvCreateImage(100, 20, *decode\depth, *decode\nChannels) ; in case the image I create is a different size 
    cvResize(*decode, *convert, #CV_INTER_AREA)
    ;cvcvtcolor(*decode,*convert,#CV_RGBA2BGR,1)  ;I wish It was as simple as changing color
   
    Define        *tgray.IplImage = cvCreateImage(100, 20, #IPL_DEPTH_8U, 1)  ; create temp gray image
    cvCvtColor(*convert, *tgray, #CV_BGR2GRAY,1) ; get our letters turn them gray 1 channel
    Define    *gray.IplImage = cvCreateImage(100, 20, #IPL_DEPTH_8U, 3)  ; go back to 3 channels

    cvThreshold(*tgray, *tgray, 50, 255, #CV_THRESH_BINARY )   ; mask
    cvCvtColor(*tgray, *gray, #CV_GRAY2BGR,1) ; back to 3 channel
    
    Define    *notgray.IplImage = cvCreateImage(100, 20, #IPL_DEPTH_8U, 3) ; I want to not the LETTERS so that iroi displays fine
    cvnot(*gray,*notgray)
    ;cvand(*iroi,*notgray,*iroi, #Null)  ;  and notgray to create mask 
    ;cvand(*convert,*iroi,*convert,#Null)  add mask to original LETTERS
    cvAdd(*image,*convert,*image,#Null)

    cvResetImageROI(*image)
    
    cvWriteFrame(*writer, *image)
    Debug cnt
  Else
    Break
  EndIf
  cnt+1
  movex +5
  If movex > 250 : movex=250:EndIf
  Until cnt> 60
;Until cnt>FrameCount

cvReleaseVideoWriter(@*writer) 
[edit] My keyboard is acting up. I cannot even do a copy and paste :shock:
deleted double paste Oct 16,2017. thank you @AAT
Norm.
Last edited by normeus on Mon Oct 16, 2017 4:09 pm, edited 1 time in total.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi normeus,

Sorry, I am not sure I correctly understood your goal, was it to add text to a video using any font?

The simple solution is to use the Function cvPutText to directly write to each video frame; see cv_video_writeframe.pb.

This can be combined with the logic provided by AAT in the example cv_pb_font.pb, where PureBasic is combined with OpenCV to draw text onto an image.

NB*: I really like your example demonstrating the "Ken Burnes effect", and when time permits will include it into the OpenCV packages.
normeus
Enthusiast
Enthusiast
Posts: 414
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: PureBasic Interface to OpenCV

Post by normeus »

JHPJHP,

actually my trouble began with me wanting to use white text on an image. Like you can with cvputText().
I was not able to do it.

I should have known that you had a working example of what I was trying to do.
My original code was in C++ with another library so I decided it would be easier to do it in PureBasic using an image.

I will try to at least read the names of the examples. Examples are there for a reason!!!

@AAT, Sorry about the confusion, about the example you had already created.



Thank you.
Norm.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

normeus wrote:I will try to at least read the names of the examples. Examples are there for a reason!!!
Sometimes I think it would be useful to make a guide to the examples.
Sometimes I think that reading a few lines of "#CV_DESCRIPTION =..." in the example is not very difficult, it's even possible to write a script that will make a general description for all examples from this lines.
Sometimes...
normeus
Enthusiast
Enthusiast
Posts: 414
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: PureBasic Interface to OpenCV

Post by normeus »

So the problem was that I wanted to use white text with a black shadow just like cvputText().
On the library I was using I had to turn to gray, mask the inverse, etc... So I came to PB with that mindset.

On the cv_pb_font.pb example, I fixed the colors to black and white and created a second image.
Had to use "DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_Gradient)" to create text.
Then cvSub shadow then cvAdd white font.
Still kicking myself for not looking at the examples
[edit] Adding blur as recommended by AAT in the comment below. It looks a lot better

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global openCV, *save.IplImage, exitCV, lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "Draw text using PureBasic commands with any font onto an OpenCV generated image." + #LF$ + #LF$ +
                  "SPACEBAR    " + #TAB$ + ": Change to another font."

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Select uMsg
    Case #WM_COMMAND
      Select wParam
        Case 1
          openCV = #True
          keybd_event_(#VK_ESCAPE, 0, 0, 0)
        Case 2
          FileName.s = SaveCVImage()

          If FileName
            params.CvSaveData

            Select LCase(GetExtensionPart(FileName))
              Case "bmp", "dib"
              Case "jpeg", "jpg", "jpe"
                params\paramId = #CV_IMWRITE_JPEG_QUALITY
                params\paramValue = 95
              Case "jp2"
              Case "png"
                params\paramId = #CV_IMWRITE_PNG_COMPRESSION
                params\paramValue = 3
              Case "ppm", "pgm", "pbm"
                params\paramId = #CV_IMWRITE_PXM_BINARY
                params\paramValue = 1
              Case "sr", "ras"
              Case "tiff", "tif"
              Default
                Select SelectedFilePattern()
                  Case 0
                    FileName + ".bmp"
                  Case 1
                    FileName + ".jpg"
                    params\paramId = #CV_IMWRITE_JPEG_QUALITY
                    params\paramValue = 95
                  Case 2
                    FileName + ".jp2"
                  Case 3
                    FileName + ".png"
                    params\paramId = #CV_IMWRITE_PNG_COMPRESSION
                    params\paramValue = 3
                  Case 4
                    FileName + ".ppm"
                    params\paramId = #CV_IMWRITE_PXM_BINARY
                    params\paramValue = 1
                  Case 5
                    FileName + ".sr"
                  Case 6
                    FileName + ".tiff"
                EndSelect
            EndSelect
            cvSaveImage(FileName, *save, @params)
          EndIf
        Case 10
          keybd_event_(#VK_ESCAPE, 0, 0, 0)
      EndSelect
    Case #WM_DESTROY
      exitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure CvMouseCallback(event, x.l, y.l, flags, *param.CvUserData)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      *save = *param\Pointer1
      DisplayPopupMenu(0, *param\Value)
  EndSelect
EndProcedure

Procedure OpenCV(ImageFile.s)
  If FileSize(ImageFile) > 0
    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, "Save")
      MenuBar()
      MenuItem(10, "Exit")
    EndIf
    hWnd = GetParent_(window_handle)
    iconCV = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
    SendMessage_(hWnd, #WM_SETICON, 0, iconCV)
    wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
    SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
    *image.IplImage = cvLoadImage(ImageFile, #CV_LOAD_IMAGE_ANYDEPTH | #CV_LOAD_IMAGE_ANYCOLOR)
    dtWidth = DesktopWidth(0) : dtHeight = DesktopHeight(0)

    If *image\width >= dtWidth - 100 Or *image\height >= dtHeight - 100
      iWidth = dtWidth - 100
      iRatio1.d = iWidth / *image\width
      iHeight = dtHeight - 100
      iRatio2.d = iHeight / *image\height

      If iRatio1 < iRatio2
        iWidth = *image\width * iRatio1
        iHeight = *image\height * iRatio1
      Else
        iWidth = *image\width * iRatio2
        iHeight = *image\height * iRatio2
      EndIf
      cvResizeWindow(#CV_WINDOW_NAME, iWidth, iHeight)
      *resize.IplImage = cvCreateImage(iWidth, iHeight, #IPL_DEPTH_8U, *image\nChannels)
      cvResize(*image, *resize, #CV_INTER_AREA)
    Else
      cvResizeWindow(#CV_WINDOW_NAME, *image\width, *image\height)
      *resize.IplImage = cvCloneImage(*image)
    EndIf
    cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
    ToolTip(window_handle, #CV_DESCRIPTION)

    If *resize\width >= 640 And *resize\height >= 480 And *resize\nChannels = 3
      *reset.IplImage = cvCloneImage(*resize)
      *mask.IplImage = cvCreateImage(*resize\width, 80, #IPL_DEPTH_8U, *resize\nChannels)
      *maskShadow.IplImage = cvCloneImage(*mask)
      pbImage = CreateImage(#PB_Any, *mask\width, 80, 24, RGB(0, 0, 0))
      pbImageShadow = CreateImage(#PB_Any, *mask\width, 80, 24, RGB(0, 0, 0))
      fontName.s = "Comic Sans MS"
      nFont = LoadFont(#PB_Any, fontName, 36, #PB_Font_HighQuality)

      If *resize\width = 640 : fontX = 20 : Else : fontX = (*resize\width - 640) / 2 + 20 : EndIf : fontY = 5

      font.CvFont : cvInitFont(@font, #CV_FONT_HERSHEY_COMPLEX | #CV_FONT_ITALIC, 1, 1, #Null, 1, #CV_AA)
      *param.CvUserData = AllocateMemory(SizeOf(CvUserData))
      *param\Pointer1 = *resize
      *param\Value = window_handle
      cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)

      Repeat
        If *resize
          cvSetZero(*mask)
          cvSetZero(*maskShadow)
          If StartDrawing(ImageOutput(pbImage))
            DrawingFont(FontID(nFont))
           DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_Gradient   )
            DrawText(fontX, fontY, "Use any font with OpenCV!", $00000000)
            *mask\imageData = DrawingBuffer()
            StopDrawing()
          EndIf
          If StartDrawing(ImageOutput(pbImageShadow))
            DrawingFont(FontID(nFont))
            DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_Gradient   )
            DrawText(fontX+5, fontY+5, "Use any font with OpenCV!", $FFFFFFFF) ; +5 to see the effect
            *maskShadow\imageData = DrawingBuffer()
            StopDrawing()
          cvSmooth(*maskShadow, *maskShadow, #CV_GAUSSIAN, 13, 13, 0, 0) ; <----- blurring the shadow
          EndIf          
          cvFlip(*mask, #Null, 0)
          cvFlip(*maskShadow, #Null, 0)
          cvSetImageROI(*resize, 0, *resize\height - 100, *resize\width, 80)
          ;cvAddS(*resize, 70, 70, 70, 0, *resize, 0)
          cvSub(*resize, *maskShadow, *resize, 0)
          cvAdd(*resize, *mask, *resize, 0)
          cvResetImageROI(*resize)
          cvPutText(*resize, fontName, 7, 30, @font, 0, 0, 0, 0)
          cvPutText(*resize, fontName, 5, 28, @font, 255, 255, 255, 0)
          cvShowImage(#CV_WINDOW_NAME, *resize)
          keyPressed = cvWaitKey(0)

          If keyPressed = 32
            newfont = (newfont + 1) % 10
            FreeFont(nFont)

            Select newfont
              Case 0
                fontName = "Comic Sans MS"
                fontY = 5
                nFont = LoadFont(#PB_Any, "Comic Sans MS", 36, #PB_Font_HighQuality)
              Case 1
                fontName = "Arial"
                fontY = 12
                nFont = LoadFont(#PB_Any, "Arial", 37, #PB_Font_HighQuality)
              Case 2
                fontName = "Impact"
                fontY = 8
                nFont = LoadFont(#PB_Any, "Impact", 42, #PB_Font_HighQuality)
              Case 3
                fontName = "Times New Roman"
                fontY = 10
                nFont = LoadFont(#PB_Any, "Times New Roman", 40, #PB_Font_HighQuality)
              Case 4
                fontName = "Verdana"
                fontY = 14
                nFont = LoadFont(#PB_Any, "Verdana", 33, #PB_Font_HighQuality)
              Case 5
                fontName = "Courier New"
                fontY = 22
                nFont = LoadFont(#PB_Any, "Courier New", 30, #PB_Font_HighQuality)
              Case 6
                fontName = "Tahoma"
                fontY = 8
                nFont = LoadFont(#PB_Any, "Tahoma", 38, #PB_Font_HighQuality)
              Case 7
                fontName = "Modern"
                fontY = 8
                nFont = LoadFont(#PB_Any, "Modern", 44, #PB_Font_Bold | #PB_Font_HighQuality)
              Case 8
                fontName = "Georgia"
                fontY = 14
                nFont = LoadFont(#PB_Any, "Georgia", 37, #PB_Font_HighQuality)
              Case 9
                fontName = "Garamond"
                fontY = 12
                nFont = LoadFont(#PB_Any, "Garamond", 37, #PB_Font_HighQuality)
            EndSelect
          EndIf
          cvReleaseImage(@*resize)
          *resize = cvCloneImage(*reset)
        EndIf
      Until keyPressed = 27 Or exitCV
      FreeMemory(*param)
      FreeFont(nFont)
      FreeImage(pbImage)
      cvReleaseImage(@*mask)
      cvReleaseImage(@*reset)
      cvReleaseImage(@*resize)
      cvReleaseImage(@*image)
      cvDestroyAllWindows()

      If openCV
        openCV = #False
        exitCV = #False
        OpenCV(OpenCVImage())
      EndIf
    Else
      If *resize\nChannels = 3
        MessageRequester(#CV_WINDOW_NAME, ImageFile + #LF$ + #LF$ + "... does not meet the size requirements, please try another image.", #MB_ICONERROR)
      Else
        MessageRequester(#CV_WINDOW_NAME, ImageFile + #LF$ + #LF$ + "... does not meet the channel requirements, please try another image.", #MB_ICONERROR)
      EndIf
      cvReleaseImage(@*resize)
      cvReleaseImage(@*image)
      cvDestroyAllWindows()
      exitCV = #False
      OpenCV(OpenCVImage())
    EndIf
  EndIf
EndProcedure

ExamineDesktops()
OpenCV("images/colors.jpg")
Norm.
Last edited by normeus on Sun Oct 22, 2017 9:50 pm, edited 1 time in total.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, normeus

Try to blur the shadow, it will see more realistic. Forexample

Code: Select all

...
          If StartDrawing(ImageOutput(pbImageShadow))
            DrawingFont(FontID(nFont))
            DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_Gradient   )
            DrawText(fontX+5, fontY+5, "Use any font with OpenCV!", $FFFFFFFF)
            *maskShadow\imageData = DrawingBuffer()
            StopDrawing()
            cvSmooth(*maskShadow, *maskShadow, #CV_GAUSSIAN, 13, 13, 0, 0) ; <----- blurring the shadow
          EndIf
...
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 636
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: PureBasic Interface to OpenCV

Post by captain_skank »

Hi,

Been mucking about with this excellent library recently and have been using it to view a RTSP feed.

The ip camera i'm using has an output of 1920*1080, but is there a way to scale resize the output on the screen to a smaller image - quality isn't important.

Any advice appreciated.

Cheers
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 636
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: PureBasic Interface to OpenCV

Post by captain_skank »

Nevermind - found it :

Code: Select all

cvResizeWindow()
is what i was after.

On another item is is there a correct way to change feeds ? I want to cycle through 6 different ip cameras.

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

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi captain_skank,
captain_skank wrote:On another item is is there a correct way to change feeds ? I want to cycle through 6 different ip cameras.
NOTE: You could also include an option to have all six cameras displaying at the same time; relatively easy using OpenCV.

Windows / OpenCV 32
- set Compiler--Compiler Options--Compile/Run--Current directory: binaries\

Instead of cvResizeWindow see the following example that uses cvResize:
- KEYS 1 - 7 (allow time for cameras to load)

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "View RTSP (Real Time Streaming Protocol) feeds." + #LF$ + #LF$ +
                  "[ 1-7 ] KEYS" + #TAB$ + ": Change Feed."

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Shared exitCV

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

Procedure CaptureFeed(Array arrRTSP.s(1), nFeed)
  *capture.CvCapture

  If *capture : cvReleaseCapture(@*capture) : EndIf

  Repeat
    nCreate + 1
    *capture = cvCreateFileCapture(arrRTSP(nFeed) + "?Transport=multicast")
  Until nCreate = 5 Or *capture
  ProcedureReturn *capture
EndProcedure

Procedure ResizeFrame(*capture, MaxSize)
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)

  If FrameWidth > MaxSize
    nRatio.d = MaxSize / FrameWidth
    FrameWidth * nRatio : FrameHeight * nRatio
  EndIf
  *frame.IplImage

  If *frame : cvReleaseImage(@*frame) : EndIf

  *frame = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 3)
  ProcedureReturn *frame
EndProcedure

Dim arrRTSP.s(7)
arrRTSP(0) = "http://live.wazcam.net/live/quds.stream/playlist.m3u8"
arrRTSP(1) = "http://live.wazcam.net/live/kana.stream/playlist.m3u8"
arrRTSP(2) = "http://live.wazcam.net/live/tamra.stream/playlist.m3u8"
arrRTSP(3) = "http://live.wazcam.net/live/big.stream/playlist.m3u8"
arrRTSP(4) = "http://live.wazcam.net/live/city2.stream/playlist.m3u8"
arrRTSP(5) = "http://live.wazcam.net/live/mashhad.stream/playlist.m3u8"
arrRTSP(6) = "http://live.wazcam.net/live/reneh.stream/playlist.m3u8"
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())
hWnd = GetParent_(window_handle)
iconCV = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
SendMessage_(hWnd, #WM_SETICON, 0, iconCV)
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)
*capture = CaptureFeed(arrRTSP(), 0)
*frame = ResizeFrame(*capture, 640)
*image.IplImage
font.CvFont : cvInitFont(@font, #CV_FONT_HERSHEY_COMPLEX_SMALL, 2, 2, #Null, 2, #CV_AA)

Repeat
  *image = cvQueryFrame(*capture)

  If *image
    cvResize(*image, *frame, #CV_INTER_AREA)
    cvPutText(*frame, "RTSP Feed: " + Str(nFeed + 1), 30, 60, @font, 0, 255, 255, 0)
    cvShowImage(#CV_WINDOW_NAME, *frame)
    keyPressed = cvWaitKey(10)

    Select keyPressed
      Case 49 To 55
        nFeed = keyPressed - 49
        *capture = CaptureFeed(arrRTSP(), nFeed)
        *frame = ResizeFrame(*capture, 640)
    EndSelect
  Else
    Break
  EndIf
Until keyPressed = 27 Or exitCV

If *frame : cvReleaseImage(@*frame) : EndIf

cvDestroyAllWindows()

If *capture : cvReleaseCapture(@*capture) : EndIf
Last edited by JHPJHP on Fri Nov 10, 2017 2:05 pm, edited 1 time in total.
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 636
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: PureBasic Interface to OpenCV

Post by captain_skank »

Hi JHPJHP,

Thanks for the reply and code.

Unfortunately the code provided won't run - it throws an error 'The code execution cannot proceed becasue opencv_world330.dll was not found'

I have checked and the .dll is in the binaries folder.

As an aside I did get a similar version of what you proposed working using cv_webcam_text.pb as a starting point. It's not pretty and will probably crash more times than a plane wihthout wings :)

I would be interested in knowing how to display multiple feeds at once though.

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

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi captain_skank,
captain_skank wrote:Unfortunately the code provided won't run - it throws an error 'The code execution cannot proceed becasue opencv_world330.dll was not found'
My fault, I should have asked which version of the interface you downloaded.

Not a problem, I can convert the code to work with the World version, but if you're not tied to that package, it might be better for you to download:
- Main Download: PureBasic Interface to OpenCV 2.4.13.3 :: 32 bit
-- more examples (includes the legacy Functions)
-- smaller size standalone applications (individual binaries)
captain_skank wrote:I would be interested in knowing how to display multiple feeds at once though.
*** The previous (updated) / following example should only be used as a guide to a more robust solution ***

Very slow to load the six feeds; would be faster with local cameras or a better connection.
- Main Download: PureBasic Interface to OpenCV 2.4.13.3 :: 32 bit

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "View 6 RTSP (Real Time Streaming Protocol) feeds."

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Shared exitCV

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

Dim arrRTSP.s(6) : Dim *capture.CvCapture(6)
arrRTSP(0) = "http://live.wazcam.net/live/quds.stream/playlist.m3u8"
arrRTSP(1) = "http://live.wazcam.net/live/kana.stream/playlist.m3u8"
arrRTSP(2) = "http://live.wazcam.net/live/tamra.stream/playlist.m3u8"
arrRTSP(3) = "http://live.wazcam.net/live/big.stream/playlist.m3u8"
arrRTSP(4) = "http://live.wazcam.net/live/city2.stream/playlist.m3u8"
arrRTSP(5) = "http://live.wazcam.net/live/mashhad.stream/playlist.m3u8"

For rtnCount = 0 To ArraySize(*capture()) - 1
  Repeat
    nCreate + 1
    *capture(rtnCount) = cvCreateFileCapture(arrRTSP(rtnCount) + "?Transport=multicast")
  Until nCreate = 5 Or *capture(rtnCount)
  nCreate = 0
Next
FrameWidth = cvGetCaptureProperty(*capture(0), #CV_CAP_PROP_FRAME_WIDTH)
FrameHeight = cvGetCaptureProperty(*capture(0), #CV_CAP_PROP_FRAME_HEIGHT)

If FrameWidth > 320
  nRatio.d = 320 / FrameWidth
  FrameWidth * nRatio : FrameHeight * nRatio
EndIf
*frame.IplImage = cvCreateImage(FrameWidth * 3, FrameHeight * 2, #IPL_DEPTH_8U, 3)
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())
hWnd = GetParent_(window_handle)
iconCV = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
SendMessage_(hWnd, #WM_SETICON, 0, iconCV)
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)
*image1.IplImage : *image2.IplImage : *image3.IplImage : *image4.IplImage : *image5.IplImage : *image6.IplImage
font.CvFont : cvInitFont(@font, #CV_FONT_HERSHEY_COMPLEX_SMALL, 1, 1, #Null, 1, #CV_AA)

Repeat
  *image1 = cvQueryFrame(*capture(0)) : *image2 = cvQueryFrame(*capture(1)) : *image3 = cvQueryFrame(*capture(2))
  *image4 = cvQueryFrame(*capture(3)) : *image5 = cvQueryFrame(*capture(4)) : *image6 = cvQueryFrame(*capture(5))

  If *image1 And *image2 And *image3 And *image4 And *image5 And *image6
    cvSetImageROI(*frame, 0, 0, FrameWidth, FrameHeight)
    cvResize(*image1, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", 20, 30, @font, 0, 255, 255, 0)
    cvSetImageROI(*frame, FrameWidth, 0, FrameWidth, FrameHeight)
    cvResize(*image2, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", FrameWidth + 20, 30, @font, 0, 255, 255, 0)
    cvSetImageROI(*frame, FrameWidth * 2, 0, FrameWidth, FrameHeight)
    cvResize(*image3, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", FrameWidth * 2 + 20, 30, @font, 0, 255, 255, 0)
    cvSetImageROI(*frame, 0, FrameHeight, FrameWidth, FrameHeight)
    cvResize(*image4, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", 20, FrameHeight + 30, @font, 0, 255, 255, 0)
    cvSetImageROI(*frame, FrameWidth, FrameHeight, FrameWidth, FrameHeight)
    cvResize(*image5, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", FrameWidth + 20, FrameHeight + 30, @font, 0, 255, 255, 0)
    cvSetImageROI(*frame, FrameWidth * 2, FrameHeight, FrameWidth, FrameHeight)
    cvResize(*image6, *frame, #CV_INTER_AREA)
    cvResetImageROI(*frame)
    cvPutText(*frame, "----", FrameWidth * 2 + 20, FrameHeight + 30, @font, 0, 255, 255, 0)
    cvShowImage(#CV_WINDOW_NAME, *frame)
    keyPressed = cvWaitKey(10)
  Else
    Break
  EndIf
Until keyPressed = 27 Or exitCV
cvReleaseImage(@*frame)
cvDestroyAllWindows()

For rtnCount = 0 To ArraySize(*capture()) - 1
  If *capture(rtnCount) : cvReleaseCapture(@*capture(rtnCount)) : EndIf
Next
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 636
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: PureBasic Interface to OpenCV

Post by captain_skank »

Awesome stuff JHPJHP.

Thanks for all the help.

Gotta say this is an exceptional piece of work.

cheers
PeterH
User
User
Posts: 26
Joined: Sun Apr 11, 2010 11:01 am

Re: PureBasic Interface to OpenCV

Post by PeterH »

Exceptional doesn't even begin to cover it. I had no hopes at all for this when I stumbled upon it.

My lack of experience does however make it a bit hard to use. I would really love to see ready to use functions for example locating faces using all those different methods (Eigenfaces, Fisherfaces etc) in an image, with parameters such as scale and neighbors natively in the wrapper. Would make it easier to step through the code and learn it bit by bit, but still be able to use it from scratch.
The face recognition is impressive, but watching how some people combine the different methods, compare the results and save the final product makes the detection rate really high. If one then can save a face and in the future compare a detected face with all the saved ones, that would be fantastic. Not expecting anyone to do all that, but just throwing the idea out there. This is a fantastic extension to PB.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi captain_skank and PeterH,

Thank you both for your kind comments.

It bears repeating, two forum members who were main contributors to the interface.
- AAT: consistent support with the interface and examples throughout the Windows builds
- wilbert: invaluable support converting the Windows builds to OSX and Linux

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

PeterH, the following are some examples demonstrating OpenCV capabilities in face detection that could be adapted for face recognition.
- there are additional examples with techniques that could enhance results: skin detection, object detection, filter and selection, etc.

NOTE: Using a combination of the following methods can produce better results.

cv_webcam_matchtemplate.pb: good for object matching with little distortion
- use the mouse to draw a rectangle
- put an object (your face) inside the rectangle
- press the Spacebar to capture the object
-- M Key to switch the method
-- S Key to show / hide the match

cv_webcam_camshift.pb: uses histogram matching, distortion not a concern
- use the mouse to draw a rectangle around your face
-- press the Spacebar to show the histogram
-- P Key to toggle projection mode

cv_webcam_haardetect_face.pb: detects (front) facial features based on pre-trained files (binaries/haarcascade_frontalface)
- Trackbar 1: Adjust scale factor
- Trackbar 2: Set minimum neighbors
- press the Spacebar to change between the 4 trained HaarCascade files
-- M Key to add a funny mask
-- S Key to toggle scale-factor flag

The following two examples can be used to create accurate facial-recognition files.
- creates a HaarCascade trained file that can be used with cv_webcam_haardetect_face.pb

cv_webcam_haardetect_train_1.pb: uses newer training files
cv_webcam_haardetect_train_2.pb: uses older training files
- directions: references/haarcascade.txt

Other examples that might be of interest.
- cv_haardetect_face.pb: detect frontal-faces
- cv_matchtemplate.pb: match one face against many faces
- cv_norm.pb: match an image against a directory of images
Last edited by JHPJHP on Mon Jul 11, 2022 2:38 pm, edited 1 time in total.
Locked