libOpenCV Windows/Linux 32/64-bit

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by D.J.Peters »

I'm done 700 commands implemented !

does capture_loop works with your camera's ?
does the gui shown on your Linux box ?
does my windows 10 builds of ~40 MB works on your Windows XP, 7,8 box also ?

May be here works all ok but not on other boxes without any feedback I can't fix such problems.

joshy
Last edited by D.J.Peters on Mar 06, 2020 1:28, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by D.J.Peters »

badidea wrote:Tying not to be one of those 200 lazy coders, but I ran into a problem: The symbolic links (linux version) seem broken after unzipping.
can you post any error output please ?
what for a 64-bit linux distro do you use ?

(may be if I use a tar.gz file the problem are fixed)

Thank you for testing and support.

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by D.J.Peters »

BasicCoder2 wrote:But not any face tracking, eye tracking ?
Learning OpenCV is your job !

You posted you used OpenCV with other languages before !

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows/Linux 32/64-bit

Post by D.J.Peters »

To preserve linux file flags I use the tar.gz compressed file format now.

I added opencv_lin32.tar.gz also

(see first post)

To be independent from your support I visited my office and tested opencv successful on:

WindowsXP 32-bit
Window 7 32-bit
Wndows 10 32 and 64-bit
Linux Slackware 32-bit
Ubuntu 18.4 64-bit

There was one short problem on the Windows XP/7 32-bit boxes.

Both have a analog TV-tuner card with video input,
so I got with capture_loop.bas the white noise screen becourse analog TV is dead since years here.

With other words connected USB cams has a higher index than 0 on this boxes.

I changed the device enumeration loop the deviceIndex counts down from 1 to 0.
The internal TV capture cards will only be used if no extra USB camera (with higer index than 0 ) are connected.

Joshy

Code: Select all

#include "opencv.bi"

#ifdef __FB_WIN32__
  dim as long videoBackends(...) =>{ CV_CAP_DSHOW, CV_CAP_VFW }
#else
  dim as long videoBackends(...) =>{ CV_CAP_V4L2, CV_CAP_V4L }
#endif  

const size = ubound(videoBackends)+1

dim as CvCapture ptr capture
for deviceIndex as long = 1 to 0 step -1
  for index as integer = 0 to size-1
    capture = cvCreateCameraCapture(videoBackends(index)+deviceIndex)
    if capture = NULL then continue for
    if cvGrabFrame(capture) then exit for,for
    cvReleaseCapture(@capture) : capture = NULL
  next
next  

if capture = NULL then
  print "no active or connected capture device found !"
  beep : sleep :end 1
end if

dim as IplImage ptr videoImage
var videoCounter = 0
var videoWidth   = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH)
var videoHeight  = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT)
var videoFPS     = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS)
dim as long viodeoFOURCC = cvGetCaptureProperty(capture,CV_CAP_PROP_FOURCC)
dim as zstring ptr stringFOURCC = callocate(5)
*cptr(ulong ptr,stringFOURCC)=viodeoFOURCC

if videoFPS<=0 then videoFPS = 24
locate 1,1 : print videoWidth,videoHeight,*stringFOURCC,videoFPS

' create 'named' window
cvNamedWindow("winMain")
cvResizeWindow("winMain",videoWidth,videoHeight)

' loop while [ESC] not pressed
while cvWaitKey(1000/videoFPS)<>27
#if 1  
  ' grab and retrieve in one go
  videoImage = cvQueryFrame(capture)
#else
  if cvGrabFrame(capture) then
    videoImage = cvRetrieveFrame(capture)
  end if
#endif  
  if videoImage <> 0 then 
    cvShowImage("winMain",videoImage) 
    videoCounter+=1
    locate 2,1 : print videoCounter
    videoImage=NULL
  end if  
wend

cvReleaseCapture(@capture)
cvDestroyAllWindows()
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by D.J.Peters »

BasicCoder2 wrote:Can't see how to transfer an image captured by opencv to a FreeBASIC bitmap ...
Here are cvImageTofbImage() in action.

Of course you can make the FB screen larger than the video image to have space
for text, other images, or your own GUI controls ...

screenres videoWidth*1.5,videoHeight*1.5,32

By the way it's a good example of using the FreeBASIC ImageConvertRow() method.
Often RGB color images from capture device are in RGB 24 bit = 3 bytes per pixel
The FB screen or image is 4 byte per pixel in 24-bit and 32-bit mode and 2 byte in 16-bit mode
but never 3 bytes per pixel !

Joshy
file "fbimage_capture_loop.bas"

Code: Select all

