2013-10-10 3 views
0

Недавно я изучаю OpenCV.Как определить режим лица по портрету?

Пробный код OpenCV для Android (2.4.6).

У меня есть некоторые удивления.

Я могу определить лицо по образцу кода (образец OpenCV - обнаружение лица). но не может обнаружить режим лица по портрету (вертикальный режим) на устройстве Android.

Во-первых, я пытаюсь установить фронтальную камеру по портретному режиму.

// добавлен код в onCameraFrame().

Core.flip (mRgba, mRgba, 1);

Еще не распознал лицо.

Как определить режим лица по портрету?

спасибо.

ответ

0

вам нужно сделать транспонирование, а затем переверните:

  int height = mGray.rows(); 
      int faceSize = Math.round(height * 0.5F); 

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

      MatOfRect rectFaces = new MatOfRect(); 

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

Установите портретный режим в манифесте андроида первым.

android:screenOrientation="portrait" 

Флип цветной и серое изображение (Мат) по часовой стрелке для обнаружения лица/признака для работы в портретном режиме. В конце обнаружения функции Logic вы переворачиваете против часовой стрелки цветное изображение (mRgba Mat). Как показано на рисунке.

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) 
{ 
    int height = Gray.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(Gray, faces, 1.1, 2, 2, 
    new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size()); 
} 
else if (mDetectorType == NATIVE_DETECTOR) 
{ 
if (mNativeDetector != null) 
    mNativeDetector.detect(Gray, faces); 
} 
else 
{ 
Log.e(TAG, "Detection method is not selected!"); 
} 


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

После того, что камера будет показывать обнаружение лица в альбомной ориентации, чтобы это исправить, повернуть холст по часовой стрелке на 90 в CameraBridgeViewBase основного класса OpenCV или взломать его. (Обратите внимание, это уменьшает FPS, но обнаружение лица по-прежнему быстро)

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

boolean bmpValid = 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) { 
Canvas canvas = 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) 
{ 
final CountDownLatch latch =new CountDownLatch(1); 
final Mat[] mRgba=new Mat[1]; 

new Thread(new Runnable() { 
@Override 
public void run() { 

try { 
Bitmap bitmap = Bitmap.createScaledBitmap(mCacheBitmap, canvas.getHeight(), canvas.getWidth(), true); 
canvas.rotate(90,0,0); 
mScale = canvas.getWidth()/(float)bitmap.getHeight(); 
float scale2 = 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; 

}

(используя OpenCV 2.4.9)