【问题标题】:Rotate VideoCapture in OpenCV on Android在 Android 上的 OpenCV 中旋转 VideoCapture
【发布时间】:2012-10-08 14:59:12
【问题描述】:

在 OpenCV 上使用 VideoCapture 类时如何旋转相机? (Android 上的人脸检测示例)。 我正在旋转画布:

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
    Matrix matrix = new Matrix();
    matrix.preTranslate(
    (canvas.getWidth() - bmp.getWidth()) / 2,
    (canvas.getHeight() - bmp.getHeight()) / 2);
    matrix.postRotate(270f, (canvas.getWidth()) / 2,
    (canvas.getHeight()) / 2);
    canvas.drawBitmap(bmp, matrix, null);
}

但来自相机的图像不旋转:人脸检测不起作用。

相机从以下接收流:

protected Bitmap processFrame(VideoCapture capture) {

    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

    capture.retrieve(mGray,
    Highgui.CV_CAP_ANDROID_GREY_FRAME);

更新 我做了以下事情:

@Override
    protected Bitmap processFrame(VideoCapture capture) {

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        Core.flip(mRgba.t(), mRgba, 0);
    }

    else {
    }
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    capture.retrieve(mDetect_thread.mGray,
            Highgui.CV_CAP_ANDROID_GREY_FRAME);

但是不工作。当我以 portret 方向(在 android 设备上)运行程序时 - 程序不启动当我以横向方向运行 rogram 时 - 程序工作,但是当我旋转设备时,程序工作,但显示的图像不旋转

【问题讨论】:

    标签: java android opencv video-capture


    【解决方案1】:

    您的问题主要是duplicate of this,只是您正在寻找Android版本。它非常相似,但在这里,可以通过转置然后翻转图像来获得 90º 旋转:

    # rotate 90º counter-clockwise
    Core.flip(mRgba.t(), mRgba, 0); //mRgba.t() is the transpose
    
    # rotate 90º clockwise
    Core.flip(mRgba.t(), mRgba, 1);
    

    对于其他轮换,您可以使用warpAffine

    Point center = new Point(x,y);
    double angle = 90;
    double scale = 1.0;
    
    Mat mapMatrix = Imgproc.getRotationMatrix2D(center, angle, scale);
    Imgproc.warpAffine(srcMat, dstMat, mapMatrix, Imgproc.INTER_LINEAR);
    

    编辑 - 更完整的示例如下:

        /** 
         * Image is first resized-to-fit the dst Mat and then rotated. 
         * mRgba is the source image, mIntermediateMat should have the same type.
         */
        private void rotationTutorial(){
            double ratio =  mRgba.height() / (double) mRgba.width();
    
            int rotatedHeight = mRgba.height();     
            int rotatedWidth  = (int) Math.round(mRgba.height() * ratio);
    
            Imgproc.resize(mRgba, mIntermediateMat, new Size(rotatedHeight, rotatedWidth));
    
            Core.flip(mIntermediateMat.t(), mIntermediateMat, 0);
    
            Mat ROI = mRgba.submat(0, mIntermediateMat.rows(), 0, mIntermediateMat.cols());
    
            mIntermediateMat.copyTo(ROI);       
        }
    
    
        /** 
         * Image is rotated - cropped-to-fit dst Mat.
         * 
         */
        private void rotationAffineTutorial(){
            // assuming source image's with and height are a pair value:
            int centerX = Math.round(mRgba.width()/2);
            int centerY = Math.round(mRgba.height()/2);
    
            Point center = new Point(centerY,centerX);
            double angle = 90;
            double scale = 1.0;
    
            double ratio =  mRgba.height() / (double) mRgba.width();
    
            int rotatedHeight = (int) Math.round(mRgba.height());       
            int rotatedWidth  = (int) Math.round(mRgba.height() * ratio);
    
            Mat mapMatrix = Imgproc.getRotationMatrix2D(center, angle, scale);
    
            Size rotatedSize = new Size(rotatedWidth, rotatedHeight);
            mIntermediateMat = new Mat(rotatedSize, mRgba.type());
    
            Imgproc.warpAffine(mRgba, mIntermediateMat, mapMatrix, mIntermediateMat.size(), Imgproc.INTER_LINEAR);
    
            Mat ROI = mRgba.submat(0, mIntermediateMat.rows(), 0, mIntermediateMat.cols());
    
            mIntermediateMat.copyTo(ROI);
        }
    

    注意:

    • 这些示例可能是特定方向的,我将它们用于横向。
    • 您不应为每个视频帧调用这些示例中的代码。有些代码应该只运行一次。

    【讨论】:

    • 当然可以。人脸识别无法通过旋转图像开箱即用。
    • @gregm 我已经修复了原始帖子的一些错别字,并提供了一些更完整的示例。如果您之前没有设法让它工作,您可能无法正确输出结果图像。这些示例展示了如何输出它(但可以提高效率)。
    • @RuiMarques 你好。 FeatureDetector 现在偏离了 90 度。我该如何解决?
    【解决方案2】:

    如果您只需要进行 90、180 或 270 度旋转(这似乎是您的情况),您最好使用更快的 Core.flip()。 下面是一个为你做的方法:

    public static Mat rotate(Mat src, double angle)
    {
        Mat dst = new Mat();
        if(angle == 180 || angle == -180) {
            Core.flip(src, dst, -1);
        } else if(angle == 90 || angle == -270) {
            Core.flip(src.t(), dst, 1);
        } else if(angle == 270 || angle == -90) {
            Core.flip(src.t(), dst, 0);
        }
    
        return dst;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多