#include "opencv.bi"
function cvImageToFBImage( cvImage as IplImage ptr) as any ptr
  dim as integer srcWidth,srcHeight,srcBytes,srcPitch,srcBits
  dim as integer dstWidth,dstHeight,dstBytes,dstPitch,dstBits
  dim as ubyte ptr dstPixels,srcPixels
  dim as any ptr fbImage
  if cvImage=NULL then return NULL
  if screenptr()=NULL then return NULL
  ' destination
  screeninfo dstWidth,dstHeight,dstBits,dstBytes
  fbImage   = ImageCreate(dstWidth,dstHeight,&HFFFFFF)
  ImageInfo fbImage,,,,dstPitch,dstPixels
  
  ' source
  srcWidth  = cvImage->width
  srcHeight = cvImage->height
  srcBytes  = cvImage->nChannels
  srcBits   = srcBytes shl 3
  srcPitch  = cvImage->widthStep
  srcPixels = cvImage->imageData
  ' get shortes dimension (in case cvImage or fbImage are smaller)
  srcWidth  = iif(srcWidth <dstWidth ,srcWidth ,dstWidth )
  srcHeight = iif(srcHeight<dstHeight,srcHeight,dstHeight)
  
  while srcHeight     ' false = don't swap red and blue
    ImageConvertRow ( srcPixels, srcBits, dstPixels, dstBits, srcWidth, false )
    srcPixels+=srcPitch
    dstPixels+=dstPitch
    srcHeight-=1
  wend
  return fbImage
end function

#ifdef __FB_WIN32__
  dim as long videoBackends(...) =>{ CV_CAP_DSHOW, CV_CAP_VFW }
#else
  dim as long videoBackends(...) =>{ CV_CAP_V4L2, CV_CAP_V4L }
#endif  

const size = ubound(videoBackends)+1

dim as CvCapture ptr capture
for deviceIndex as long = 1 to 0 step -1
  for index as integer = 0 to size-1
    capture = cvCreateCameraCapture(videoBackends(index)+deviceIndex)
    if capture = NULL then continue for
    if cvGrabFrame(capture) then exit for,for
    cvReleaseCapture(@capture) : capture = NULL
  next
next  

if capture = NULL then
  print "no active or connected capture device found !"
  beep : sleep :end 1
end if

dim as IplImage ptr cvImage
var videoWidth  = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH)
var videoHeight = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT)
var videoFPS    = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS)

screenres videoWidth ,videoHeight,32
' loop while [ESC] not pressed
while asc(inkey())<>27

  ' grab next videoframe and retrieve it in one go !
  cvImage = cvQueryFrame(capture)
  if cvImage <> NULL then
    var fbImage = cvImageToFBImage(cvImage)
    if fbImage then
      put (0,0),fbImage,PSET
      ImageDestroy(fbImage)
    end if  
    cvImage = NULL
  end if  
  sleep 10 '1000/videoFPS
wend

cvReleaseCapture(@capture)

Last edited by D.J.Peters on Mar 06, 2020 8:32, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows/Linux 32/64-bit

Post by D.J.Peters »

I added CopyCvImageToFBImage()

In the last fbImage example cvImageToFBImage() the fbImage was created new for every input captured frame !

But if you don't change the video resolution you can create the fbImage once for the whole capture session.

In this case CopyCvImageToFBImage() are the right choice.

By the way if your capture device supports different resolutions you can set the well known supported size with :
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, newWidth)
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, newHeight)

Joshy

Code: Select all

#include "opencv.bi"

function CopyCvImageToFBImage( fbImage as any ptr, cvImage as IplImage ptr) as boolean
  dim as integer srcWidth,srcHeight,srcBytes,srcPitch,srcBits
  dim as integer dstWidth,dstHeight,dstBytes,dstPitch,dstBits
  dim as ubyte ptr dstPixels,srcPixels
  if cvImage=NULL then return false
  if fbImage=NULL then return false
  ' source
  srcWidth  = cvImage->width
  srcHeight = cvImage->height
  srcBytes  = cvImage->nChannels
  srcBits   = srcBytes shl 3
  srcPitch  = cvImage->widthStep
  srcPixels = cvImage->imageData
  ' something wrong with the input cvImage return false ?
  if srcWidth <=0 or srcHeight<=0 or srcBytes<1 or srcPixels=NULL then return false
  
  ' destination something wrong return false
  if ImageInfo(fBImage,dstWidth,dstHeight,dstBytes,dstPitch,dstPixels) then return false    
  dstBits = dstBytes shl 3
  ' get shortes dimension (in case cvImage or fbImage are smaller)
  srcWidth  = iif(srcWidth <dstWidth ,srcWidth ,dstWidth )
  srcHeight = iif(srcHeight<dstHeight,srcHeight,dstHeight)
  ' copy cvImage to fbImage
  while srcHeight     ' false = don't swap red and blue
    ImageConvertRow ( srcPixels, srcBits, dstPixels, dstBits, srcWidth, false )
    srcPixels+=srcPitch
    dstPixels+=dstPitch
    srcHeight-=1
  wend
  return true
