2012-10-18 38 views
9

如何在OpenCV上使用類VideoCapture時旋轉攝像頭? (Android上的樣本臉部檢測)。在Android上的OpenCV中旋轉視頻捕捉

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); 

UPDATE 我做了以下內容:

@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設備上) - 程序不啓動當我以橫向方向運行程序 - 程序工作,但是當我旋轉設備時,程序工作,但顯示圖像不旋轉

回答

9

您的問題主要是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); 
    } 

說明:

  • 這些例子可能是針對具體方向的,我將它們設計爲橫向。
  • 您不應該爲每個視頻幀調用這些示例中的代碼。一些代碼只能運行一次。
+0

偏離它的工作原理。這是人臉識別,不能與旋轉圖像一起使用。 –

+0

這不起作用 – gregm

+0

您能否詳細說明一下? –

0

如果你只需要做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; 
}