Java OpenCV 阿鲁科垫
Java OpenCV Aruco Mat
我正在尝试将 Android 相机预览图像输入 OpenCV 以检测 Aruco 代码。根据之前的工作,目前的流程如下:
- 我有一个 YUV
Image.Plane
。
- 我把它喂给ZXing
PlanarYUVLuminanceSource
。
- 对此我调用
getMatrix()
,它给出了 byte[]
的亮度值。
- 检查 https://github.com/jsmith613/Aruco-Marker-Tracking-Android/,我注意到它正在调用
(CvCameraViewFrame).rgba()
,返回的 Mat
是 CV_8UC4
类型。我注意到调用 (Mat).get(0, 0)
会产生 double[4]
,例如 {1, 4, 2, 255}
,我推断这些对应于 RGBA。然后 Mat
传递给 (MarkerDetector).detect()
.
- 因此,我构建了一个具有相同形式和类型的
Mat
并加载了数据。
Mat mat = new Mat(width, height, CvType.CV_8UC4, new Scalar(0.0, 0.0, 0.0, 255.0));
- (对于 x 和 y:)
int lum = matrix[y * w + x] & 0xFF; mat.put(x, y, new double[]{lum, lum, lum, 255});
- 然后我把这个
Mat
给检测器。
它 有效 ,但是 for 循环很慢 - 复制所有像素大约需要一秒钟。我强烈怀疑有更快的方法 - 肯定有办法将普通字节数组传递给 Mat
?仍然可以与 (MarkerDetector).detect()
?
一起使用的一个
我的代码,一旦我有了 PlanarYUVLuminanceSource
(source
),如下所示:
Mat mat = new Mat(width, height, CvType.CV_8UC4, new Scalar(0.0, 0.0, 0.0, 255.0));
byte[] matrix = source.getMatrix();
double[] pixel = new double[]{0,0,0,255};
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int luminance = matrix[y * width + x] & 0xFF;
pixel[0] = luminance;
pixel[1] = luminance;
pixel[2] = luminance;
mat.put(x, y, pixel);
}
}
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
好的,我成功了:
Mat mat = new Mat(height, width, CvType.CV_8UC4);
byte[] matrix = source.getMatrix();
byte[] temp = new byte[width * height * 4];
int i = 0;
mat.get(0, 0, temp);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
byte luminance = matrix[y * width + x];
temp[i++] = luminance;
temp[i++] = luminance;
temp[i++] = luminance;
temp[i++] = (byte)255;
}
}
mat.put(0, 0, temp);
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
如果您更改 MarkerDetector
以跳过 Imgproc.cvtColor
并使用 in
而不是 grey
,您可以改为:
Mat mat = new Mat(height, width, CvType.CV_8UC1);
byte[] matrix = source.getMatrix();
byte[] temp = new byte[width * height];
int i = 0;
mat.get(0, 0, temp);
System.arraycopy(matrix, 0, temp, 0, width * height);
mat.put(0, 0, temp);
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
旁注 - 我还没有做足够的测试来确定,但似乎如果你重复使用 mMarkerDetector
,检测会随着时间的推移逐渐变慢,但每次制作一个新的检测速度都相对较快。
此外,请注意,我最初交换了矩阵的维度 - 它似乎没有影响我的原始代码,但它确实影响了我输入原始数组的时间。
(请注意,所有这些代码在我的 IDE 和我的浏览器之间的传输过程中都发生了一些变化 - 不过它应该可以工作。)
我正在尝试将 Android 相机预览图像输入 OpenCV 以检测 Aruco 代码。根据之前的工作,目前的流程如下:
- 我有一个 YUV
Image.Plane
。 - 我把它喂给ZXing
PlanarYUVLuminanceSource
。 - 对此我调用
getMatrix()
,它给出了byte[]
的亮度值。 - 检查 https://github.com/jsmith613/Aruco-Marker-Tracking-Android/,我注意到它正在调用
(CvCameraViewFrame).rgba()
,返回的Mat
是CV_8UC4
类型。我注意到调用(Mat).get(0, 0)
会产生double[4]
,例如{1, 4, 2, 255}
,我推断这些对应于 RGBA。然后Mat
传递给(MarkerDetector).detect()
. - 因此,我构建了一个具有相同形式和类型的
Mat
并加载了数据。 Mat mat = new Mat(width, height, CvType.CV_8UC4, new Scalar(0.0, 0.0, 0.0, 255.0));
- (对于 x 和 y:)
int lum = matrix[y * w + x] & 0xFF; mat.put(x, y, new double[]{lum, lum, lum, 255});
- 然后我把这个
Mat
给检测器。
它 有效 ,但是 for 循环很慢 - 复制所有像素大约需要一秒钟。我强烈怀疑有更快的方法 - 肯定有办法将普通字节数组传递给 Mat
?仍然可以与 (MarkerDetector).detect()
?
我的代码,一旦我有了 PlanarYUVLuminanceSource
(source
),如下所示:
Mat mat = new Mat(width, height, CvType.CV_8UC4, new Scalar(0.0, 0.0, 0.0, 255.0));
byte[] matrix = source.getMatrix();
double[] pixel = new double[]{0,0,0,255};
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int luminance = matrix[y * width + x] & 0xFF;
pixel[0] = luminance;
pixel[1] = luminance;
pixel[2] = luminance;
mat.put(x, y, pixel);
}
}
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
好的,我成功了:
Mat mat = new Mat(height, width, CvType.CV_8UC4);
byte[] matrix = source.getMatrix();
byte[] temp = new byte[width * height * 4];
int i = 0;
mat.get(0, 0, temp);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
byte luminance = matrix[y * width + x];
temp[i++] = luminance;
temp[i++] = luminance;
temp[i++] = luminance;
temp[i++] = (byte)255;
}
}
mat.put(0, 0, temp);
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
如果您更改 MarkerDetector
以跳过 Imgproc.cvtColor
并使用 in
而不是 grey
,您可以改为:
Mat mat = new Mat(height, width, CvType.CV_8UC1);
byte[] matrix = source.getMatrix();
byte[] temp = new byte[width * height];
int i = 0;
mat.get(0, 0, temp);
System.arraycopy(matrix, 0, temp, 0, width * height);
mat.put(0, 0, temp);
Vector<Marker> markers = new Vector<>();
mMarkerDetector.detect(mat, result, mCameraParameters, Constants.ARUCO_MARKER_SIZE, null);
旁注 - 我还没有做足够的测试来确定,但似乎如果你重复使用 mMarkerDetector
,检测会随着时间的推移逐渐变慢,但每次制作一个新的检测速度都相对较快。
此外,请注意,我最初交换了矩阵的维度 - 它似乎没有影响我的原始代码,但它确实影响了我输入原始数组的时间。
(请注意,所有这些代码在我的 IDE 和我的浏览器之间的传输过程中都发生了一些变化 - 不过它应该可以工作。)