end function

function cvImageToFBImage( cvImage as IplImage ptr ) as any ptr
  dim as integer srcWidth,srcHeight,srcBytes,srcPitch,srcBits
  dim as integer dstWidth,dstHeight,dstBytes,dstPitch,dstBits
  dim as ubyte ptr dstPixels,srcPixels
  dim as any ptr fbImage
  if cvImage=NULL then return NULL
  if screenptr()=NULL then return NULL
  ' destination
  screeninfo dstWidth,dstHeight,dstBits,dstBytes
  fbImage   = ImageCreate(dstWidth,dstHeight,&HFFFFFF)
  ImageInfo fbImage,,,,dstPitch,dstPixels
  
  ' source
  srcWidth  = cvImage->width
  srcHeight = cvImage->height
  srcBytes  = cvImage->nChannels
  srcBits   = srcBytes shl 3
  srcPitch  = cvImage->widthStep
  srcPixels = cvImage->imageData
  ' get shortes dimension (in case cvImage or fbImage are smaller)
  srcWidth  = iif(srcWidth <dstWidth ,srcWidth ,dstWidth )
  srcHeight = iif(srcHeight<dstHeight,srcHeight,dstHeight)
  
  while srcHeight     ' false = don't swap red and blue
    ImageConvertRow ( srcPixels, srcBits, dstPixels, dstBits, srcWidth, false )
    srcPixels+=srcPitch
    dstPixels+=dstPitch
    srcHeight-=1
  wend
  return fbImage
end function


#ifdef __FB_WIN32__
  dim as long videoBackends(...) =>{ CV_CAP_DSHOW, CV_CAP_VFW }
#else
  dim as long videoBackends(...) =>{ CV_CAP_V4L2, CV_CAP_V4L }
#endif  

const size = ubound(videoBackends)+1

dim as CvCapture ptr capture
for deviceIndex as long = 1 to 0 step -1
  for index as integer = 0 to size-1
    capture = cvCreateCameraCapture(videoBackends(index)+deviceIndex)
    if capture = NULL then continue for
    if cvGrabFrame(capture) then exit for,for
    cvReleaseCapture(@capture) : capture = NULL
  next
next  

if capture = NULL then
  print "no active or connected capture device found !"
  beep : sleep :end 1
end if

dim as IplImage ptr cvImage
dim as      any ptr  fbImage
var videoWidth  = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH)
var videoHeight = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT)
var videoFPS    = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS)

'screenres videoWidth*1.5,videoHeight*1.5,32
screenres videoWidth ,videoHeight,32
fbImage = ImageCreate(videoWidth,videoHeight)

' loop while [ESC] not pressed
while asc(inkey())<>27

  ' grab next videoframe and retrieve it in one go !
  cvImage = cvQueryFrame(capture)
  if cvImage <> NULL then
    if CopycvImageToFBImage(fbImage, cvImage) = true then
      put (0,0),fbImage,PSET
    end if  
  end if  
  sleep 10 '1000/videoFPS
wend

cvReleaseCapture(@capture)
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by BasicCoder2 »

Joshy you are the gift that keeps on giving!
D.J.Peters wrote:You posted you used OpenCV with other languages before ! Joshy
Wishful thinking. I should have posted I have been learning to use opencv with other languages. I have been spending time working through beginner tutorials on using opencv with Python and Processing. My real interest in opencv was to use it with FreeBASIC and the RPi to capture image data as escapi.bi was windows only. I hope I can give that a try next week sometime.
Thank you again.
paul doe
Moderator
Posts: 1740
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by paul doe »

BasicCoder2 wrote:Joshy you are the gift that keeps on giving!
...
Or the poor folk that keeps doing other people's homework, depending on how you look at it ;)

@Joshy: tested, works flawlessly (Win10 64 bit, fbc 1.07.1 w/gcc 5.x 64-bit). Tested on my laptop's builtin camera without hassles. Nice work!

A little request, if I may? Could you post the sources of the C++ wrappers for FreeBasic?

EDITED: Perhaps I should have remembered to add some cue to indicate that the quote was effectively in jest.
Last edited by paul doe on Mar 06, 2020 16:34, edited 3 times in total.
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: libOpenCV Windows/Linux 32/64-bit

Post by BasicCoder2 »

Joshy continues to enhance FreeBASIC with his contributions making it an even better choice as a programming language.

