Using OpenCV to Read JPEGS to Mats on FRCVision Raspberry Pi

I am writing a program for a Raspberry Pi (3 Model B v 1.2) with the FRCVision image (v 2020.2.1, the latest at the time of this post) that uses OpenCV to calibrate a webcam from images of a chessboard pattern taken with the webcam. When testing code to read the .jpg files stored on the Pi into the Mat datatype that OpenCV uses for image processing, I encountered the runtime error unsatisfiedLinkError when I called the OpenCV method Imgcodecs.imread(String). The code is below. I was not sure how to set up the file structure on my own, so I downloaded FRCVision’s Java example program and replaced the Main file with my code. I understand this is not the ideal way of doing things, but I don’t think this is the source of my problem because the code built successfully and would have thrown a build error if the method had not been imported correctly.

/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.*;
import java.io.File;

public final class Main {
  /**
   * Main.
   */
  public static void main(String... args) {

    //Create a list of Mats to eventually use as input for findChessboardCorners()
    List<Mat> calibrationInputs = new ArrayList<Mat>();

    //Assign all the files in the folder calibrationInput to an array of Files
    //calibrationInput is a folder on the Pi containing .jpg images of a chessboard pattern 
    File calibDir = new File("calibrationInput/");
    File[] files = calibDir.listFiles();

    //Get each file in the array as a Mat and add them to the list of Mats
    for (File i : files){
      String path = i.getAbsolutePath();
      Mat inputImg = Imgcodecs.imread(path);
      calibrationInputs.add(inputImg);
    }

  }
}

In the documentation for the method there is a relevant note. I don’t really understand it, but I think it might explain the error:

On Linux*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for codecs supplied with an OS image. Install the relevant packages (do not forget the development files, for example, “libjpeg-dev”, in Debian* and Ubuntu*) to get the codec support or turn on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake.

Do you agree that what this note describes is the reason for the error? If so, could you help explain the steps I have to take to follow the note’s instructions on the Pi so I can use the Imgcodecs.imread(String) method? Any and all help is greatly appreciated.

Do you have the OpenCV Java library inluded in the Java library path?

1 Like

OpenCV does not load the JNI library automatically. You don’t need to do this in robot programs or most vision programs because CameraServerCvJNI loads the OpenCV library for you. However, you’re not using CameraServer, so you have to load the OpenCV library yourself with something like:

import org.opencv.core.Core;

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
1 Like

That fixed it, thanks so much for the help!