Skip to content

Commit

Permalink
[apriltag] Make AprilTagDetector.detect() use RawFrame instead of Ope…
Browse files Browse the repository at this point in the history
…nCV Mat
  • Loading branch information
calcmogul committed Dec 22, 2024
1 parent 469bb32 commit 43093e8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package edu.wpi.first.apriltag;

import edu.wpi.first.apriltag.jni.AprilTagJNI;
import org.opencv.core.Mat;
import edu.wpi.first.util.RawFrame;

/**
* An AprilTag detector engine. This is expensive to set up and tear down, so most use cases should
Expand Down Expand Up @@ -293,11 +293,12 @@ public void clearFamilies() {
*
* <p>The image must be grayscale.
*
* @param img 8-bit OpenCV Mat image
* @param frame The frame object containing an 8-bit image.
* @return Results (array of AprilTagDetection)
*/
public AprilTagDetection[] detect(Mat img) {
return AprilTagJNI.detect(m_native, img.cols(), img.rows(), (int) img.step1(), img.dataAddr());
public AprilTagDetection[] detect(RawFrame frame) {
return AprilTagJNI.detect(
m_native, frame.getWidth(), frame.getHeight(), frame.getWidth(), frame.getDataPtr());
}

private long m_native;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.util.PixelFormat;
import edu.wpi.first.util.RawFrame;
import edu.wpi.first.util.RuntimeLoader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -171,8 +173,15 @@ void testDecodeAndPose() {
fail(ex);
return;
}

var frameBytes = new byte[image.width() * image.height()];
image.get(0, 0, frameBytes);

var frame = new RawFrame();
frame.setData(frameBytes, image.width(), image.height(), 1, PixelFormat.kGray);

try {
AprilTagDetection[] results = detector.detect(image);
AprilTagDetection[] results = detector.detect(frame);
assertEquals(1, results.length);
assertEquals("tag36h11", results[0].getFamily());
assertEquals(1, results[0].getId());
Expand Down Expand Up @@ -204,8 +213,15 @@ void testPoseRotatedX() {
fail(ex);
return;
}

var frameBytes = new byte[image.width() * image.height()];
image.get(0, 0, frameBytes);

var frame = new RawFrame();
frame.setData(frameBytes, image.width(), image.height(), 1, PixelFormat.kGray);

try {
AprilTagDetection[] results = detector.detect(image);
AprilTagDetection[] results = detector.detect(frame);
assertEquals(1, results.length);

var estimator =
Expand Down Expand Up @@ -237,8 +253,15 @@ void testPoseRotatedY() {
fail(ex);
return;
}

var frameBytes = new byte[image.width() * image.height()];
image.get(0, 0, frameBytes);

var frame = new RawFrame();
frame.setData(frameBytes, image.width(), image.height(), 1, PixelFormat.kGray);

try {
AprilTagDetection[] results = detector.detect(image);
AprilTagDetection[] results = detector.detect(frame);
assertEquals(1, results.length);

var estimator =
Expand Down Expand Up @@ -267,8 +290,15 @@ void testPoseStraightOn() {
fail(ex);
return;
}

var frameBytes = new byte[image.width() * image.height()];
image.get(0, 0, frameBytes);

var frame = new RawFrame();
frame.setData(frameBytes, image.width(), image.height(), 1, PixelFormat.kGray);

try {
AprilTagDetection[] results = detector.detect(image);
AprilTagDetection[] results = detector.detect(frame);
assertEquals(1, results.length);

var estimator =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import edu.wpi.first.networktables.IntegerArrayPublisher;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.util.PixelFormat;
import edu.wpi.first.util.RawFrame;
import edu.wpi.first.wpilibj.TimedRobot;
import java.util.ArrayList;
import org.opencv.core.Mat;
Expand Down Expand Up @@ -65,6 +67,9 @@ void apriltagVisionThreadProc() {
var mat = new Mat();
var grayMat = new Mat();

var frameBytes = new byte[640 * 480];
var frame = new RawFrame();

// Instantiate once
ArrayList<Long> tags = new ArrayList<>();
var outlineColor = new Scalar(0, 255, 0);
Expand All @@ -89,7 +94,10 @@ void apriltagVisionThreadProc() {

Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_RGB2GRAY);

AprilTagDetection[] detections = detector.detect(grayMat);
grayMat.get(0, 0, frameBytes);
frame.setData(frameBytes, grayMat.width(), grayMat.height(), 1, PixelFormat.kGray);

AprilTagDetection[] detections = detector.detect(frame);

// have not seen any tags yet
tags.clear();
Expand Down
16 changes: 16 additions & 0 deletions wpiutil/src/main/java/edu/wpi/first/util/RawFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ public void setData(ByteBuffer data, int width, int height, int stride, PixelFor
m_nativeObj, data, data.limit(), width, height, stride, pixelFormat.getValue());
}

/**
* Set frame data.
*
* @param data A byte array containing the frame data.
* @param width The width of the frame, in pixels
* @param height The height of the frame, in pixels
* @param stride The number of bytes in each row of image data
* @param pixelFormat The PixelFormat of the frame
*/
public void setData(byte[] data, int width, int height, int stride, PixelFormat pixelFormat) {
var dataByteBuffer = ByteBuffer.allocateDirect(width * height * stride);
dataByteBuffer.put(data);

setData(dataByteBuffer, width, height, stride, pixelFormat);
}

/**
* Call to set frame information.
*
Expand Down

0 comments on commit 43093e8

Please sign in to comment.