我试图从相机API中捕获数据并进行颜色后处理。我的问题是,虽然我可以将byte []对象转换为Mat对象,但我无法在没有收到错误的情况下获取颜色通道。我从以下帖子开始:How to get the Mat object from the Byte[] in openCV android?但该实现不起作用。
以下是相关代码:
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
File pictureFile_interp = getOutputMediaFile(MEDIA_TYPE_IMAGE);
try {
//Now try to convert and save.
Parameters params = camera.getParameters();
Size sz = params.getPictureSize();
//ERROR IN THE LINE BELOW!!!!
Mat raw = new Mat(sz.height,sz.width,CvType.CV_8UC4);
raw.put(0, 0, data);
Mat targ = Highgui.imdecode(raw, 0);
orig = new Mat();
Imgproc.cvtColor(targ, orig, Imgproc.COLOR_GRAY2RGB);
//Imgproc.cvtColor(targ, fixed, Imgproc.COLOR_BGR2RGB);
//now we have the target we want...let's interpolate.
interp = interpExperiment(orig,interpBy);
Highgui.imwrite(pictureFile_interp.toString(), interp);
} finally{
}
}
当我尝试该代码时,我得到一个例外:
Provided data element number should be multiple of the Mat channels count (3)
相反,我用
替换有问题的行Mat raw = new Mat(sz.height,sz.width,CvType.CV_8U);
raw.put(0, 0, data);
Mat targ = Highgui.imdecode(raw, 0);
我可以获得灰度图像。
我做错了什么Mat raw = new Mat(sz.height,sz.width,CvType.CV_8UC3);
?我已经查看了很多针对此问题的stackoverflow帖子,并且没有一个适用于颜色矩阵。非常感谢任何帮助。
答案 0 :(得分:3)
我找到了一个解决方法:使用Bitmapfactory,您可以将byte []数组转换为位图,然后您可以将其正确转换为Mat。
Bitmap bmp = BitmapFactory.decodeByteArray(data , 0, data.length);
Mat orig = new Mat(bmp.getHeight(),bmp.getWidth(),CvType.CV_8UC3);
Bitmap myBitmap32 = bmp.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(myBitmap32, orig);
Imgproc.cvtColor(orig, orig, Imgproc.COLOR_BGR2RGB,4);
似乎应该有一个更好的方法,但这有效。
答案 1 :(得分:3)
public Mat Byte_to_Mat(byte[] data) {
Mat jpegData = new Mat(1, data.length, CvType.CV_8UC1);
jpegData.put(0, 0, data);
Mat bgrMat = new Mat();
bgrMat = Highgui.imdecode(jpegData, Highgui.IMREAD_COLOR);
答案 2 :(得分:1)
使用时:
raw.put(0, 0, data);
您通常会在点(0,0)设置像素的所有通道值;因此,如果您有3通道图像,那么您将提供三个值的字节数组,如:
byte data[] = {1,2,3}
您可以一次设置多个像素,但关键是您的数据阵列需要多个通道,否则opencv将不知道要查看所有像素值的内容。所以,例如,再次对于3频道的Mat,你是允许的:
byte data[] = {1,2,3,4,5,6};
这会将像素值(0,0)设置为(1,2,3)和(0,1)设置为(4,5,6)
但不是:
byte data[] = {1,2,3,4,5,6,7};
这就是7个元素,它不是3的倍数。
当您的数据阵列长度不是通道数的倍数时,您会看到错误。
您应该检查数据阵列的实际格式。根据我在设备上的经验,它往往是YUV,它与RGB的尺寸不同,因此需要进行一些转换。
答案 3 :(得分:1)
您获得的数据很可能是YUV
格式。它通常是1通道矩阵,如果它是RGB或灰度和相同的宽度,高度是图像高度的1.5倍。
Mat raw = new Mat(sz.height*1.5,sz.width,CvType.CV_8UC1); // YUV data
raw.put(0, 0, data);
orig = new Mat(sz.height, sz.height, CvType.CV_8UC4); // RGBA image
Imgproc.cvtColor(raw, orig, Imgproc.COLOR_YUV2RGBA_NV21); // This might vary depending on the camera image type
答案 4 :(得分:0)
@ user3502402所做的更改绝对正确。您只需要在Highgui.imdecode(raw, 1)
中将标志从0更改为1,代码就会生成完美的彩色照片