[英]Android Face detection only works with drawables not with images from SD card
所以我有代碼在任何給定的圖像文件中檢測多達10個面孔並返回給我信息,如眼睛的位置和其他類似的東西。 因此,當我告訴它使用存儲在我的項目的資源的drawable文件夾中的圖像文件時,它工作得很好。 但是,當我有它嘗試從我從SD卡導入的位圖找到面孔時,它不會找到任何面孔。 但這些都是完全相同的圖像。 有任何想法嗎? 我的代碼如下:
編輯:經過進一步檢查后,我發現當我插入這行代碼時System.out.println("Row Bytes: " + sourceImage.getRowBytes());
我得到的drawable是352和SD卡圖像是704.我認為這意味着drawable在.apk文件中被壓縮,但SD卡圖像顯然不是。 不確定這是否會影響任何事情。
public class FaceView extends View {
private static final int NUM_FACES = 10; // max is 64
private static final boolean DEBUG = true;
private FaceDetector arrayFaces;
private FaceDetector.Face getAllFaces[] = new FaceDetector.Face[NUM_FACES];
private FaceDetector.Face getFace = null;
private PointF eyesMidPts[] = new PointF[NUM_FACES];
private float eyesDistance[] = new float[NUM_FACES];
private Bitmap sourceImage;
private Paint tmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pOuterBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pInnerBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private int picWidth, picHeight;
private float xRatio, yRatio;
public FaceView(Context context) {
super(context);
pInnerBullsEye.setStyle(Paint.Style.FILL);
pInnerBullsEye.setColor(Color.RED);
pOuterBullsEye.setStyle(Paint.Style.STROKE);
pOuterBullsEye.setColor(Color.RED);
tmpPaint.setStyle(Paint.Style.STROKE);
tmpPaint.setTextAlign(Paint.Align.CENTER);
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.RGB_565;
//********This code imports the image from the SD card which does not work
String imageInSD = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/testfolder/" + "face1" + ".png";
Bitmap sourceImage = BitmapFactory.decodeFile(imageInSD,bfo);
//**********This code uses an image in the projects drawable folder, this code works.
sourceImage = BitmapFactory.decodeResource( getResources() ,R.drawable.face1, bfo);
picWidth = sourceImage.getWidth();
picHeight = sourceImage.getHeight();
arrayFaces = new FaceDetector( picWidth, picHeight, NUM_FACES );
arrayFaces.findFaces(sourceImage, getAllFaces);
for (int i = 0; i < getAllFaces.length; i++)
{
getFace = getAllFaces[i];
try {
PointF eyesMP = new PointF();
getFace.getMidPoint(eyesMP);
eyesDistance[i] = getFace.eyesDistance();
eyesMidPts[i] = eyesMP;
if (DEBUG)
{
Log.i("Face",
i + " " + getFace.confidence() + " " + getFace.eyesDistance() + " "
+ "Pose: ("+ getFace.pose(FaceDetector.Face.EULER_X) + ","
+ getFace.pose(FaceDetector.Face.EULER_Y) + ","
+ getFace.pose(FaceDetector.Face.EULER_Z) + ")"
+ "Eyes Midpoint: ("+eyesMidPts[i].x + "," + eyesMidPts[i].y +")"
);
}
}
catch (Exception e)
{
if (DEBUG) Log.e("Face", i + " is null");
}
}
}
@Override
protected void onDraw(Canvas canvas)
{
xRatio = getWidth()*1.0f / picWidth;
yRatio = getHeight()*1.0f / picHeight;
canvas.drawBitmap( sourceImage, null , new Rect(0,0,getWidth(),getHeight()),tmpPaint);
for (int i = 0; i < eyesMidPts.length; i++)
{
if (eyesMidPts[i] != null)
{
pOuterBullsEye.setStrokeWidth(eyesDistance[i] /6);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 2 , pOuterBullsEye);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 6 , pInnerBullsEye);
}
}
}
}
好吧,我相信我知道你的問題在這里。 設備無法將圖像渲染為位圖圖像,因為它位於外部存儲器中。 面部識別工作只是沒有進入畫布。 我的xoom所有設備都有渲染限制(2048x2048)我在這里找到了 。 將圖像作為資源添加時它起作用的原因是因為你的文件縮小了,因為它構建了.apk(說實話我不知道為什么會這樣做,但是我留下了一些println用於測試,其他人可以更好地回答這個問題。 無論如何,我只是在你的代碼尋找面之后,在它嘗試將位圖渲染到畫布之前,除以2來縮放位圖。 現在一切似乎都很好。 您可能需要調整面部指示器但功能正常。 我希望這有幫助。
public class FaceView extends View {
private static final int NUM_FACES = 1; // max is 64
private static final boolean DEBUG = true;
private FaceDetector arrayFaces;
private FaceDetector.Face getAllFaces[] = new FaceDetector.Face[NUM_FACES];
private FaceDetector.Face getFace = null;
private PointF eyesMidPts[] = new PointF[NUM_FACES];
private float eyesDistance[] = new float[NUM_FACES];
private Bitmap sourceImage;
private Paint tmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pOuterBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pInnerBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private int picWidth, picHeight;
private float xRatio, yRatio;
public FaceView(Context context) {
super(context);
pInnerBullsEye.setStyle(Paint.Style.FILL);
pInnerBullsEye.setColor(Color.RED);
pOuterBullsEye.setStyle(Paint.Style.STROKE);
pOuterBullsEye.setColor(Color.RED);
tmpPaint.setStyle(Paint.Style.STROKE);
tmpPaint.setTextAlign(Paint.Align.CENTER);
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.RGB_565;
//********This code imports the image from the SD card which does not work
String imageInSD = Environment.getExternalStorageDirectory().getAbsolutePath() + "/face1" + ".jpg";
System.out.println(imageInSD);
sourceImage = BitmapFactory.decodeFile(imageInSD, bfo);
//Bitmap sourceImage;// = BitmapFactory.decodeFile(imageInSD,bfo);
//**********This code uses an image in the projects drawable folder, this code works.
//sourceImage = BitmapFactory.decodeResource( getResources() ,R.drawable.face1, bfo);
picWidth = sourceImage.getWidth();
picHeight = sourceImage.getHeight();
System.out.println(picWidth + "x" + picHeight);
arrayFaces = new FaceDetector( picWidth, picHeight, NUM_FACES );
arrayFaces.findFaces(sourceImage, getAllFaces);
sourceImage = Bitmap.createScaledBitmap (sourceImage, picWidth/2, picHeight/2, false);
for (int i = 0; i < getAllFaces.length; i++)
{
getFace = getAllFaces[i];
try {
PointF eyesMP = new PointF();
getFace.getMidPoint(eyesMP);
eyesDistance[i] = getFace.eyesDistance();
eyesMidPts[i] = eyesMP;
if (DEBUG)
{
Log.i("Face",
i + " " + getFace.confidence() + " " + getFace.eyesDistance() + " "
+ "Pose: ("+ getFace.pose(FaceDetector.Face.EULER_X) + ","
+ getFace.pose(FaceDetector.Face.EULER_Y) + ","
+ getFace.pose(FaceDetector.Face.EULER_Z) + ")"
+ "Eyes Midpoint: ("+eyesMidPts[i].x + "," + eyesMidPts[i].y +")"
);
}
}
catch (Exception e)
{
if (DEBUG) Log.e("Face", i + " is null");
}
}
}
@Override
protected void onDraw(Canvas canvas)
{
xRatio = getWidth()*1.0f / picWidth;
yRatio = getHeight()*1.0f / picHeight;
canvas.drawBitmap( sourceImage, null , new Rect(0,0,getWidth(),getHeight()),tmpPaint);
for (int i = 0; i < eyesMidPts.length; i++)
{
if (eyesMidPts[i] != null)
{
pOuterBullsEye.setStrokeWidth(eyesDistance[i] /6);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 2 , pOuterBullsEye);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 6 , pInnerBullsEye);
}
}
}
}
事實證明,相機拍攝的照片會保存為PNG文件,只有在使用JPG文件時才可以從SD卡成功進行人臉檢測。 只需將文件轉換為JPG,它就可以正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.