CvException warpAffine旋转帧

时间:2013-06-16 09:52:17

标签: android opencv rotation video-streaming

大家早上好。 我正在开发一个Android应用程序。 我在logcat中收到此异常:

 06-16 11:42:41.726: WARN/dalvikvm(11429): threadid=13: thread exiting with uncaught exception (group=0x40e61ac8)
 06-16 11:42:41.726: ERROR/AndroidRuntime(11429): FATAL EXCEPTION: Thread-2473
    CvException [org.opencv.core.CvException: /home/reports/ci/slave/50-SDK/opencv/modules/imgproc/src/imgwarp.cpp:3272: error: (-215) src.cols > 0 && src.rows > 0 in function void cv::warpAffine(cv::InputArray, cv::OutputArray, cv::InputArray, cv::Size, int, int, const Scalar&)
    ]
    at org.opencv.imgproc.Imgproc.warpAffine_2(Native Method)
    at org.opencv.imgproc.Imgproc.warpAffine(Imgproc.java:9114)
    at com.micaela.myapp.MainActivity.manageRotation(MainActivity.java:416)
    at com.micaela.myapp.MainActivity.chooseMode(MainActivity.java:374)
    at com.micaela.myapp.MainActivity.onCameraFrame(MainActivity.java:344)
    at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:381)
    at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:323)
    at java.lang.Thread.run(Thread.java:856)

我的应用程序使用JavaCameraView对象打开视频流,并从中捕获帧,然后在屏幕上显示它们之前,它们会根据设备的方向正确旋转。为此,我在2.4.5版本中使用了OpenCv4Android库的warpAffine函数。

我调用此函数的方法是:

public void manageRotation(Mat matrix, Display display) {

    int screenOrientation = display.getRotation();

    Point center =new Point(matrix.cols()/2,matrix.rows()/2);
    int angle = 0; //default
    double scale = 1.0;

    Mat rotImage;

    switch (screenOrientation){
        default:
        case ORIENTATION_0: // Portrait
            if (mOpenCvCameraView.getCameraId() == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                angle=90;
                rotImage = Imgproc.getRotationMatrix2D(center, angle, scale);
                Imgproc.warpAffine(matrix, matrix, rotImage, matrix.size());
            } else{
                angle=-90;
                rotImage = Imgproc.getRotationMatrix2D(center, angle, scale);
                Imgproc.warpAffine(matrix, matrix, rotImage, matrix.size());
            }
            break;
        case ORIENTATION_90: // Landscape right
            angle = 180;
            rotImage = Imgproc.getRotationMatrix2D(center, angle, scale);
            Imgproc.warpAffine(matrix, matrix, rotImage, matrix.size());
            break;
        case ORIENTATION_180:  //Reverse portrait
            angle = 270;
            rotImage = Imgproc.getRotationMatrix2D(center, angle, scale);
            Imgproc.warpAffine(matrix, matrix, rotImage, matrix.size());
            break;
        case ORIENTATION_270: // Landscape left
            break;
    }

}

我在OnCameraFrame中调用此方法,捕获帧后,将其作为参数传递。 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

要记住关于OpenCV错误的重要一点是它们与它们的含义相反,因为它们代表了失败的断言。所以错误

src.cols > 0 && src.rows > 0

实际上意味着源矩阵的一个或两个维度为0.这可能意味着您的Mat matrix有0行和0列。由于您将其传递给函数,因此您的问题不在您发布的代码中。

此外,warpAffine非常慢,并且对于90度的倍数的旋转来说是不必要的。改为使用翻转和换位,例如

if (rot == 270) {
    // Rotate clockwise 270 degrees
    Core.flip(mat.t(), mat, 0);
} else if (rot == 180) {
    // Rotate clockwise 180 degrees
    Core.flip(mat, mat, -1);
} else if (rot == 90) {
    // Rotate clockwise 90 degrees
    Core.flip(mat.t(), mat, 1);
}