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:
- List filenames in the
assets
folder: UseAssetManager
to list all files in theassets
folder. - Load template images: Use
AssetManager
to open each asset file as anInputStream
and convert it to an OpenCVMat
.
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:
- Access
AssetManager
: TheAssetManager
is obtained using thegetAssets()
method. - List Files in
assets
: TheassetManager.list("")
method is used to list all filenames in theassets
folder. - Load Files from
assets
: For each filename, anInputStream
is opened usingassetManager.open(filename)
, and the content is read and converted to an OpenCVMat
using a helper methodloadMatFromInputStream(InputStream inputStream)
. - 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
.