OpenCV.js

 

JavaScript Bindings for OpenCV

Sajjad Taheri

 

 

 

 

Donald Bren School of Computer Science, UCIrvine
 

OpenCV

  1. An Open Source Library for computer vision
    1. Image processing
    2. video processing
    3. machine learning
    4. object detection
    5. IO
    6. image coding
  2. GPU and SIMD acceleration
  3. Bindings for other languages:
    1. Python, Java

 

ASM.JS

"Mangled names"

Embind

Bind C++ functions and classes to JavaScript

C/C++ Program

LLVM Bytecode

Emscripten: From C++ to JavaScript

MSER: Sample class from OpenCV

class CV_EXPORTS_W MSER : public Feature2D
{
public:
    //! the full constructor
    CV_WRAP static Ptr<MSER> create( int _delta=5, int _min_area=60, int _max_area=14400,
          double _max_variation=0.25, double _min_diversity=.2,
          int _max_evolution=200, double _area_threshold=1.01,
          double _min_margin=0.003, int _edge_blur_size=5 );

    CV_WRAP virtual void detectRegions( InputArray image,
                                        CV_OUT std::vector<std::vector<Point> >& msers,
                                        std::vector<Rect>& bboxes ) = 0;

    CV_WRAP virtual void setDelta(int delta) = 0;
    CV_WRAP virtual int getDelta() const = 0;

    CV_WRAP virtual void setMinArea(int minArea) = 0;
    CV_WRAP virtual int getMinArea() const = 0;

    CV_WRAP virtual void setMaxArea(int maxArea) = 0;
    CV_WRAP virtual int getMaxArea() const = 0;

    CV_WRAP virtual void setPass2Only(bool f) = 0;
    CV_WRAP virtual bool getPass2Only() const = 0;
};
  • OpenCV uses Macros to identify symbols to binding generators

Binding code for MSER Class

emscripten::class_<cv::MSER ,base<Feature2D>>("MSER")
    
    .function("getPass2Only", select_overload<bool(cv::MSER&)>(&Wrappers::MSER_getPass2Only_wrap),pure_virtual() )
    .function("setMinArea", select_overload<void(cv::MSER&,int)>(&Wrappers::MSER_setMinArea_wrap),pure_virtual() )
    .function("getDelta", select_overload<int(cv::MSER&)>(&Wrappers::MSER_getDelta_wrap),pure_virtual() )
    .class_function("create",select_overload<Ptr<MSER>(int,int,int,double,double,int,double,double,int)>(&Wrappers::create_MSER_wrapper))
    .function("getMaxArea", select_overload<int(cv::MSER&)>(&Wrappers::MSER_getMaxArea_wrap),pure_virtual() )
    .function("setMaxArea", select_overload<void(cv::MSER&,int)>(&Wrappers::MSER_setMaxArea_wrap),pure_virtual() )
    .function("setPass2Only", select_overload<void(cv::MSER&,bool)>(&Wrappers::MSER_setPass2Only_wrap),pure_virtual() )
    .function("getMinArea", select_overload<int(cv::MSER&)>(&Wrappers::MSER_getMinArea_wrap),pure_virtual() )
    .function("detectRegions", select_overload<void(cv::MSER&,const cv::Mat&, std::vector<std::vector<Point> >&,std::vector<Rect>&)>(&Wrappers::MSER_detectRegions_wrap),pure_virtual() )
    .function("setDelta", select_overload<void(cv::MSER&,int)>(&Wrappers::MSER_setDelta_wrap),pure_virtual() )
;

Binding Generator Script

  • parses all OpenCV headers
    • extracts all the symbols with OpenCV Wrap macros
      • classes
      • functions
      • class functions
      • properties
      • enumerations and constants
    • generates appropriate binding for each type

Results

  • We have covered six modules so far

    • core
    • image processing
    • object detection
    • features_2d
    • image codecs
    • machine learning

60 classes

800 functions(including class methods)

80 Enums

  • Function overloading
  • Default parameters

C++ code

JS code

void erode(){

   Mat image,dst;
   image = imread("image.jpg", CV_LOAD_IMAGE_COLOR);  
 
   // Create a structuring element
   int erosion_size = 6;  
   Mat element = getStructuringElement(cv::MORPH_RECT,
   cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
   cv::Point(erosion_size, erosion_size) );
 
   // Apply erosion or dilation on the image
   erode(image,dst,element);  
   
   namedWindow( "Display window", CV_WINDOW_AUTOSIZE );  
   imshow( "Display window", image );                 
 
   namedWindow( "Result window", CV_WINDOW_AUTOSIZE );   
   imshow( "Result window", dst );
}
function erode(){
    var src = cv.matFromArray( getInput() , cv.CV_8UC4 ); 
    var dst = new cv.Mat();
    cv.cvtColor(src, src , 
        cv.cv_ColorConversionCodes.COLOR_RGBA2RGB.value,0);

    // Create a structuring element
    var erosion_type = cv.cv_MorphShapes.MORPH_RECT.value;

    var erosion_size=new cv.Size(2*Control.erosion_size+1,
         2*Control.erosion_size+1 );

    var element = cv.getStructuringElement( erosion_type 
        ,erosion_size  ) ;

    
    // Apply erosion or dilation on the image   
    cv.erode(src, dst, element) ;

    show_image( dst , "canvas2");
    
    // Clean up   
    src.delete();
    dst.delete();
    erosion_size.delete();
				
}

Erode Function

Core and image processing modules

Feature Extraction module

HAAR object detection - Working with HTML5 video element

  • Image/Video are coming from HTML Canvas

  • interface to grab/show image from HTML canvas
  • Canvas API gets images in RGBA format

    • OpenCV likes RGB better

  • Canvas only supports data with 8 bits per pixels

    • depth data are represented with 16 bits per pixels

    • work in progress to fix this

Input/Output Interface

Challenges

  • Generated JS files are big

    • 10MB for library itself

    • 2 MB for haar cascade face and eye models

  • Downloading and Parsing will be time consuming

    • JS library and files are gzipped

    • will be extracted after Emscripten system initialization

    • Web Assembly

  • OpenCV is not fully covered

    • Anonymous Enums are not supported by Embind

  • Some issues with SSE2

Performance

  • Sources of penalty

    • how well browsers supports asm.js

    • Data should be copied into/from ASM.js heap

      • before computation

      • after computation

        • saved on this by returning a pointer to the heap

    • Wrapper functions overhead

    • Image format conversion

      • RGBA -> RGB and vice versa

Text

Thanks!

OpenCV.js

By Sajjad Taheri

OpenCV.js

  • 613