Java 如何从openCV android中的字节[]获取Mat对象?
我正在Android中使用OpenCV库。我有一个类实现了Java 如何从openCV android中的字节[]获取Mat对象?,java,android,opencv,image-processing,bitmap,Java,Android,Opencv,Image Processing,Bitmap,我正在Android中使用OpenCV库。我有一个类实现了PictureCallBack 覆盖方法onPictureTaken()如下所示 @Override public void onPictureTaken(byte[] data, Camera camera) { Log.i(TAG, "Saving a bitmap to file"); // The camera preview was automatically stopped. Start it aga
PictureCallBack
覆盖方法onPictureTaken()
如下所示
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
因为我希望在图像处理中进一步使用图像数据,而不是保存和重新加载图像
从字节数组获取Mat对象的最有效方法是什么?
我已经尝试过这些方法:
Mat m=new Mat();
m、 put(0,0,数据)代码>
bitmapToMat()
在这种情况下,红色变为蓝色在保存图像以备将来使用时,我也没有遇到任何问题,但这导致了一个例外,因为当我使用以前存储的图像时,文件尚未生成。您必须指定图像/Mat的宽度和高度以及通道深度
Mat mat = new Mat(width, height, CvType.CV_8UC3);
mat.put(0, 0, data);
确保您使用的垫子类型正确。可能您的数据不是3字节RGB格式,您应该使用其他类型,例如CvType.CV\u 8UC1
祝你好运 opencv有一种将Mats写入文件的简洁方法——它可以根据提供的文件扩展名生成不同的格式。下面是一个简单的例子:
public void writeImageToFile(Mat image, String filename) {
File root = Environment.getExternalStorageDirectory();
File file = new File(root, filename);
Highgui.imwrite(file.getAbsolutePath(), image);
if (DEBUG)
Log.d(TAG,
"writing: " + file.getAbsolutePath() + " (" + image.width()
+ ", " + image.height() + ")");
}
如果红色和蓝色被交换,那么听起来好像onPictureTaken()中的字节数据是BGRA格式的。您可以使用以下方式将其交换为RGBA:
Imgproc.cvtColor(bgrImg, rgbImg, Imgproc.COLOR_BGR2RGB);
该格式实际上是特定于设备的-在我使用的一台设备上,它以YUV的形式出现。最好、最简单的方法如下:
byte[] bytes = FileUtils.readFileToByteArray(new File("aaa.jpg"));
Mat mat = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
对我来说,下一步对我来说很好: Java端:
Bitmap bitmap = mTextureView.getBitmap(mWidth, mHeight);
int[] argb = new int[mWidth * mHeight];
// get ARGB pixels and then proccess it with 8UC4 OpenCV convertion
bitmap.getPixels(argb, 0, mWidth, 0, 0, mWidth, mHeight);
// native method (NDK or CMake)
processFrame8UC4(argb, mWidth, mHeight);
JNIEXPORT jint JNICALL com_native_detector_Utils_processFrame8UC4
(JNIEnv *env, jobject object, jint width, jint height, jintArray frame) {
jint *pFrameData = env->GetIntArrayElements(frame, 0);
// it is the line:
Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();
// your code..
env->ReleaseIntArrayElements(frame, pFrameData, 0);
}
OpenCV侧(NDK):
Bitmap bitmap = mTextureView.getBitmap(mWidth, mHeight);
int[] argb = new int[mWidth * mHeight];
// get ARGB pixels and then proccess it with 8UC4 OpenCV convertion
bitmap.getPixels(argb, 0, mWidth, 0, 0, mWidth, mHeight);
// native method (NDK or CMake)
processFrame8UC4(argb, mWidth, mHeight);
JNIEXPORT jint JNICALL com_native_detector_Utils_processFrame8UC4
(JNIEnv *env, jobject object, jint width, jint height, jintArray frame) {
jint *pFrameData = env->GetIntArrayElements(frame, 0);
// it is the line:
Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();
// your code..
env->ReleaseIntArrayElements(frame, pFrameData, 0);
}
您可以使用作为opencv一部分的imdecode方法(这是针对emgucv的,但在其他版本的opencv上应该有类似的操作,语法可能不同) 例如:
byte [] imageArray
Mat dest
CvInvoke.Imdecode(imageArray, ImreadModes.Unchanged, dest)
你能定义数据吗??它是什么?
数据
是字节[]
数组,包含一系列正确格式的像素。它可以从例如buffereImage
-byte[]data=((DataBufferByte)image.getRaster().getDataBuffer()).getData()获取代码>高度和宽度参数是错误的。垫=新垫(高度、宽度CvType.CV_8UC3);我在很多类似的问题上都看到了这一点,但它导致了与内存相关的崩溃。当图像大于预期的Mat输出时,这似乎不是一个可行的解决方案。