PureBasic Interface to OpenCV

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

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi JHPJHP and all readers of this topic!

Look at the first post: it's 1 year anniversary for now!
My congratulations to you!
Image
It was very interesting year.
Many thanks to JHPJHP for his persistence and very hard work!

Good luck!
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: PureBasic Interface to OpenCV

Post by applePi »

Congratulation JHPJHP , 200 examples is a big feat. i have noticed that many people are using your PureBasic Interface to OpenCV, since it is better and smarter and speedier than all the clumsy and problematic usage under C++ . i know that from the several notes from users here and there over the years.
wish you the best
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi AAT, applePi,

Wow a full year :!: Thank you again AAT for being a support and contributor right from the beginning, this would have been a package of 20 examples and not 200 without it.

Thank you applePi for adding new life to the project with your expertise in OpenGL, and the art of 3D programming.

Thank you to the many PureBasic users who have left comments or questions, showing that this project was well worth the time and effort.
Last edited by JHPJHP on Tue Jan 27, 2015 2:18 am, edited 2 times in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

JHPJHP wrote:...this would have been a package of 20 examples...
My first saved package consists of 9 examples and 1 pbi. :D
Feel the differenсe :!:
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: PureBasic Interface to OpenCV

Post by dige »

1 year :D This is great opportunity to say thank you JHPJHP, for the great work!
"Daddy, I'll run faster, then it is not so far..."
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi dige,

You're very much welcome.

I can hardly believe that another year is coming to a close, but I look forward to the next one and the programming challenges to come.

Cheers!

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

I've updated the binaries from: OpenCV v2.4.9 to v2.4.10.
- update also includes the latest reference files

Sorry no new examples, nor do I plan on adding any.
- existing examples have been tested and found working

NB*: I've applied numerous bug fixes to various examples over the last few months.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP!
Thank you for your great work!

Good luck!

P.S. I work on the project on processing of the image from the IP camera for now.
There are some problems with FFMPEG in OpenCV, for example
http://answers .opencv.org/question/39079/opencv249-with-ip-cam-have-h246-error/? answer=53755#post-id-53755
I have no decision for this problem. :(
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: PureBasic Interface to OpenCV

Post by bbanelli »

JHPJHP wrote:I've updated the binaries from: OpenCV v2.4.9 to v2.4.10.
Am I missing something or is there no change log for 2.4.10 version?
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi AAT,

It's always good to hear from you. Let me know if I can help in anyway.

Cheers!

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

Hi bbanelli,

I found the change log for OpenCV v2.4.10, but now look what you've caused... :P

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

I've updated the binaries from: OpenCV v2.4.10 to v2.4.11.
- update also includes the latest reference files

After reading bbanelli's post, I did a search for the OpenCV v2.4.10 Change Logs and found then, but they also pointed to another stable release of OpenCV.
- http://code.opencv.org/projects/OpenCV/versions/22
- http://code.opencv.org/projects/OpenCV/versions/23

NB*: I've kept the Haarcascade classifiers from OpenCV v2.4.10 due to compatibility issues with the PureBasic interface and the classifiers included in v2.4.11.
Last edited by JHPJHP on Sun Mar 01, 2015 8:39 pm, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: PureBasic Interface to OpenCV

Post by bbanelli »

JHPJHP wrote:Hi bbanelli,

I found the change log for OpenCV v2.4.10, but now look what you've caused... :P
Always happy to "cause" updates and new stuff on T&T section from you! :)
After reading bbanelli's post, I did a search for the OpenCV v2.4.10 Change Logs and found then, but they also pointed to another stable release of OpenCV.
- http://code.opencv.org/projects/OpenCV/versions/22
- http://code.opencv.org/projects/OpenCV/versions/23
Does this mean that v10 and v11 are bugfixes only, while 2.9 had some new features and improvements as well?
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi bbanelli,
bbanelli wrote:Does this mean that v10 and v11 are bugfixes only, while 2.9 had some new features and improvements as well?
I think that's exactly what these "hidden" versions are. Good to know - thank you.

After reviewing the change logs it may seem like little benefit to downloading the update, but that wouldn't be true:
- the follow are just a few of the fixes in the latest OpenCV update supported by this Interface
-- VideoCapture records with incorrect speed and FPS
-- cvMinEnclosingCircle computes radius by 3% to large
-- Segmentation fault in Canny detector

