Announcing Xojo OpenCVC - OpenCV 4.5 for Xojo

The Xojo-OpenCVC Windows DLLs have been updated. It turns out the ones that were posted recently were Debug builds, not release builds. That’s been fixed and it should now work.

Remember that if you’re using Windows, you need to unzip the opencv_world452.zip file and make sure the resulting DLL is in the “externals” folder, BEFORE you run the xojo project.

1 Like

Hi Perry,

I did take a look but did not see any VS or Xcode project files. Just the final resulting DLL…

I guess the developer must have maintained them.

Thanks,
John…

OpenCV-C is the C Wrapper for OpenCV 4.5.2. It contains Visual Studio and XCode project files and all the source code.

Xojo-OpenCVC is a Xojo project that uses OpenCV-C to provide native Xojo code for OpenCV. It only uses the DLL and Dylib generated from the OpenCV-C project.

They are different, but related projects, in different Github repositories.

3 Likes

Hi Perry,

OK, I’ll review when I have some quality focused time.

Working on several client projects with one eye towards XoJo. I need both eyes and my brain!

Appreciate,
John…

Hi Perry,

Had a chance to review (shallowly) and yes, everything one needs to understand how to structure a Windows DLL/Mac DynLib seems to be there.

Thank you so much for this gift!

Appreciate,
John…

2 Likes

I’ve just created a Linux shared lib of the OpenCV-C code:

First, download the OpenCV-C to your Linux machine.

Then install the OpenCV SDK:

sudo apt-get install libopencv-dev

Create a file CMakeList.txt inside the Sources folder with the following content:

cmake_minimum_required(VERSION 3.10)
project(OpenCVC)

# Find OpenCV4 package
find_package(OpenCV REQUIRED)

# Collect all .cpp files in this directory
file(GLOB SOURCES "*.cpp")

# Create a shared library named OpenCVC (will produce libOpenCVC.so)
add_library(OpenCVC SHARED ${SOURCES})

# Include OpenCV headers
target_include_directories(OpenCVC PRIVATE ${OpenCV_INCLUDE_DIRS})

# Link OpenCV libraries
target_link_libraries(OpenCVC PRIVATE ${OpenCV_LIBS})

# Optionally, set the output library name explicitly
set_target_properties(OpenCVC PROPERTIES OUTPUT_NAME "OpenCVC")

cd into the Sources dir and then run these cmds:

mkdir build
cd build
cmake ..
make

You should then get a libOpenCVC.so shared lib in the build folder that you can link to from the Xojo classes. I copied it directly into /usr/lib and then, after opening the openCVDesktop.xojo_project, edit the constant openCV.LibOpenCVC, adding a value for the Linux platform with the value libOpenCVC.so.

Then I was able to run the project on my Pi 5 (I had previously installed various openCV and other libs and tools so that I could use the camera from python, so some more installations may be needed to get this working).

For the demo to work I also had to make sure that the various folders from inside the “external” folder were found by the app. I leave that as an exercise to the reader.

My thanks go to @Perry_Paolantonio for making this all possible!

4 Likes

I’d love to see some example Xojo projects showing some of the cool stuff I’m sure one can do with this.

I did some testing a while ago. When the file is loaded then OpenCVC is really fast. But for resizing images in memory it’s like embarrassing slow. Like seconds compared to ticks with the MBS plugin.

I’d be most interested in object recognition/classification, feature extraction, and that type of stuff.

4 Likes

Then something is wrong on your end. We are using it specifically because of the speed and the whole point of the project was to speed up resizing of massive images.

The benchmarks in the documentation are tests I did with resizing images in memory, on a pretty modest machine (an old i7, if I recall). OpenCV resize was significantly faster than all the other methods we tested, and the starting point was about 14,000 x 10,000 pixel file. OpenCV was almost 10x faster than the others scaling from full size to 640x480

Some if this is there already. If you try the test app and click on the “faces” button, you’ll see how it works. I don’t have a lot of expertise with this end of things, but what you’re looking for might already be there.

1 Like

I’ll dig out the example. It wasn’t really complicated.

OpenCV:

dim t1 as Integer = System.Ticks
dim p as Picture = lotte
dim mb as MemoryBlock = p.GetData(Picture.FormatJPEG)
reference = openCV.Codecs.imDecode(mb, openCV.ImReadModes.Color)
If reference=Nil Then Return
Var scale As Double=.1
Var scaledSize As New openCV.CVCSize(reference.Width*scale, reference.Height*Scale)
reference2= New openCV.CVCMat
openCV.imgProc.CVCresize(reference, reference2, scaledSize, 0.0, 0.0, openCV.InterpolationFlags.Area)
dim t2 as Integer = System.Ticks
dim t3 as Integer = t2 - t1
beep

