Conversion between Processing PImage and OpenCV cv::Mat

This example illustrates the use of the Java version of OpenCV. I built the OpenCV 2.4.8 in Mac OSX 10.9. After building, I copied the following two files to the code folder of the Processing sketch:

  • opencv-248.jar
  • libopencv_java248.dylib

The program initialised the default video capture device. It converted the PImage first into an OpenCV matrix – Mat. The matrix is duplicated into another copy and then converted back to another PImage for display with the image command.
 
It can achieve around 60 frame per second in my old iMac. Here is the screenshot.
 

 

import processing.video.*;
 
import java.util.*;
import java.nio.*;
 
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
 
Capture cap;
PImage img;
 
byte [] bArray;
int [] iArray;
int pixCnt1, pixCnt2;
 
void setup() {
  size(640, 480);
  background(0);
  // Define and initialise the default capture device.
  cap = new Capture(this, width, height);
  cap.start();
 
  // Load the OpenCV native library.
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  println(Core.VERSION);
 
  // pixCnt1 is the number of bytes in the pixel buffer.
  // pixCnt2 is the number of integers in the PImage pixels buffer.
  pixCnt1 = width*height*4;
  pixCnt2 = width*height;
 
  // bArray is the temporary byte array buffer for OpenCV cv::Mat.
  // iArray is the temporary integer array buffer for PImage pixels.
  bArray = new byte[pixCnt1];
  iArray = new int[pixCnt2];
 
  img = createImage(width, height, ARGB);
}
 
void draw() {
  // Copy the webcam image to the temporary integer array iArray.
  arrayCopy(cap.pixels, iArray);
 
  // Define the temporary Java byte and integer buffers. 
  // They share the same storage.
  ByteBuffer bBuf = ByteBuffer.allocate(pixCnt1);
  IntBuffer iBuf = bBuf.asIntBuffer();
 
  // Copy the webcam image to the byte buffer iBuf.
  iBuf.put(iArray);
 
  // Copy the webcam image to the byte array bArray.
  bBuf.get(bArray);
 
  // Create the OpenCV cv::Mat.
  Mat m1 = new Mat(cap.height, cap.width, CvType.CV_8UC4);
 
  // Initialise the matrix m1 with content from bArray.
  m1.put(0, 0, bArray);
 
  // Clone m1 into another matrix m2. Now m2 is an exact copy of m1.
  Mat m2 = m1.clone();
 
  // Copy content of m2 to the byte array bArray.
  m2.get(0, 0, bArray);
 
  // Treat bArray as an integer buffer and copy the content to iArray.
  ByteBuffer.wrap(bArray).asIntBuffer().get(iArray);
 
  // Copy the content of iArray to the PImage img pixels buffer.
  arrayCopy(iArray, img.pixels);
  img.updatePixels();
 
  // Display the new image img.
  image(img, 0, 0);
 
  text("Frame Rate: " + round(frameRate), 500, 50);
}
 
void captureEvent(Capture _c) {
  _c.read();
}