I do not have the skill set to add things like opencv to the FreeBASIC environment just as most Python users do not have the skill set to add things like
import cv2
import matplotlib
import numpy
import pygame
and so on ...

My "homework" is to now use opencv in some project.
badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by badidea »

D.J.Peters wrote:
badidea wrote:Tying not to be one of those 200 lazy coders, but I ran into a problem: The symbolic links (linux version) seem broken after unzipping.
can you post any error output please ?
what for a 64-bit linux distro do you use ?

(may be if I use a tar.gz file the problem are fixed)

Thank you for testing and support.

Joshy
Yep, tar.gz file keeps the links intact. capture_loop.bas works with my build-in laptop webcam.
Ubuntu (Mate) 18.4.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by D.J.Peters »

paul doe wrote:@Joshy: tested, works flawlessly
Thank you for testing.
paul doe wrote:Could you post the sources of the C++ wrappers for FreeBasic ?
I would do it (I posted all sources from the wrappers I wrote in the past) but there isn't any OpenCV wrapper for FreeBASIC,
It's pure magic from a pro and the C API :lol:
badidea wrote:Yep, tar.gz file keeps the links intact. capture_loop.bas works with my build-in laptop webcam.
Thank you for your feedback.

Joshy
Last edited by D.J.Peters on Mar 06, 2020 23:29, edited 3 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows/Linux 32/64-bit

Post by D.J.Peters »

From the book "OReilly Learning OpenCV.pdf" it's for absolute OpenCV beginners like me :-)

Here are two windows one shows the input video stream the second the blured version !

cvSmooth() can be replaced by any other filter or effect.

Joshy

file "capture_filter_loop.bas"

Code: Select all

#include "opencv.bi"

#ifdef __FB_WIN32__
  dim as long videoBackends(...) =>{ CV_CAP_MSMF, CV_CAP_DSHOW, CV_CAP_VFW }
#else
  dim as long videoBackends(...) =>{ CV_CAP_V4L2, CV_CAP_V4L }
#endif  

const size = ubound(videoBackends)+1

dim as CvCapture ptr capture
for deviceIndex as long = 1 to 0 step -1
  for index as integer = 0 to size-1
    capture = cvCreateCameraCapture(videoBackends(index)+deviceIndex)
    if capture = NULL then continue for
    if cvGrabFrame(capture) then exit for,for
    cvReleaseCapture(@capture) : capture = NULL
  next
next  

if capture = NULL then
  print "no active or connected capture device found !"
  beep : sleep :end 1
end if

dim as IplImage ptr imageInput,imageOutput
var videoWidth   = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH)
var videoHeight  = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT)

' create 2 windows
cvNamedWindow ("winInput")  
cvMoveWindow  ("winInput",0,0)
cvResizeWindow("winInput",videoWidth,videoHeight)

cvNamedWindow ("winOutput")
cvMoveWindow  ("winOutput",videoWidth+10,0)
cvResizeWindow("winOutput",videoWidth,videoHeight)

' loop while [ESC] not pressed
while cvWaitKey(10)<>27
  ' grab and retrieve in one go
  imageInput = cvQueryFrame(capture)

  if imageInput <> 0 then 
    ' if it's the first call create a copy of then input image 
    ' (it's the safe way to create a second image buffer with the same format)
    if imageOutput = NULL then ' !!! do it only once !!!
      imageOutput = cvCloneImage(imageInput)
    end if
    ' use any filter/effect
    cvSmooth( imageInput, imageOutput, CV_GAUSSIAN,9,9)    
    cvShowImage("winInput",imageInput) 
    cvShowImage("winOutput",imageOutput) 
  end if  
wend
if imageOutput<>NULL then cvReleaseImage(@imageOutput)
if capture<>NULL then cvReleaseCapture(@capture)
cvDestroyAllWindows()
paul doe
Moderator
Posts: 1740
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: libOpenCV Windows 32/64.bit Linux 64-bit

Post by paul doe »

D.J.Peters wrote:...
I would do it (I posted all sources from the wrappers I wrote in the past) but there isn't any OpenCV wrapper for FreeBASIC,
It's pure magic from a pro and the C API :lol:
...
Oh I was under the impression that you actually wrapped the C++ API. Many thanks.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: libOpenCV Windows/Linux 32/64-bit

Post by D.J.Peters »

It's to complicated for me to update all the linux and windows archives if I update only one *.bi or *.bas file .

I separated the *.bi and *.bas files from the opencv runtime libraries see first post.

Joshy
JohnK_RQ
Posts: 27
Joined: Nov 25, 2019 1:50

Re: libOpenCV Windows/Linux 32/64-bit

Post by JohnK_RQ »

This another awesome lib from DJ Peters. Thanks!
Post Reply