Android OpenCv Utils:nMattBitmap捕获的cv::异常:

Android OpenCv Utils:nMattBitmap捕获的cv::异常:,android,opencv,camera,Android,Opencv,Camera,我已经用纵向模式创建了camera view,它工作得很好,但现在我正在尝试应用人脸检测,它在横向模式下工作,但不在纵向模式下,请检查下面的错误 E/OpenCV/StaticHelper: OpenCV error: Cannot load info library for OpenCV E/cv::error(): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src

我已经用纵向模式创建了camera view,它工作得很好,但现在我正在尝试应用人脸检测,它在横向模式下工作,但不在纵向模式下,请检查下面的错误

  E/OpenCV/StaticHelper: OpenCV error: Cannot load info library for OpenCV
  E/cv::error(): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp, line 97
  E/org.opencv.android.Utils: nMatToBitmap catched cv::Exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
  E/CameraBridge: Mat type: Mat [ 0*0*CV_8UC4, isCont=true, isSubmat=false, nativeObj=0xffffffffb80ebf00, dataAddr=0x0 ]E/CameraBridge: Bitmap type: 480*720
  E/CameraBridge: Utils.matToBitmap() throws an exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
我的Camera类如下所示,用于在纵向视图中显示相机帧

public class PortraitCameraView extends CameraBridgeViewBase implements Camera.PreviewCallback {
    private static final int MAGIC_TEXTURE_ID = 10;
    private static final String TAG = "JavaCameraView";

    private byte mBuffer[];
    private Mat[] mFrameChain;
    private int mChainIdx = 0;
    private Thread mThread;
    private boolean mStopThread;

    protected Camera mCamera;
    protected JavaCameraFrame[] mCameraFrame;
    private SurfaceTexture mSurfaceTexture;
    private int mCameraId;

    public static class JavaCameraSizeAccessor implements ListItemAccessor {

        public int getWidth(Object obj) {
            Camera.Size size = (Camera.Size) obj;
            return size.width;
        }

        public int getHeight(Object obj) {
            Camera.Size size = (Camera.Size) obj;
            return size.height;
        }
    }
    public PortraitCameraView(Context context, int cameraId) {
        super(context, cameraId);
    }

