Skip to content Skip to sidebar Skip to footer

How To Detect Face By Portrait Mode?

I'm studying OpenCV recently. OpenCV for Android sample code(2.4.6) is tested. I have some wonder. I can detect face by sample code(OpenCV Sample - face-detection). but, can't dete

Solution 1:

you need to do transpose and then flip:

intheight= mGray.rows();
            intfaceSize= Math.round(height * 0.5F);

            Mattemp= mGray.clone();
            Core.transpose(mGray, temp);
            Core.flip(temp, temp, -1);

            MatOfRectrectFaces=newMatOfRect();

            // java detector fast
            mCascade.detectMultiScale(temp, rectFaces, 1.1, 1, 0, newSize(faceSize, faceSize), newSize());

Solution 2:

Set the portrait mode in android's manifest first.

 android:screenOrientation="portrait"

Flip the colored and gray image(Mat) clockwise for face/feature detection to work in portrait mode. At the end of feature detection Logic, you flip counter clockwise the colored image(mRgba Mat) . As illustrated.

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

    Core.flip(inputFrame.gray().t(),mGray,1); //rotate clockwise 
    Core.flip(inputFrame.rgba().t(),mRgba,1);
    mRgba=Feature_DetectionNATIVE(mRgba,mGray);
    Core.flip(mRgba.t(),mRgba,0);             //rotate counter clockwise//this is a solution for  allowing face detection in portrait view if it isn't working at all.return mRgba;
 }
public Mat Feature_DetectionNATIVE(Mat mRgba2, final Mat Gray)
{
if (mAbsoluteFaceSize == 0) 
{
    intheight= Gray.rows();
    if (Math.round(height * mRelativeFaceSize) > 0)
     {
       mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);

     }
 mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);

}

MatOfRectfaces=newMatOfRect();

if (mDetectorType == JAVA_DETECTOR) 
 {
if (mJavaDetector != null)
  mJavaDetector.detectMultiScale(Gray, faces, 1.1, 2, 2, 
  newSize(mAbsoluteFaceSize, mAbsoluteFaceSize), newSize());
 }
elseif (mDetectorType == NATIVE_DETECTOR)
{
if (mNativeDetector != null)
  mNativeDetector.detect(Gray, faces);
 }
else 
{
Log.e(TAG, "Detection method is not selected!");
}


Rect[] facesArray = faces.toArray();
for (inti=0; i < facesArray.length; i++)
{
  Core.rectangle(mRgba2, facesArray[i].tl(), facesArray[i].br(),     FACE_RECT_COLOR, 3);
}
    return mRgba2;
}

After that the camera will show face detection in landscape orientation to fix this you rotate the canvas clockwise by 90 in opencv's CameraBridgeViewBase main class or hack it.(Note this reduces FPS but face detection is still fast)

protectedvoiddeliverAndDrawFrame(CvCameraViewFrame frame) {
 Mat modified;
 if (mListener != null) {
 modified = mListener.onCameraFrame(frame);
 } else {
  modified = frame.rgba();
 }

 booleanbmpValid=true;
 if (modified != null) {
 try {
  Utils.matToBitmap(modified, mCacheBitmap);

  } catch(Exception e) {
 Log.e(TAG, "Mat type: " + modified);
 Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" +   mCacheBitmap.getHeight());
 Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
 bmpValid = false;
  }
 }

 if (bmpValid && mCacheBitmap != null) {
 Canvascanvas= getHolder().lockCanvas();
  if (canvas != null) {
 canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
 Log.d(TAG, "mStretch value: " + mScale);
 canvas=rotateCanvas(canvas,mCacheBitmap);
 getHolder().unlockCanvasAndPost(canvas);
 }    } }

 protected Canvas rotateCanvas(final Canvas canvas, final Bitmap mCacheBitmap)
 { 
 finalCountDownLatchlatch=newCountDownLatch(1);
 final Mat[] mRgba=newMat[1];

 newThread(newRunnable() {
 @Overridepublicvoidrun() {

 try {
 Bitmapbitmap= Bitmap.createScaledBitmap(mCacheBitmap, canvas.getHeight(),  canvas.getWidth(), true);
canvas.rotate(90,0,0);
mScale = canvas.getWidth() / (float)bitmap.getHeight();
floatscale2= canvas.getHeight() / (float)bitmap.getWidth();
if(scale2 > mScale){
    mScale = scale2;
 }
if (mScale != 0) {
 canvas.scale(mScale, mScale,0,0);
 }
canvas.drawBitmap(bitmap, 0, -bitmap.getHeight(), null);

}
catch (CvException e) {           e.printStackTrace();}
latch.countDown();//setting //release await() in this thread
}

}).start();

try {  latch.await(); //waits for countDown in the Thread inorder to obtain a value from the thread

} catch (InterruptedException e) {   e.printStackTrace();}

return canvas;

}

(Using OpenCV 2.4.9)

Post a Comment for "How To Detect Face By Portrait Mode?"