Android将字节数组从Camera API转换为颜色Mat对象openCV

时间:2014-04-21 17:12:48

标签: android c++ opencv

我试图从相机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帖子,并且没有一个适用于颜色矩阵。非常感谢任何帮助。

5 个答案:

答案 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,代码就会生成完美的彩色照片