OpenCV for Android:使用 Imgproc.cvtColor 将相机预览从 YUV 转换为 RGB

Posted

技术标签:

【中文标题】OpenCV for Android:使用 Imgproc.cvtColor 将相机预览从 YUV 转换为 RGB【英文标题】:OpenCV for Android: Convert Camera preview from YUV to RGB with Imgproc.cvtColor 【发布时间】:2013-05-04 12:36:56 【问题描述】:

如果我尝试转换相机预览 YUV 字节数组,则会出现运行时错误 到带有 Imgproc.cvtColor( mYUV_Mat, mRgba_Mat, Imgproc.COLOR_YUV420sp2RGBA, 4 ) 的 RGB(A) 字节数组 在 onPreviewFrame(byte[] data, Camera camera):

Preview.java:

     mCamera.setPreviewCallback(new PreviewCallback() 
          public void onPreviewFrame(byte[] data, Camera camera)
          
            // Pass YUV data to draw-on-top companion
            System.arraycopy(data, 0, mDrawOnTop.mYUVData, 0, data.length);
            mDrawOnTop.invalidate();
          
       );

DrawOnTop.java:

public class DrawOnTop extends View 
Bitmap mBitmap;
Mat mYUV_Mat;
protected void onDraw(Canvas canvas) 
    if (mBitmap != null)
    

        canvasWidth = canvas.getWidth();
        canvasHeight = canvas.getHeight();
        int newImageWidth = 640;
        int newImageHeight = 480;
        marginWidth = (canvasWidth - newImageWidth)/2;

        if( mYUV_Mat != null ) mYUV_Mat.release();

        //mYUV_Mat = new Mat( newImageWidth, newImageHeight, CvType.CV_8UC1 );
        mYUV_Mat = new Mat( newImageWidth, newImageHeight, CvType.CV_8UC4 );
        mYUV_Mat.put( 0, 0, mYUVData );

        //Mat mRgba_Mat = new Mat();
        Mat mRgba_Mat = new Mat(newImageWidth,newImageHeight,CvType.CV_8UC4);

        //Mat mRgba_Mat = mYUV_Mat;

        //Imgproc.cvtColor( mYUV_Mat, mRgba_Mat, Imgproc.COLOR_YUV2RGBA_NV21, 4 );
        //Imgproc.cvtColor( mYUV_Mat, mRgba_Mat, Imgproc.COLOR_YUV420sp2RGB, 4 );
        Imgproc.cvtColor( mYUV_Mat, mRgba_Mat, Imgproc.COLOR_YUV420sp2RGBA, 4 );


        // Draw Bitmap New:
        Bitmap mBitmap = Bitmap.createBitmap( newImageWidth, newImageHeight, Bitmap.Config.ARGB_8888 );
        Utils.matToBitmap( mRgba_Mat, mBitmap );
        mRgba_Mat.release();


转换 mYUV_Mat.put( 0, 0, mYUVData ) 运行正确。 但是尝试使用 Imgproc.cvtColor 将 mYUV_Mat 转换为 mRgb_Mat 导致所有运行时错误(“找不到源。”使用 Eclipse)。

对于我的目标,正确的 Imgproc.cvtColor 命令是什么?

(我不想使用 Java YUV2RGB(A) 解码方法,因为它很慢 用于图像处理。我想使用 OpenCV Imgproc.cvtColor 方法 因为我可以进行本地调用)

【问题讨论】:

【参考方案1】:

也许Imgproc 库未正确包含在您的项目中,但其他 OpenCV 库包含?崩溃的那一行是您使用Imgproc 中的方法的第一行,这可以解释为什么前面的代码部分可以正确运行。

您的代码看起来不错,除了您可以为 mRgba_Mat 使用无参数构造函数(因为大多数 OpenCV4android 函数,包括 cvtColor,都可以推断出目标矩阵的所需大小),并且您分配了很多mYUV_Mat 的空间浪费。如果只为 YUV 矩阵分配比 RGB 矩阵多 50% 的空间,则不需要完整的 4 个通道:

mYUV_Mat = new Mat( newImageHeight + newImageHeight / 2, newImageWidth, CvType.CV_8UC1 );

【讨论】:

Mat构造函数的第一个参数不是一个高度和第二个宽度吗? IMO 第一个参数是行,实际上是图像的高度而不是宽度:P 是的,你是对的,论点应该颠倒过来。我正在修改问题中的代码,这也是错误的顺序。 谢谢!但我认为应该是Mat(height + height / 2, width, CvType.CV_8UC1 )高度是第一个参数)。 @AlexCohn 是的,之前在 cmets 中讨论过,但我当时没有做出改变。现在已经修好了。 @1'' 仍然是生成的垫子 - mRgba_Mat 没有给出全部三个通道,只有一个通道处于活动状态(给出 0-255 的值),其他两个为 0 为什么?

以上是关于OpenCV for Android:使用 Imgproc.cvtColor 将相机预览从 YUV 转换为 RGB的主要内容,如果未能解决你的问题,请参考以下文章

android中如何用opencv处理倾斜校正的问题,求源代码

怎样在eclipse中加载opencv for android

OpenCV for Android - 使用 SURF 描述符训练 SVM

关于Opencv的IplImage怎么把其每个点像素值提取出来

opencv for android(十六):opencv在android上的录制avi格式的视频

OpenCV - 如何以 Mat 形式编写 IplImage 数组?