Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

OpenCV Mat object

David Miguel Lozano edited this page Oct 6, 2016 · 2 revisions

Instantiation

Mat image1 = new Mat(480,640,CvType.CV_8U);
Mat image3 = new Mat(new Size(640,480), CvType.CV_8U, new Scalar(255);
Mat image2 = new Mat(new Size(640,480), CvType.CV_8UC3);
Mat image3 = new Mat(new Size(640,480), CvType.CV_8UC3, new Scalar(new double[]{128,3,4})); // BGR

OpenCV stores its matrix internally in the BGR (blue, green, and red) format.

It is important to note that while creating the matrix with a specifed size and type, it will also immediately allocate memory for its contents.

Getting info

  • image1.dump(): print a matrix's contents.
  • image1.rows(): number of rows.
  • image1.cols(): number of cols.
  • image.total(): total number of pixels.
  • image1.elemSize(): number of bytes per pixel (channels).
  • image1.isContinuous(): if the matrix uses extra padding when representing the image, so that it can be hardware-accelerated in some platforms.
  • image1.isSubmatrix(): if the matrix was created from another matrix and also whether it refers to the data from another matrix.
  • image1.getNativeObjAddr(): native object address, which is a Java Native Interface (JNI) detail.
  • image1.dataAddr(): points to an internal data address.

Pixel manipulation

Fill matrix with values {128, 3, 4} (Blue,Green,Red):

Mat image = new Mat(new Size(3,3), CvType.CV_8UC3);
for(int i=0;i<image.rows();i++){
    for(int j=0;j<image.cols();j++){
        image.put(i, j, new byte[]{128,3,4});
    }
}
image.dump();

Result:

[128, 3, 4, 128, 3, 4, 128, 3, 4;
 128, 3, 4, 128, 3, 4, 128, 3, 4;
 128, 3, 4, 128, 3, 4, 128, 3, 4]

It is okay to access pixels this way for small matrices. The only problem is the overhead of JNI calls for big images. On the other hand, if we manipulate the whole matrix on the Java side and then copy it to the native side in a single call, it will be much more efficient:

  1. Allocate memory with the same size as the matrix in a byte array.
  2. Put the image contents into that array (optional).
  3. Manipulate the byte array contents.
  4. Make a single put call, copying the whole byte array to the matrix.

Example:

public void threshold(Mat image) {
    int totalBytes = (int) (image.total() * image.elemSize());
    byte buffer[] = new byte[totalBytes];
    image.get(0, 0, buffer);
    for (int i = 0; i < totalBytes; i++) {
        if (buffer[i] < THRESHOLD) buffer[i] = 0;
    }
    image.put(0, 0, buffer);
}

References