/opencvr

Primary LanguagePythonApache License 2.0Apache-2.0

opencvr: Ruby binding of OpenCV

About this library

opencvr is a ruby extension library which provides the wrapper of OpenCV.

Tiny sample

#!/usr/bin/env ruby

require 'cv2'

# Read a JPEG file
img = CV2::imread("input.jpg")
# draw a circle of radius: 100 at position (200, 200) with blue color
# (BGR: 255, 0, 0), thickness: 3 and antialiased
CV2::circle(img, [200, 200], 50, [255, 0, 0], thickness: 3, lineType: CV2::LINE_AA)
# Save to out.jpg
CV2::imwrite("out.jpg", img)

How to create binding code

opencvr generates binding code with the similar way of python binding, which is officially provided by OpenCV.

To provide ruby API of C/C++ library, we need to write binding code for each API (functions, enums, etc.). OpenCV has many APIs, so it would be an exhausting task if we manually write all binding codes.

To avoid this problem, python binding codes are automatically generated by reading header files of C++ interface. opencvr uses similar way and reuse some scripts of python binding generator.

Supported features

See Support Status.

Here is an example of supported functions.

  • cv::imread()
  • cv::imwrite()
  • cv::arrowedLine()
  • cv::circle()

Binding of cv::Mat is manually crated for now (may be changed in the future), and it supports:

  • cv::Mat::cols
  • cv::Mat::rows
  • cv::Mat::channles()

Future plan

  • Support more classes, functions, etc.
  • Create gem
  • Use numo-narray (Does anyone need?)
    • See the below section for the detail

Matrix library

OpenCV uses cv::Mat class as matrix class and image data is represented as an instance of it. However OpenCV python binding provides image data as ndarray of numpy library because numpy is widely used in python world. Thus python developers can manipulate image data not only with OpenCV APIs but also with numpy APIs and other python libraries which are based on numpy.

To provide matrix data as numpy, python binding has special process when cv::Mat instance is created. For example, when cv::imread() is called, python binding does the below things:

  • Create a new cv::Mat instance with custom generated called NumPyAllocator.
    • NumPyAllocator allocates memory by using numpy C API (PyArray_SimpleNew()) and set the pointer to a member variable of cv::Mat.
  • Copy the return value of cv::imread() to the created cv::Mat instance.
  • Returns the pointer as the return value. So it can be used as ndarray.

In ruby world, numo-narray is a famous matrix library, but opencvr does not replace cv::Mat with numo-narray. I haven't tried it because:

  • I'm not sure such requirement really exists
  • I'm not familiary with numo-narray C API and therefore not sure it's possible or not

How to install

From gem

opencvr gem has not been created yet.

Build from source

Prerequisites

Below components are required to build opencvr:

  • Ruby (>3.0.0)
    • recommend to use rbenv
  • Python (>3.x)
  • OpenCV
    • libopencv-dev (apt package on Ubuntu-20.04)
    • opencv (brew package on macOS)

Build

Ubuntu

$ ruby extconf.rb  # Makefile and headers.txt are generated
$ ./gen2rb.py headers.txt
$ make

macOS

$ ruby extconf.rb  # Makefile and headers.txt are generated
$ ./gen2rb.py headers.txt
$ make CXXFLAGS="-std=c++14"

Run test

$ test/bind-test1.rb

License

Apache License 2.0. See License.txt.

gen2rb.py and hdr_parser.py are created by using files in OpenCV, which is under Apache Licsense Version 2.0. Refer the original file.