PureBasic Interface to OpenCV

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

Re: OpenCV (v2)

Post by JHPJHP »

I've updated the binaries to include newer versions of the C Runtime files.
- located in the x86 folder is a cRt folder with 32-bit versions of the files (v10 & v11)
- located in the x64 folder is a cRt folder with 64-bit versions of the files (v10 & v11)

Cheers!
Last edited by JHPJHP on Wed Dec 25, 2013 3:27 pm, edited 1 time in total.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

JHPJHP, mаny thanks, for your work!

Are you plan to add function from chapter "3.5 Structural Analysis and Shape Descriptors" of "The OpenCV Reference Manual" (opencv2refman.pdf in the "doc" folder)?
In particular, cvMinAreaRect function?

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

Re: OpenCV (v2)

Post by JHPJHP »

Hi AAT,

I guess you've been thinking about this one for awhile: http://forum.purebasic.com/english/view ... 32&start=0 :wink:

Start of the week, and I'm back to work so there isn't a lot of time, but I've had a chance to view the following examples (same ball-park as your request)...
- http://stackoverflow.com/questions/6471 ... -functions
- https://opencv-python-tutroals.readthed ... tures.html

... based on the links above, I've added some Constants and the following Functions (not much time for anything else)
- cvCreateMemStorage
- cvFindContours
- cvDrawContours
- cvConvexHull2
- cvDrawContours
- cvGetSeqElem
- cvClearMemStorage

NB*: I've also included the latest Reference Manual, a Change Log, and a Read Me file.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Hi, JHPJHP!

Thank you very much for your time and efforts spent on me.
JHPJHP wrote: I guess you've been thinking about this one for awhile: http://forum.purebasic.com/english/view ... 32&start=0 :wink:
Yes :)
I solved my problem in a different way (vithout openCV), but it isn't pleasant to me.

My main problem is openCV structures, data and its conversion. For example, how to convert IplImage into CvMat or CvSeq?
And recursive structures in C like this

Code: Select all

typedef struct CvMemStorage
{
    int signature;
    CvMemBlock* bottom;           /* First allocated block.                   */
    CvMemBlock* top;              /* Current memory block - top of the stack. */
    struct  CvMemStorage* parent; /* We get new blocks from parent as needed. */
    int block_size;               /* Block size.                              */
    int free_space;               /* Remaining free space in current block.   */
}
CvMemStorage;
makes me crazy... :shock:

Your prototype function

Code: Select all

cvFindContours(*image, *storage, *first_contour, header_size, mode, method, x, y)
but in C

Code: Select all

C: int cvFindContours(CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) )
Are you sure, that
*first_contour is equivalent to CvSeq** first_contour? (Pointer to pointer? :shock: )

I hope that you won't give up work on OpenCV (v2).

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

Re: OpenCV (v2)

Post by JHPJHP »

Hi AAT,
For example, how to convert IplImage into CvMat or CvSeq?
From my understanding you don't convert between the three, as each has its own purpose.
*first_contour is equivalent to CvSeq** first_contour? (Pointer to pointer? :shock: )
Pointer to Structure
- IplImage: stores image data
- CvMat stores the numerical matrices of image data (take a look at: cv_filter2d.pb)
- CvSeq stores sequence data derived from functions such as cvFindContours

I've added the following Dynamic Structures:
- CvContour
- CvMemBlock
- CvMemStorage
- CvSeqBlock
- CvSeq

NB*: I won't know if the Structures are setup correctly until I've had time to put together an example to test with.

NB**: I've modified and renamed some of the existing Structures which affected most of the examples requiring some slight changes.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Hi JHPJHP.
Please, look at this code when you will have a time.
It's not working... :(

Code: Select all

IncludeFile "includes/cv_functions.pbi"

; C declaration:
;================
;
; typedef struct CvPoint2D32f
; {
;     float x;
;     float y;
; }
; CvPoint2D32f;
; 
; typedef struct CvSize2D32f
; {
;     float width;
;     float height;
; }
; CvSize2D32f;
; 
; typedef struct CvBox2D
; {
;     CvPoint2D32f center;  /* Center of the box.                          */
;     CvSize2D32f  size;    /* Box width and length.                       */
;     float angle;          /* Angle between the horizontal axis           */
;                           /* And the first side (i.e. length) in degrees */
; }
; CvBox2D;
;
; /* Finds minimum area rotated rectangle bounding a set of points */
;CvBox2D cvMinAreaRect2(const CvArr* points, CvMemStorage* storage=NULL )
;
;Parameters
;points – Input vector of 2D points, stored in:
;– CvSeq* or CvMat* (C interface)
;==============================================================================

