为什么在Android中使用javaCV cvHaarDetectObjects方法在Portrait模式下不会发生facedetection

时间:2013-10-05 12:16:00

标签: android javacv

我尝试修改为Android提供的FacePreview.java示例,因为该代码始终以横向模式打开相机,所以在我打开相机后,我在Preview.java添加了定位逻辑:

mCamera.setDisplayOrientation(90);

当我运行程序时,我发现始终是对象检测,即cvHaarDetectObjects仅在手机处于横向模式时才有效,在其他模式下主要是纵向,它根本不会检测任何面部。 这背后的原因是什么?

faces = cvHaarDetectObjects(
    grayImage,
    classifier,
    storage,
    1.1,
    3,
    CV_HAAR_FEATURE_MAX
      | CV_HAAR_SCALE_IMAGE 
      | CV_HAAR_FIND_BIGGEST_OBJECT
      | CV_HAAR_DO_ROUGH_SEARCH
      | CV_HAAR_DO_CANNY_PRUNING);
当手机处于纵向模式或方向与风景不同时,

faces.total始终返回0

我尝试修改地点但没找到预期的地方。

1 个答案:

答案 0 :(得分:0)

似乎在OpenCV / JavaCV中,哈尔分类器(xml文件)是使用风景图像进行训练的。您可以在面部检测之前旋转Mat对象:

public static opencv_core.Mat rotate(opencv_core.Mat src, int angle) {
    opencv_core.IplImage iplSrc = src.asIplImage();
    opencv_core.IplImage iplRes = opencv_core.IplImage.create(
        iplSrc.height(),
        iplSrc.width(),
        iplSrc.depth(),
        iplSrc.nChannels()
    );
    cvTranspose(iplSrc, iplRes);
    cvFlip(iplRes, iplRes, angle);
    return new opencv_core.Mat(iplRes);

因此,如果您从某个图像文件加载Mat,您可以执行以下操作:

opencv_core.Mat mat = imread(imagePath, CV_LOAD_IMAGE_GRAYSCALE);
int orientation = ExifInterface.ORIENTATION_UNDEFINED;
try {
     ExifInterface exif = new ExifInterface(imagePath);
     orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
} catch (IOException e) {
     e.printStackTrace();
}
switch (orientation) {
    case ExifInterface.ORIENTATION_ROTATE_90:
       mat = MatUtils.rotate(mat, 90);
       break;
}