Using opencv and FreeBASIC code

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
BasicCoder2
Posts: 3777
Joined: Jan 01, 2009 7:03
Location: Australia

Using opencv and FreeBASIC code

Post by BasicCoder2 »

This is my simple example using opencv to capture an image but using FreeBASIC to process that image.

It uses D.J.Peter's opencv.bi and example code found at shiny3d.de/public/libs/libOpenCV/fbopencv.zip

FreeBasic forum thread,
viewtopic.php?f=14&t=28361

Code: Select all

' This uses code written by D.J.Peters
' shiny3d.de/public/libs/libOpenCV/fbopencv.zip
' 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)

#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 shortest 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 fbImage1
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*2,videoHeight,32  'fit two images
'screenres videoWidth ,videoHeight,32


fbImage1 = ImageCreate(videoWidth,videoHeight)

dim as ulong v,r,g,b

' 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(fbImage1, cvImage) = true then
      put (0,0),fbImage1,PSET  'show image
        'invert
        for j as integer = 0 to videoHeight-1
            for i as integer = 0 to videoWidth-1
                v = point(i,j,fbImage1)
                r = v shr 16 and 255
                g = v shr 8 and 255
                b = v and 255
                r = 255-r
                g = 255-g
                b = 255-b
                pset fbImage1,(i,j),rgb(r,g,b)
            next i
        next j
      put (videoWidth,0),fbImage1,PSET 'show inverted image

    end if 
  end if 
  
  sleep 10 '1000/videoFPS
wend

cvReleaseCapture(@capture)
Post Reply