Structure CvPoint2D32f  Align #PB_Structure_AlignC
    x.f
    y.f
EndStructure

Structure CvSize2D32f Align #PB_Structure_AlignC
    width.f;
    height.f;
EndStructure

Structure CvBox2D Align #PB_Structure_AlignC
    center.CvPoint2D32f   ; Center of the box.  
    size.CvSize2D32f      ; Box width and length.
    angle.float           ; Angle between the horizontal axis And the first side (i.e. length) in degrees
EndStructure

ImportC "opencv_imgproc247.lib"
  cvMinAreaRect2(*CvArr, *CvMemStorage=#Null) 
EndImport

Global  MARect.CvBox2D, *mems.CvMemStorage
 
Debug("Mat Start filling")
*kernel = cvCreateMat(250, 250, CV_MAKETYPE(#CV_8U, 3))
cvSet(*kernel, 0, 0, 0, 0, #Null)

; Draw rectangle
For i=0 To 99
  For j=0 To 249
    cvSet2D(*kernel, i, j, 0, 0, 0, 0)
  Next j
Next i

For i=100 To 149
  For j=0 To 75
    cvSet2D(*kernel, i, j, 0, 0, 0, 0)
  Next j
  For j=76 To 175
    cvSet2D(*kernel, i, j, 1, 0, 0, 0)
  Next j      
  For j=176 To 249
    cvSet2D(*kernel, i, j, 0, 0, 0, 0)
  Next       
Next i    

For i=150 To 249
  For j=0 To 249
    cvSet2D(*kernel, i, j, 0, 0, 0, 0)
  Next j
Next i      
Debug("Mat filled")

*rect = @MARect
*rect = cvMinAreaRect2(*kernel,*mems)
Debug("Center: X="+StrF(MARect\center\x)+" Y="+StrF(MARect\center\y)+", Angle="+StrF(MARect\angle))
Debug("Width="+StrF(MARect\size\width)+", Height="+StrF(MARect\size\height))  

cvReleaseMat(@*kernel)
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

I have made some additions and updates to Constants, Structures, Macros, and Functions... too many to list.
- a new example has also been added: cv_contours.pb

This example scans an image for contours building each contour into an array of points. It then applies the data to a blank matrices using predefined filters, creating a "drawn" version of the image (filled or outlined).

NB*: Added the OpenCV License file to references.

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

Hi AAT,

I think the problem with the function: cvMinAreaRect2 is the way its declared, it's the same issue I experienced with most of the functions, that they don't match the documentation. I located an OpenCV Reference Manual from 2001 with a legacy declaration, illustrating the discrepancy between versions, and possibly what you're up against:
void cvMinAreaRect ( CvPoint* points, int n, int left, int bottom, int right,
int top, CvPoint2D32f* anchor, CvPoint2D32f* vect1, CvPoint2D32f* vect2 );
All I can suggest is a lot of "Trial & Error", adding and removing parameters, data types, etc. until you find something that works; unfortunately for now I have other projects that take priority.

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

Re: OpenCV (v2)

Post by AAT »

Hi. JHPJHP
Thank you very much!
I will try to find proper prototype.

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

Re: OpenCV (v2)

Post by JHPJHP »

The following error reported by AAT has been addressed:
"Microsoft Visual C++ Runtime Library Runtime Error! This application has requested the Runtime to terminate it in an unusual way."
The error had to do with converting a 1 Channel image into a 1 Channed image.
- if an image has a single Channel then it's addressed in one of the following ways
-- image is cloned instead of creating a new one (in some instances this negates the effect)
-- when creating the image the nChannels Structure value from a previous instance is used
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: OpenCV (v2)

Post by User_Russian »

Little John wrote:Hello JHPJHP,

that looks very interesting.

Unfortunately, I'm not able to run any of the examples (using PB 5.21 LTS on Windows XP x86).
I always get a German error message which translates to something like
PureBasic_Compilation0.exe - Entry point not found
---------------------------
The procedure entry point "GetTickCount64" was not found in the DLL "KERNEL32.dll".
Similar problem.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: OpenCV (v2)

Post by JHPJHP »

Hi User_Russian,

Sorry thats my fault, I removed the notes from the first post into a readme.txt file located in the download - I'll add them back.

For Windows XP: copy the files from \binaries\x86\vc10\, overwriting the ones located at \binaries\.

Please let me know if this fixes the problem.
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: OpenCV (v2)

Post by User_Russian »

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

Re: OpenCV (v2)

Post by JHPJHP »

Hi User_Russian,

Glad to hear it!

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

I've added a bunch of new functions.
- some haven't been tested, but I followed the same format as the ones proven via the examples

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

Hi AAT,

Most of the examples added use the same general array (CvArr) parameter as cvMinAreaRect2, and can possibly assist in tracing down the current issue. I had a few hours today to try some of the new functions, and came up against the same message-less crash seen from the example you posted. This seems to indicate that the problem is larger then a single function, and may be related to the array itself.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

Hi JHPJHP,
I have the same problems with CvArr parameter in other functions...
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: OpenCV (v2)

Post by AAT »

New example for cvContourArea() function

Prepared test image (1 month is stored)
http://rghost.ru/50527445

Code: Select all

; OpenCV
; Image filtration on the minimum area of a contour 
; (removal of small elements of the image or noise)
; Based on JHPJHP code cv_contours.pb 
; 
; The filter On/Off by #FilterOn value
;
; AAT
;==================================================

IncludeFile "includes/cv_functions.pbi"

#CV_WINDOW_NAME = "Contour Area Filter"
#FilterOn = #True           ; Filter On = #True, Off = #False
#FilterValue = 35           ; minimal area of the visible contour

ImportC "opencv_imgproc247.lib"
  cvContourArea.d(*contour, start_index.i, end_index.i, oriented.i)  
EndImport  

ImageFolder.s = Space(#MAX_PATH)
SHGetFolderPath_(#Null, #CSIDL_MYPICTURES, 0, 0, ImageFolder)
PathAddBackslash_(ImageFolder)
Pattern.s = "All Images (*.*)|*.bmp;*.dib;*.jpeg;*.jpg;*.jpe;*.png;*.tiff;*.tif|Windows Bitmaps (*.bmp)|*.bmp;*.dib|JPEG Files (*.jpg)|*.jpeg;*.jpg;*.jpe|Portable Network Graphics (*.png)|*.png|TIFF Files (*.tiff)|*.tiff;*.tif"
ImageFile.s = OpenFileRequester("Please choose an image file", ImageFolder, Pattern, 0)

If ImageFile
  *image.IplImage
  *gray.IplImage
  *contour.IplImage
  carea.d   
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_NORMAL)
  *image = cvLoadImage(ImageFile, #CV_LOAD_IMAGE_ANYDEPTH | #CV_LOAD_IMAGE_ANYCOLOR)
  cvResizeWindow(#CV_WINDOW_NAME, *image\width, *image\height)
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  *storage.CvMemStorage
;  *contours.CvContour
  *contours.CvSeq                            ; same result as *contours.CvContour
  *storage = cvCreateMemStorage(0)
  *gray = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
  cvCvtColor(*image, *gray, #CV_BGR2GRAY, 1)
  cvThreshold(*gray, *gray, 64, 255, #CV_THRESH_BINARY)
  nContours = cvFindContours(*gray, *storage, @*contours, SizeOf(CvContour), #CV_RETR_LIST, #CV_CHAIN_APPROX_SIMPLE, 0, 0)
  If nContours
    *contour = cvCreateImage(*gray\width, *gray\height, #IPL_DEPTH_8U, 3)    
    cvSet(*contour, 5, 5, 5, 0, #Null)
;    Debug("#Counturs="+Str(nContours))
    For rtnCount = 1 To nContours           
      carea = cvContourArea(*contours, 0, $3fffffff, 0)
;      Debug("Contour Area="+StrD(carea))    
      If #FilterOn = #True
        If carea => #FilterValue
          cvDrawContours(*contour, *contours, 255, 155, 0, 0, 155, 255, 0, 0, -1, 1, #CV_AA, 0, 0)                                     
        EndIf
      Else
        cvDrawContours(*contour, *contours, 0, 155, 255, 0, 0, 255, 255, 0, -1, 1, #CV_AA, 0, 0)          
      EndIf      
      *contours = *contours\h_next
    Next

    Repeat
      If *contour
        cvShowImage(#CV_WINDOW_NAME, *contour)
        keyPressed = cvWaitKey(0)
      EndIf
    Until keyPressed = 27
    
    cvDestroyWindow(#CV_WINDOW_NAME)
    cvClearMemStorage(*storage)
    cvReleaseImage(@*contour)
    cvReleaseImage(@*gray)
    cvReleaseImage(@*image)
  EndIf
EndIf
Locked