Comparison code with MBS CGImageSource:

dim t1 as Integer = System.Ticks
dim p as Picture = lotte
dim MimeData as MemoryBlock = p.GetData(Picture.FormatJPEG)
dim options as new Dictionary
options.Value(CGImageSourceMBS.kCGImageSourceThumbnailMaxPixelSize) = 500
options.Value(CGImageSourceMBS.kCGImageSourceCreateThumbnailFromImageAlways) = true
options.Value(CGImageSourceMBS.kCGImageSourceCreateThumbnailWithTransform) = True

dim theCGImage as CGImageMBS = CGImageSourceMBS.CreateThumbnailMT(MimeData, 0, options)
dim PreviewPic as Picture = theCGImage.Picture
dim t2 as Integer = System.Ticks
dim t3 as Integer = t2 - t1
beep

OpenCV 118 ticks vs. 12 ticks for the MBS plugin. Not seconds but still 10 times slower. M1 processor.

1 Like

I don’t have time to look into this, and probably won’t for a little while, but my initial guess is that the OpenCVC library might be built for Intel only on mac, not universal, which could explain the slowdown. It’s been several months since the last set of updates, and I just don’t recall the build settings on that.

I’m just swamped with other work. My target is Windows, so that’s where I have the most experience, but most of the development has been done on Mac.

That being said, you’re using imDecode here, which may account for some of the slowdown you’re seeing since it’s converting the image to a JPEG.

In my film scanner app, I work with the raw bitmap data off of a frame grabber. That data has no formatting so there’s no conversion to JPEG. If you start your timer after the imDecode line, I’d be curious to see if it’s significantly faster. If I recall, the benchmarks I did back when I first did the documentation were testing only the CVCResize function against the other scaling operations, and not anything leading into or coming out of it. A fair test of the speed to resize would be to only measure the time around the actual function doing the resizing, not including any format conversions

This is the entirety of the code I use to display a raw 14k x 10k frame grab in a much smaller canvas preview window, and it’s very fast:

(frame is a pre-existing CVCMat passed to this method, containing the raw frame grab, so this code is purely about resizing it)

//determine the size of the canvas
Var scaledSize As New openCV.CVCSize(wMainWindow.PreviewCanvas.Width, wMainWindow.PreviewCanvas.Height)

//resize the image in openCV to fit the canvas
var resizedImage as New openCV.CVCMat
openCV.imgProc.CVCresize(frame, resizedImage, scaledSize, 0.0, 0.0, openCV.InterpolationFlags.Area)

//convert the image to a png for display
var displayFrame as picture = resizedImage.imageToPNG

//draw to the preview Canvas
wMainWindow.PreviewCanvas.Backdrop = displayFrame

It may very well be possible that working on a JPEG is a bit slower than working with the raw image data, but I’ve never tested that because I only work with the raw bitmap until the end, when it’s saved to a file, or as in the function above where it’s converted to a smaller PNG for display.

No, I’m using a universal version. I’ve tested only resizing which is indeed super fast (< 1 tick). But since I have jpgs and pngs in memory or from a database I need to load the images with imDecode.

Can you run as ARM only?
Can you build as ARM only?

I’ve tested only resizing which is indeed super fast (< 1 tick). But since I have jpgs and pngs in memory or from a database I need to load the images with imDecode.

Ok, so I think the intial comment is kind of unfair since you’re including more than resizing in a test of how fast it is. Once the image is in a CVMat, all functions we’ve tested have been incredibly fast, which is the whole reason we use it. Resize is only one of many functions we’re doing with OpenCV - the raw data we capture gets stuffed into a mat, and that gets passed around from OpenCV function to OpenCV function, until we’re ready to export it to a file. At that point, we do a conversion. If you have to convert each image and all you’re doing to those images is resizing, and your source images aren’t that big to begin with, then it might not be the solution for you. With significantly larger files I bet you’d see a difference. the ones we’re working with are 300MB each.

Are you referring to your Xojo app? What I’m referring to is the OpenCVC dylib, and whether it’s built for Intel or Universal. I just don’t recall off the top of my head and I’m not near my mac dev machine at the moment.

Of course, I meant the OpenCVC dylib.

lipo -info /Users/beatrixwillius/Desktop/libOpenCVC.dylib
Architectures in the fat file: /Users/beatrixwillius/Desktop/libOpenCVC.dylib are: x86_64 arm64

In my apps I have a lot of images which need to be resized. The images from emails are usually not that big. For my new app which archives messages the images usually are the size of iPhone images. The task is to resize the images from a database or in memory. I’ll use the fastest solution which is the MBS plugin.