Note: The Canny detector is used in numerous examples and is a key component to a variety of algorithms.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP!
JHPJHP wrote:...
-- cvMinEnclosingCircle computes radius by 3% to large
-- Segmentation fault in Canny detector...
These operators are used in my project.
The changes in their work do not affect the work of my program, it's good! :)

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

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi!
It is often necessary to detect object boundaries in an image. In many cases, programmers prefer to work with grayscale images, as it is much faster. However, working in Grayscale is not always possible to detect the desired object. For example, see a picture in attachment (save it as "a.png").
You can see that the green rectangle merged with the background and the yellow figure merged with the cyan rectangle on the gray presentation of this picture.
(http://recog.ru/blog/opencv/203.html)

Code: Select all

IncludeFile "includes/cv_functions.pbi"

*Image.IplImage = cvLoadImage("a.png", #CV_LOAD_IMAGE_COLOR)
*ImageClone.IplImage = cvCloneImage(*Image)
*Gray.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
*GrayClone.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
*GrayTemp.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
*GColor.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
rows.l = 3 : columns.l = 3
*ConvKernel.IplConvKernel = cvCreateStructuringElementEx(rows, columns, cvFloor(rows/2), cvFloor(columns/2), #CV_SHAPE_RECT, 0) 

cvCvtColor(*Image, *Gray, #CV_BGR2GRAY, 1)
cvShowImage("Color", *Image) : cvMoveWindow("Color", 10, 10)
cvShowImage("Gray", *Gray) : cvMoveWindow("Gray", 10, 360)
        
cvMorphologyEx(*Gray, *GrayClone, *GrayTemp, *ConvKernel, #CV_MOP_GRADIENT, 1)
cvMorphologyEx(*Image, *ImageClone, *GrayTemp, *ConvKernel, #CV_MOP_GRADIENT, 1)
cvCvtColor(*ImageClone, *GColor, #CV_BGR2GRAY, 1)

cvShowImage("Color Gradient", *ImageClone) : cvMoveWindow("Color Gradient", 510, 10)
cvShowImage("Color->Gray Gradient", *GColor) : cvMoveWindow("Color->Gray Gradient", 1020, 10)
cvShowImage("Gray Gradient", *GrayClone) : cvMoveWindow("Gray Gradient", 510, 360)

Repeat
  keyPressed = cvWaitKey(1)
Until keyPressed = 27

cvDestroyWindow("Color Image")
cvDestroyWindow("Color->Gray Image")
cvDestroyWindow("Gray Gradient")
cvDestroyWindow("Color Gradient")
cvDestroyWindow("Color->Gray Gradient")

cvReleaseImage(@*GColor)
cvReleaseImage(@*GrayTemp)
cvReleaseImage(@*GrayClone)
cvReleaseImage(@*Gray) 
cvReleaseImage(@*ImageClone)
cvReleaseImage(@*Image)
Image
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: PureBasic Interface to OpenCV

Post by bbanelli »

I don't know if this has been discussed, but I tried working with this in "native" PB environment.

Namely, I wanted to have multiple display sources in one window, something like this.

Image
https://youtu.be/Sp7VcjPlgGA

Here is my code.

Code: Select all

IncludeFile "includes/cv_functions.pbi"

EnableExplicit

Enumeration #PB_Event_FirstCustomValue
  #Event_ThreadMessage
  #EventType_UpdateFrame
EndEnumeration

Global *capture, *param.USER_INFO
Global.i ThreadFlag = 1
Global.cvFont font1, font2, font3
Global Dim Thr.i(4)
Threaded.i i, j, Parameter
Threaded.b adjust1, adjust2, adjust3
Threaded *image.IplImage
Define.i nCreate, CaptureThr, Event, FrameSyncMutex

Procedure ErrorHandler()
  Protected ErrorMessage$
  ErrorMessage$ = "A program error was detected:" + Chr(13) 
  ErrorMessage$ + Chr(13)
  ErrorMessage$ + "Error Message:   " + ErrorMessage()      + Chr(13)
  ErrorMessage$ + "Error Code:      " + Str(ErrorCode())    + Chr(13)  
  ErrorMessage$ + "Code Address:    " + Str(ErrorAddress()) + Chr(13)
 
  If ErrorCode() = #PB_OnError_InvalidMemory   
    ErrorMessage$ + "Target Address:  " + Str(ErrorTargetAddress()) + Chr(13)
  EndIf
 
  If ErrorLine() = -1
    ErrorMessage$ + "Sourcecode line: Enable OnError lines support to get code line information." + Chr(13)
  Else
    ErrorMessage$ + "Sourcecode line: " + Str(ErrorLine()) + Chr(13)
    ErrorMessage$ + "Sourcecode file: " + ErrorFile() + Chr(13)
  EndIf
 
  ErrorMessage$ + Chr(13)
  ErrorMessage$ + "Register content:" + Chr(13)
 
  CompilerSelect #PB_Compiler_Processor 
    CompilerCase #PB_Processor_x86
      ErrorMessage$ + "EAX = " + Str(ErrorRegister(#PB_OnError_EAX)) + Chr(13)
      ErrorMessage$ + "EBX = " + Str(ErrorRegister(#PB_OnError_EBX)) + Chr(13)
      ErrorMessage$ + "ECX = " + Str(ErrorRegister(#PB_OnError_ECX)) + Chr(13)
      ErrorMessage$ + "EDX = " + Str(ErrorRegister(#PB_OnError_EDX)) + Chr(13)
      ErrorMessage$ + "EBP = " + Str(ErrorRegister(#PB_OnError_EBP)) + Chr(13)
      ErrorMessage$ + "ESI = " + Str(ErrorRegister(#PB_OnError_ESI)) + Chr(13)
      ErrorMessage$ + "EDI = " + Str(ErrorRegister(#PB_OnError_EDI)) + Chr(13)
      ErrorMessage$ + "ESP = " + Str(ErrorRegister(#PB_OnError_ESP)) + Chr(13)
 
    CompilerCase #PB_Processor_x64
      ErrorMessage$ + "RAX = " + Str(ErrorRegister(#PB_OnError_RAX)) + Chr(13)
      ErrorMessage$ + "RBX = " + Str(ErrorRegister(#PB_OnError_RBX)) + Chr(13)
      ErrorMessage$ + "RCX = " + Str(ErrorRegister(#PB_OnError_RCX)) + Chr(13)
      ErrorMessage$ + "RDX = " + Str(ErrorRegister(#PB_OnError_RDX)) + Chr(13)
      ErrorMessage$ + "RBP = " + Str(ErrorRegister(#PB_OnError_RBP)) + Chr(13)
      ErrorMessage$ + "RSI = " + Str(ErrorRegister(#PB_OnError_RSI)) + Chr(13)
      ErrorMessage$ + "RDI = " + Str(ErrorRegister(#PB_OnError_RDI)) + Chr(13)
      ErrorMessage$ + "RSP = " + Str(ErrorRegister(#PB_OnError_RSP)) + Chr(13)
      ErrorMessage$ + "Display of registers R8-R15 skipped."         + Chr(13)
 
    CompilerCase #PB_Processor_PowerPC
      ErrorMessage$ + "r0 = " + Str(ErrorRegister(#PB_OnError_r0)) + Chr(13)
      ErrorMessage$ + "r1 = " + Str(ErrorRegister(#PB_OnError_r1)) + Chr(13)
      ErrorMessage$ + "r2 = " + Str(ErrorRegister(#PB_OnError_r2)) + Chr(13)
      ErrorMessage$ + "r3 = " + Str(ErrorRegister(#PB_OnError_r3)) + Chr(13)
      ErrorMessage$ + "r4 = " + Str(ErrorRegister(#PB_OnError_r4)) + Chr(13)
      ErrorMessage$ + "r5 = " + Str(ErrorRegister(#PB_OnError_r5)) + Chr(13)
      ErrorMessage$ + "r6 = " + Str(ErrorRegister(#PB_OnError_r6)) + Chr(13)
      ErrorMessage$ + "r7 = " + Str(ErrorRegister(#PB_OnError_r7)) + Chr(13)
      ErrorMessage$ + "Display of registers r8-R31 skipped."       + Chr(13)
 
  CompilerEndSelect
  
  ThreadFlag = 0
  Delay(250)
  For i = 0 To 3
    If IsThread(Thr(i))
      KillThread(Thr(i))
    EndIf
  Next    
  
  MessageRequester("OnError example", ErrorMessage$)
  
  End
 
EndProcedure

OnErrorCall(@ErrorHandler())

Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture

Procedure RefreshFrame(*p)
  Shared FrameSyncMutex
  Parameter  = *p
  While ThreadFlag
    LockMutex(FrameSyncMutex)
    *image = cvQueryFrame(*capture)
    UnlockMutex(FrameSyncMutex)
    If *image
      cvPutText(*image, "Part " + Str(Parameter), 0, 50, @font1, 0, 0, 255, 0)
      cvPutText(*image, FormatDate("%yyyy-%mm-%dd",Date()), 0, 440, @font2, 0, 255, 0, 0)
      cvPutText(*image, FormatDate("%hh-%ii-%ss", Date()), 370, 440, @font3, 255, 0, 0, 0)
      cvFlip(*image, #Null, 0)
      StartDrawing(ImageOutput(Parameter))
      DrawImage(ImageID(Parameter),0,0)
      CopyMemory(*image\imageData, DrawingBuffer(), (*image\width) * (*image\height) * 3)
      StopDrawing()
      PostEvent(#Event_ThreadMessage, 0, Parameter, #EventType_UpdateFrame, Parameter)
    EndIf
  Wend
  ProcedureReturn
EndProcedure

Procedure OnThreadMessage()
  Select EventType()
    Case #EventType_UpdateFrame
      ResizeImage(EventData(),320,240)
      SetGadgetState(EventGadget(), ImageID(EventData()))
      ResizeImage(EventData(),640,480)
  EndSelect
  ProcedureReturn
EndProcedure

If *capture
  If OpenWindow(0, 0, 0, 640, 520, "PB Native@OpenCV", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    BindEvent(#Event_ThreadMessage, @OnThreadMessage())
    
    FrameSyncMutex = CreateMutex()
    
    ButtonGadget(100, 10, 490, 200, 20, "Exit")
    CreateImage(0, 640, 480)
    CreateImage(1, 640, 480)
    CreateImage(2, 640, 480)
    CreateImage(3, 640, 480)
    ImageGadget(0,0,0,320,240, ImageID(0))
    ImageGadget(1,320,0,320,240, ImageID(1))
    ImageGadget(2,0,240,320,240, ImageID(2))
    ImageGadget(3,320,240,320,240, ImageID(3))
    
    font1.CvFont
    font2.CvFont
    font3.CvFont
    cvInitFont(@font1, #CV_FONT_HERSHEY_SCRIPT_COMPLEX, 1.5, 1.5, #Null, 1, #CV_AA)
    cvInitFont(@font2, #CV_FONT_HERSHEY_SIMPLEX, 1.5, 1.5, #Null, 1, #CV_AA)
    cvInitFont(@font3, #CV_FONT_HERSHEY_TRIPLEX | #CV_FONT_ITALIC, 1.5, 1.5, #Null, 1, #CV_AA)
        
    *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
    *param\uValue = WindowID(0)
    
    For i = 0 To 3
      Thr(i) = CreateThread(@RefreshFrame(), i)
    Next
    
    Repeat
      Event = WaitWindowEvent()
      
      Select Event
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 100
              ThreadFlag = 0
              FreeMemory(*param)
              cvReleaseCapture(@*capture)
              End 0
          EndSelect
      EndSelect
    Until Event = #PB_Event_CloseWindow
  EndIf
EndIf
It would be sane that there are separated capture sequences (for example, multiple cameras), however, what would be a proper way to sync threads if one capture is made? How to achieve (mutex, semaphores?) than that same capture would be copied to "display" threads for manipulation, and only after "post-processing" is done in each thread, new capture frame is taken?

In addition to that, is there a better way to handle resize of picture, since capture is 640x480 and I'd like to display 320x240 images (or any other resolution)? Image size must be 640x480 since I use CopyMemory and if resolution is changed, there's a memory violation.

Furthermore, is OpenCV fully thread safe in general? For some reason, I get memory access errors on DrawImage(ImageID(Parameter),0,0) or in CopyMemory below that line, so I don't know if that's related to OpenCV or my lousy coding skills. :)

Image

When that happens, process remains active (I guess threads don't die), so I have put the following code in ErrorHandler procedure.

Code: Select all

ThreadFlag = 0
Delay(250)
For i = 0 To 3
  If IsThread(Thr(i))
    KillThread(Thr(i))
  EndIf
Next    
Should this prevent that kind of behavior? I am asking "should it" since I've fiddled with code in the meanwhile and I can't reproduce that particular memory error, do'h. :D

Edit: well, I've let it run through the night and no crashes happened. In addition to that, it also exits gracefully without leaving any threads. Would still like to hear some comments about above mentioned issues in general! Thanks in advance!

Thanks to all in advance,

Bruno
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
Locked