To read files from the assets folder in an Android project, you will need to use the AssetManager class. The AssetManager class provides access to an application’s raw asset files.

Here’s how you can list the filenames in the assets folder and load the template images from there:

  1. List filenames in the assets folder: Use AssetManager to list all files in the assets folder.
  2. Load template images: Use AssetManager to open each asset file as an InputStream and convert it to an OpenCV Mat.

Here’s an example:

package jp.jaxa.iss.kibo.rpc.sampleapk;
 
import android.content.res.AssetManager;
import android.util.Log;
import gov.nasa.arc.astrobee.Result;
import jp.jaxa.iss.kibo.rpc.api.KiboRpcService;
import org.opencv.aruco.Aruco;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.aruco.Dictionary;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
 
public class YourService extends KiboRpcService {
 
    private final String TAG = this.getClass().getSimpleName();
 
    @Override
    protected void runPlan1() {
        // The mission starts: Undocks Astrobee from docking station, starts timer, returns Success/Failure
        api.startMission();
        Log.i(TAG, "Start mission");
 
        // Move to point1 (1st attempt)
        Point point = new Point(11d, -9.88d, 5.195d);
        Quaternion quaternion = new Quaternion(0.5f, -0.6f, -0.707f, 0.707f);
        Result result = api.moveTo(point, quaternion, true);
 
        // Check result and loop while moveTo() has not succeeded
        final int LOOP_MAX = 7;
        int loopCounter = 0;
        while (!result.hasSucceeded() && loopCounter < LOOP_MAX) {
            // Retry
            result = api.moveTo(point, quaternion, true);
            ++loopCounter;
        }
 
        // Get a camera image.
        Mat image = api.getMatNavCam();
 
        if (image == null) {
            // Error handling
            Log.i(TAG, "No image");
        } else {
            detectAR(image);
            api.saveMatImage(image, "image_detected_markers.png");
 
            Mat undistortImg = correctImageDistortion(image);
            api.saveMatImage(undistortImg, "undistort_image_detected_markers.png");
 
            // Pattern matching
            AssetManager assetManager = getAssets();
            try {
                String[] templateFileNames = assetManager.list("");
                if (templateFileNames != null) {
                    Mat[] templates = new Mat[templateFileNames.length];
                    int[] templateMatchCnt = new int[templateFileNames.length];
                    
                    for (int i = 0; i < templateFileNames.length; i++) {
                        InputStream inputStream = assetManager.open(templateFileNames[i]);
                        templates[i] = loadMatFromInputStream(inputStream);
                        if (templates[i].empty()) {
                            Log.e(TAG, "Failed to load template image: " + templateFileNames[i]);
                        } else {
                            templateMatchCnt[i] = matchTemplate(undistortImg, templates[i]);
                            Log.i(TAG, "Template " + templateFileNames[i] + " matches: " + templateMatchCnt[i]);
                        }
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, "Error loading template images", e);
            }
        }
 
        /*************************************************************************/
        /* Write your code to recognize type and number of items in each area! */
        /*************************************************************************/
 
        // When you recognize items, let’s set the type and number.
        api.setAreaInfo(1, "item_name", 1);
 
        /******************************************************/
        /* Let's move to the each area and recognize the items. */
        /******************************************************/
 
        // When you move to the front of the astronaut, report the rounding completion.
        api.reportRoundingCompletion();
 
        /************************************************************/
        /* Write your code to recognize which item the astronaut has. */
        /************************************************************/
 
        // Let's notify the astronaut when you recognize it.
        api.notifyRecognitionItem();
 
        /*********************************************************************************************************/
        /* Write your code to move Astrobee to the location of the target item (what the astronaut is looking for) */
        /*********************************************************************************************************/
 
        // Take a snapshot of the target item.
        api.takeTargetItemSnapshot();
    }
 
    // Load Mat from InputStream
    private Mat loadMatFromInputStream(InputStream inputStream) {
        Mat image = new Mat();
        try {
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            image = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.IMREAD_GRAYSCALE);
        } catch (Exception e) {
            Log.e(TAG, "Error loading Mat from InputStream", e);
        }
        return image;
    }
 
    // Detect AR and draw markers
    private void detectAR(Mat image) {
        Dictionary dictionary = Aruco.getPredefinedDictionary(Aruco.DICT_5X5_250); // Load predefined ArUco dict of 250 unique 5x5 markers
        List<Mat> corners = new ArrayList<>();
        Mat markerIds = new Mat();
        Aruco.detectMarkers(image, dictionary, corners, markerIds); // Detect markers and store the corners and IDs
 
        // Convert image to RGB color space
        Imgproc.cvtColor(image, image, Imgproc.COLOR_GRAY2RGB);
 
        // Draw detected markers on image
        if (!markerIds.empty()) {
            Scalar green = new Scalar(0, 255, 0);
            Scalar red = new Scalar(255, 0, 0);
            Aruco.drawDetectedMarkers(image, corners); //, markerIds, green);
 
            // Draw marker ID label
            if (corners.size() > 0) {
                Mat firstCorner = corners.get(0);
                double x = firstCorner.get(0, 0)[0];
                double y = firstCorner.get(0, 0)[1];
                Point labelPos = new Point(x, y - 30); // Offset
                int markerId = (int) markerIds.get(0, 0)[0];
                Imgproc.putText(image, "id=" + markerId, labelPos, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, red, 2);
            }
 
            Log.i(TAG, "Markers detected: " + markerIds.dump());
        } else {
            Log.i(TAG, "No markers detected.");
        }
    }
 
    // Correct image distortion
    private Mat correctImageDistortion(Mat image) {
        // Get camera matrix and populate with camera intrinsics
        Mat cameraMatrix = new Mat(3, 3, CvType.CV_64F);
        cameraMatrix.put(0, 0, api.getNavCamIntrinsics()[0]);
 
        // Get lens distortion parameters
        Mat cameraCoefficients = new Mat(1, 5, CvType.CV_64F);
        cameraCoefficients.put(0, 0, api.getNavCamIntrinsics()[1]);
        cameraCoefficients.convertTo(cameraCoefficients, CvType.CV_64F);
 
        // Undistort image
        Mat undistortImg = new Mat();
        Calib3d.undistort(image, undistortImg, cameraMatrix, cameraCoefficients);
 
        return undistortImg;
    }
 
    // Template matching method
    private int matchTemplate(Mat image, Mat template) {
        Mat result = new Mat();
        Imgproc.matchTemplate(image, template, result, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        return mmr.maxLoc.x > 0 ? 1 : 0;
    }
 
    @Override
    protected void runPlan2() {
        // write your plan 2 here.
    }
 
    @Override
    protected void runPlan3() {
        // write your plan 3 here.
    }
 
    // You can add your method.
    private String yourMethod() {
        return "your method";
    }
}

Explanation:

  1. Access AssetManager: The AssetManager is obtained using the getAssets() method.
  2. List Files in assets: The assetManager.list("") method is used to list all filenames in the assets folder.
  3. Load Files from assets: For each filename, an InputStream is opened using assetManager.open(filename), and the content is read and converted to an OpenCV Mat using a helper method loadMatFromInputStream(InputStream inputStream).
  4. Pattern Matching: Each template is matched against the undistorted image, and results are logged.

Ensure the filenames in the assets folder match those specified in the TEMPLATE_FILE_NAMES array. The assets folder should be located in src/main/assets.