Android OpenCv Utils:nMattBitmap捕获的cv::异常:
我已经用纵向模式创建了camera view,它工作得很好,但现在我正在尝试应用人脸检测,它在横向模式下工作,但不在纵向模式下,请检查下面的错误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
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"