    public PortraitCameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected boolean initializeCamera(int width, int height) {
        Log.d(TAG, "Initialize java camera");
        boolean result = true;
        synchronized (this) {
            mCamera = null;

            boolean connected = false;
            int numberOfCameras = android.hardware.Camera.getNumberOfCameras();
            android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
            for (int i = 0; i < numberOfCameras; i++) {
                android.hardware.Camera.getCameraInfo(i, cameraInfo);
                if (cameraInfo.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK) {
                    try {
                        mCamera = Camera.open(i);
                        mCameraId = i;
                        connected = true;
                    } catch (RuntimeException e) {
                        Log.e(TAG, "Camera #" + i + "failed to open: " + e.getMessage());
                    }
                    if (connected) break;
                }
            }

            if (mCamera == null) return false;

        /* Now set camera parameters */
            try {
                Camera.Parameters params = mCamera.getParameters();
                Log.d(TAG, "getSupportedPreviewSizes()");
                List<Camera.Size> sizes = params.getSupportedPreviewSizes();

                if (sizes != null) {
                /* Select the size that fits surface considering maximum size allowed */
                    Size frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), height, width); //use turn around values here to get the correct prev size for portrait mode

                    params.setPreviewFormat(ImageFormat.NV21);
                    Log.d(TAG, "Set preview size to " + Integer.valueOf((int)frameSize.width) + "x" + Integer.valueOf((int)frameSize.height));
                    params.setPreviewSize((int)frameSize.width, (int)frameSize.height);

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
                        params.setRecordingHint(true);

                    List<String> FocusModes = params.getSupportedFocusModes();
                    if (FocusModes != null && FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                    {
                        params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                    }

                    mCamera.setParameters(params);
                    params = mCamera.getParameters();

                    mFrameWidth = params.getPreviewSize().height; //the frame width and height of the super class are used to generate the cached bitmap and they need to be the size of the resulting frame
                    mFrameHeight = params.getPreviewSize().width;

                    int realWidth = mFrameHeight; //the real width and height are the width and height of the frame received in onPreviewFrame
                    int realHeight = mFrameWidth;

                    if ((getLayoutParams().width == FrameLayout.LayoutParams.MATCH_PARENT) && (getLayoutParams().height == FrameLayout.LayoutParams.MATCH_PARENT))
                        mScale = Math.min(((float)height)/mFrameHeight, ((float)width)/mFrameWidth);
                    else
                        mScale = 0;

                    if (mFpsMeter != null) {
                        mFpsMeter.setResolution(mFrameWidth, mFrameHeight);
                    }

                    int size = mFrameWidth * mFrameHeight;
                    size  = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;
                    mBuffer = new byte[size];

                    mCamera.addCallbackBuffer(mBuffer);
                    mCamera.setPreviewCallbackWithBuffer(this);

                    mFrameChain = new Mat[2];
                    mFrameChain[0] = new Mat(realHeight + (realHeight/2), realWidth, CvType.CV_8UC1); //the frame chane is still in landscape
                    mFrameChain[1] = new Mat(realHeight + (realHeight/2), realWidth, CvType.CV_8UC1);

                    AllocateCache();

                    mCameraFrame = new JavaCameraFrame[2];
                    mCameraFrame[0] = new JavaCameraFrame(mFrameChain[0], mFrameWidth, mFrameHeight); //the camera frame is in portrait
                    mCameraFrame[1] = new JavaCameraFrame(mFrameChain[1], mFrameWidth, mFrameHeight);

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);
                        mCamera.setPreviewTexture(mSurfaceTexture);
                    } else
                        mCamera.setPreviewDisplay(null);

                /* Finally we are ready to start the preview */
                    Log.d(TAG, "startPreview");
                    mCamera.startPreview();
                }
                else
                    result = false;
            } catch (Exception e) {
                result = false;
                e.printStackTrace();
            }
        }

        return result;
    }

    protected void releaseCamera() {
        synchronized (this) {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.setPreviewCallback(null);

                mCamera.release();
            }
            mCamera = null;
            if (mFrameChain != null) {
                mFrameChain[0].release();
                mFrameChain[1].release();
            }
            if (mCameraFrame != null) {
                mCameraFrame[0].release();
                mCameraFrame[1].release();
            }
        }
    }

    @Override
    protected boolean connectCamera(int width, int height) {

    /* 1. We need to instantiate camera
     * 2. We need to start thread which will be getting frames
     */
    /* First step - initialize camera connection */
        Log.d(TAG, "Connecting to camera");
        if (!initializeCamera(width, height))
            return false;

    /* now we can start update thread */
        Log.d(TAG, "Starting processing thread");
        mStopThread = false;
        mThread = new Thread(new CameraWorker());
        mThread.start();

        return true;
    }

    protected void disconnectCamera() {
    /* 1. We need to stop thread which updating the frames
     * 2. Stop camera and release it
     */
        Log.d(TAG, "Disconnecting from camera");
        try {
            mStopThread = true;
            Log.d(TAG, "Notify thread");
            synchronized (this) {
                this.notify();
            }
            Log.d(TAG, "Wating for thread");
            if (mThread != null)
                mThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            mThread =  null;
        }

    /* Now release camera */
        releaseCamera();
    }

    public void onPreviewFrame(byte[] frame, Camera arg1) {
        Log.d(TAG, "Preview Frame received. Frame size: " + frame.length);
        synchronized (this) {
            mFrameChain[1 - mChainIdx].put(0, 0, frame);
            this.notify();
        }
        if (mCamera != null)
            mCamera.addCallbackBuffer(mBuffer);
    }
    private class JavaCameraFrame implements CvCameraViewFrame {
        private Mat mYuvFrameData;
        private Mat mRgba;
        private int mWidth;
        private int mHeight;
        private Mat mRotated;

        public Mat gray() {
            if (mRotated != null) mRotated.release();
            mRotated = mYuvFrameData.submat(0, mWidth, 0, mHeight); //submat with reversed width and height because its done on the landscape frame
            mRotated = mRotated.t();
            Core.flip(mRotated, mRotated, 1);
            return mRotated;
        }

        public Mat rgba() {
            Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2BGR_NV12, 4);
            if (mRotated != null) mRotated.release();
            mRotated = mRgba.t();
            Core.flip(mRotated, mRotated, 1);
            return mRotated;
        }

        public JavaCameraFrame(Mat Yuv420sp, int width, int height) {
            super();
            mWidth = width;
            mHeight = height;
            mYuvFrameData = Yuv420sp;
            mRgba = new Mat();
        }

        public void release() {
            mRgba.release();
            if (mRotated != null) mRotated.release();
        }


    };

    private class CameraWorker implements Runnable {

        public void run() {
            do {
                synchronized (PortraitCameraView.this) {
                    try {
                        PortraitCameraView.this.wait();
                    } catch (InterruptedException e) {
                        Log.e(TAG, "CameraWorker interrupted", e);
                    }
                }

                if (!mStopThread) {
                    if (!mFrameChain[mChainIdx].empty())
                        deliverAndDrawFrame(mCameraFrame[mChainIdx]);
                    mChainIdx = 1 - mChainIdx;
                }
            } while (!mStopThread);
            Log.d(TAG, "Finish processing thread");
        }
    }
}
公共类肖像CameraView扩展CameraBridgeViewBase实现Camera.PreviewCallback{
私有静态最终整型魔法纹理ID=10;
私有静态最终字符串TAG=“JavaCameraView”;
专用字节mBuffer[];
私人地毯链;
私有整数mChainIdx=0;
私有线程mThread;
私有布尔mStopThread;
受保护的摄像机mCamera;
受保护的JavaCameraFrame[]mCameraFrame;
私人表面结构;
麦卡默雷德私人酒店;
公共静态类JavaCameraSizeAccessor实现ListItemAccessor{
公共整型getWidth(对象对象对象){
Camera.Size Size=(Camera.Size)obj;
返回大小。宽度;
}
公共int getHeight(对象对象对象){
Camera.Size Size=(Camera.Size)obj;
返回大小。高度;
}
}
公共摄像机视图(上下文,int-cameraview){
超级(上下文,cameraId);
}
公共肖像摄影视图(上下文、属性集属性){
超级(上下文,attrs);
}
受保护的布尔初始值设定项(整数宽度、整数高度){
d(标记“初始化java摄像头”);
布尔结果=真;
已同步(此){
mCamera=null;
布尔连接=假;
int numberOfCameras=android.hardware.Camera.getNumberOfCameras();
android.hardware.Camera.CameraInfo-CameraInfo=新的android.hardware.Camera.CameraInfo();
对于(int i=0;i=Build.VERSION\u代码.冰淇淋\u三明治)
参数setRecordingHint(真);
List FocusModes=params.getSupportedFocusModes();
if(FocusModes!=null&&FocusModes.contains(Camera.Parameters.FOCUS\u MODE\u CONTINUOUS\u VIDEO))
{
参数设置聚焦模式(摄像机参数聚焦模式连续视频);
}
mCamera.setParameters(参数);
params=mCamera.getParameters();
mFrameWidth=params.getPreviewSize().height;//超类的帧宽度和高度用于生成缓存的位图,它们需要是结果帧的大小
mFrameHeight=params.getPreviewSize().width;
int realWidth=mFrameHeight;//实际宽度和高度是在onPreviewFrame中接收的帧的宽度和高度
int realHeight=mFrameWidth;
如果((getLayoutParams().width==FrameLayout.LayoutParams.MATCH_父项)&&(getLayoutParams().height==FrameLayout.LayoutParams.MATCH_父项))
mScale=数学最小值(((浮动)高度)/mFrameHeight、((浮动)宽度)/mFrameWidth);
其他的
mScale=0;
如果(mFpsMeter!=null){
设置分辨率(mFrameWidth、mFrameHeight);
}
int size=mFrameWidth*mFrameHeight;
size=size*ImageFormat.getBitsPerPixel(params.getPreviewFormat())/8;
mBuffer=新字节[大小];
mCamera.addCallbackBuffer(mBuffer);
mCamera.setPreviewCallbackWithBuffer(此);
mFrameChain=新材料[2];
mFrameChain[0]=新的Mat(realHeight+(realHeight/2),realWidth,CvType.CV_8UC1);//帧通道仍处于横向
mFrameChain[1]=新垫(realHeight+(realHeight/2)、realWidth、CvType.CV_8UC1);
AllocateCache();
mCameraFrame=新的JavaCameraFrame[2];
mCameraFrame[0]=新的JavaCameraFrame(mFrameChain[0],mFrameWidth,mFrameHeight);//相机帧是纵向的
mCameraFrame[1]=新的JavaCameraFrame(mFrameChain[1],mFrameWidth,mFrameHeight);
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.HONEYCOMB){
mSurfaceTexture=新的表面纹理(魔法纹理ID);
麦卡梅拉
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();

    if (mAbsoluteFaceSize == 0) {
        int height = mGray.rows();

        if (Math.round(height * mRelativeFaceSize) > 0) {
            mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
        }

        mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
    }

    MatOfRect faces = new MatOfRect();

    if (mDetectorType == JAVA_DETECTOR) {
        if (mJavaDetector != null)
            mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                    new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
    }
    else if (mDetectorType == NATIVE_DETECTOR) {
        if (mNativeDetector != null)
            mNativeDetector.detect(mGray, faces);
    }
    else {
        Log.e(TAG, "Detection method is not selected!");
    }

    Rect[] facesArray = faces.toArray();
    for (int i = 0; i < facesArray.length; i++)
        Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);

    return mRgba;
}
        android:screenOrientation="landscape"
        android:theme="@style/Theme.AppCompat.NoActionBar"