在android中使用人脸检测裁剪图像
Posted
技术标签:
【中文标题】在android中使用人脸检测裁剪图像【英文标题】:Crop Image with face detection in android 【发布时间】:2014-04-28 10:09:06 【问题描述】:我需要一个可以使用人脸检测功能裁剪任何图像的演示。
已修复
但是经过几个小时的冲浪后,我一个演示都没有,所以我准备了一个演示,结合了我在网上找到的几个演示。
我已经准备了一个演示来裁剪图像。
我的演示裁剪了图像矩形和圆形。
它还检测人脸并根据人脸检测裁剪图像。
我正在使用下面的图片来裁剪它。
裁剪结果的截图是:
示例的xml是:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity" >
<View
android:id="@+id/part1"
android:layout_
android:layout_ >
</View>
<View
android:id="@+id/part2"
android:layout_
android:layout_
android:layout_marginTop="30dp" >
</View>
</LinearLayout>
Activity的java代码:
public class MainActivity extends Activity
public View part1, part2;
int viewHeight, viewWidth;
private FaceDetector myFaceDetect;
private FaceDetector.Face[] myFace;
float myEyesDistance;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
part1 = findViewById(R.id.part1);
part2 = findViewById(R.id.part2);
part1.post(new Runnable()
@Override
public void run()
// TODO Auto-generated method stub
viewHeight = part1.getMeasuredHeight();
viewWidth = part1.getMeasuredWidth();
try
Paint paint = new Paint();
paint.setFilterBitmap(true);
Bitmap bitmapOrg = BitmapFactory.decodeResource(
getResources(),
R.drawable.sachin_tendulkar_10102013);
int targetWidth = bitmapOrg.getWidth();
int targetHeight = bitmapOrg.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight, Bitmap.Config.ARGB_8888);
RectF rectf = new RectF(0, 0, viewWidth, viewHeight);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addRect(rectf, Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(
bitmapOrg,
new Rect(0, 0, bitmapOrg.getWidth(), bitmapOrg
.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), paint);
Matrix matrix = new Matrix();
matrix.postScale(1f, 1f);
BitmapFactory.Options bitmapFatoryOptions = new BitmapFactory.Options();
bitmapFatoryOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.sachin_tendulkar_10102013,
bitmapFatoryOptions);
myFace = new FaceDetector.Face[5];
myFaceDetect = new FaceDetector(targetWidth, targetHeight,
5);
int numberOfFaceDetected = myFaceDetect.findFaces(
bitmapOrg, myFace);
Bitmap resizedBitmap = null;
if (numberOfFaceDetected > 0)
PointF myMidPoint = null;
Face face = myFace[0];
myMidPoint = new PointF();
face.getMidPoint(myMidPoint);
myEyesDistance = face.eyesDistance();
if (myMidPoint.x + viewWidth > targetWidth)
while (myMidPoint.x + viewWidth > targetWidth)
myMidPoint.x--;
if (myMidPoint.y + viewHeight > targetHeight)
while (myMidPoint.y + viewHeight > targetHeight)
myMidPoint.y--;
resizedBitmap = Bitmap.createBitmap(bitmapOrg,
(int) (myMidPoint.x - myEyesDistance),
(int) (myMidPoint.y - myEyesDistance),
viewWidth, viewHeight, matrix, true);
else
resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
viewWidth, viewHeight, matrix, true);
/* convert Bitmap to resource */
// Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap,
// 0,
// 0, viewWidth, viewHeight, matrix, true);
BitmapDrawable bd = new BitmapDrawable(resizedBitmap);
part1.setBackgroundDrawable(bd);
catch (Exception e)
System.out.println("Error1 : " + e.getMessage()
+ e.toString());
);
part2.post(new Runnable()
@Override
public void run()
// TODO Auto-generated method stub
viewHeight = part2.getMeasuredHeight();
viewWidth = part2.getMeasuredWidth();
try
Paint paint = new Paint();
paint.setFilterBitmap(true);
Bitmap bitmapOrg = BitmapFactory.decodeResource(
getResources(),
R.drawable.sachin_tendulkar_10102013);
int targetWidth = bitmapOrg.getWidth();
int targetHeight = bitmapOrg.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight, Bitmap.Config.ARGB_8888);
RectF rectf = new RectF(0, 0, viewWidth, viewHeight);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addRect(rectf, Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(
bitmapOrg,
new Rect(0, 0, bitmapOrg.getWidth(), bitmapOrg
.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), paint);
Matrix matrix = new Matrix();
matrix.postScale(1f, 1f);
BitmapFactory.Options bitmapFatoryOptions = new BitmapFactory.Options();
bitmapFatoryOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.sachin_tendulkar_10102013,
bitmapFatoryOptions);
myFace = new FaceDetector.Face[5];
myFaceDetect = new FaceDetector(targetWidth, targetHeight,
5);
int numberOfFaceDetected = myFaceDetect.findFaces(
bitmapOrg, myFace);
Bitmap resizedBitmap = null;
if (numberOfFaceDetected > 0)
PointF myMidPoint = null;
Face face = myFace[0];
myMidPoint = new PointF();
face.getMidPoint(myMidPoint);
myEyesDistance = face.eyesDistance() + 20;
if (myMidPoint.x + viewWidth > targetWidth)
while (myMidPoint.x + viewWidth > targetWidth)
myMidPoint.x--;
if (myMidPoint.y + viewHeight > targetHeight)
while (myMidPoint.y + viewHeight > targetHeight)
myMidPoint.y--;
resizedBitmap = Bitmap.createBitmap(bitmapOrg,
(int) (myMidPoint.x - myEyesDistance),
(int) (myMidPoint.y - myEyesDistance),
viewWidth, viewHeight, matrix, true);
else
resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
viewWidth, viewHeight, matrix, true);
/* convert Bitmap to resource */
// Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap,
// 0,
// 0, viewWidth, viewHeight, matrix, true);
BitmapDrawable bd = new BitmapDrawable(resizedBitmap);
part2.setBackgroundDrawable(new BitmapDrawable(
getCroppedBitmap(bd.getBitmap())));
catch (Exception e)
System.out.println("Error1 : " + e.getMessage()
+ e.toString());
);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
public Bitmap getCroppedBitmap(Bitmap bitmap)
// Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
// bitmap.getHeight(), Config.ARGB_8888);
// Canvas canvas = new Canvas(output);
//
// final int color = 0xff424242;
// final Paint paint = new Paint();
// final Rect rect = new Rect(0, 0, bitmap.getWidth(),
// bitmap.getHeight());
//
// paint.setAntiAlias(true);
// canvas.drawARGB(0, 0, 0, 0);
// paint.setColor(color);
// // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
// bitmap.getWidth() / 2, paint);
// paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
// canvas.drawBitmap(bitmap, rect, rect, paint);
// // Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
// // return _bmp;
// return output;
int targetWidth = bitmap.getWidth();
int targetHeight = bitmap.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = bitmap;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), null);
return targetBitmap;
【问题讨论】:
现在有什么问题? 我的问题现在已经解决了,但是上传了代码以防有人想要它,thnx.. 它可以在任何图像中使用吗? 是的,它是..您只需像我一样将图像放在任何可绘制的文件夹中..如果您想从图库中裁剪任何图像,只需为该图像制作一个名为 bitmapOrg 的位图..并继续演示.. 它不适用于所有图像 【参考方案1】:该演示适用于放置在可绘制文件夹中的任何图像,
但是,如果您想裁剪任何动态图像,例如从图库中下载或选择的任何图像,只需对代码进行一些更改:
看线:
Bitmap bitmapOrg = BitmapFactory.decodeResource(
getResources(),
R.drawable.sachin_tendulkar_10102013);
这里我从 drawable 文件夹中获取图像,现在对于任何下载的图像,您只需将该图像保存在 bitmapOrg 变量中,因此只需将上述行更改两次,part1 用于矩形,part2 用于 ciculart您下载的图像作为位图保存到 bitmapOrg,并使用演示,它将以矩形和圆形方式裁剪您的图像。
【讨论】:
我用过这个,但它并不是在每张图像中都给出 100% 的结果。如果你在分类中使用了新的谷歌视觉 API,那么它会给你 100%。以上是关于在android中使用人脸检测裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章