Просмотр изображений и распознавание лиц.
У меня возникли некоторые проблемы с обнаружением лиц просматриваемого изображения. Я знаю, что проблема в том, что я не знаю, как применить код распознавания лиц, который я тестирую на импортированном изображении. Пример кода, который я тестирую, был написан для образа, хранящегося локально. Я думаю, что я близок, но вы можете мне помочь?
Сначала я создал метод галереи
protected void gallery() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction("android.intent.action.GET_CONTENT");
startActivityForResult(Intent.createChooser(intent, "Choose An Image"), 1);
}
Я все еще изучаю намерения и тому подобное, но, насколько я понимаю, мне нужно было использовать намерение, чтобы использовать галерею Android, и поскольку я устанавливаю действие для получения контента, я также использую намерение для передачи ему информации. Сказав это, я попытался затем передать информацию в намерении Ури. Вот что я сделал дальше.
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == 1 && resultCode == RESULT_OK)
{
Uri uri = intent.getData();
try {
InputStream is = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView image = (ImageView)findViewById(R.id.img_view);
image.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Итак, вот что меня смущает. Я полагаю, InputStream имеет информацию об изображении? Ну, я попытался применить код распознавания лиц внутри этого же try-catch. Я так и понял после изображения.setImageBitmap (bitmap) завершен, то есть настало время применить распознавание лиц. Вот это лицо код обнаружения.
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == 1 && resultCode == RESULT_OK)
{
Uri uri = intent.getData();
try {
InputStream is = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView image = (ImageView)findViewById(R.id.image_view);
image.setImageBitmap(bitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig=Bitmap.Config.RGB_565;
bitmap = BitmapFactory.decodeResource(getResources(), R.id.img_view, options);
imageWidth = bitmap.getWidth();
imageHeight = bitmap.getHeight();
detectedFaces = new FaceDetector.Face[NUM_FACES];
faceDetector= new FaceDetector(imageWidth, imageHeight, NUM_FACES);
NUM_FACE_DETECTED = faceDetector.findFaces(bitmap, detectedFaces);
mIL.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Я не знаю, как изменить " mFaceBitmap = BitmapFactory.decodeResource (getResources (), R. drawable.smilingfaces, options); " что для локальных изображений, к изображению, которое, как я думаю, хранится внутри входного потока (или это так? Где находится выбранное изображение?) Я придумал вместо этого сделать макет imageView, так как изображение находится в макете. Я не понимаю, как это все переносится и работает вместе. В любом случае, этот фрагмент кода должен обнаруживать лица. А затем onDraw () рисует квадраты вокруг обнаруженных граней. Я не знаю, куда его поместить, но я поместил его вне onActivityResult ()
protected void onDraw(Canvas canvas) {
Paint myPaint = new Paint();
myPaint.setColor(Color.RED);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
myPaint.setDither(true);
for (int count = 0; count < NUM_FACE_DETECTED; count++) {
Face face = detectedFaces[count];
PointF midPoint = new PointF();
face.getMidPoint(midPoint);
eyeDistance = face.eyesDistance();
canvas.drawRect(midPoint.x-eyeDistance, midPoint.y-eyeDistance, midPoint.x+eyeDistance, midPoint.y+eyeDistance, myPaint);
}
}
Какой-нибудь совет? Я очень близок к тому, чтобы заставить это работать!
1 ответ:
Я понял, чего ты на самом деле хочешь. Я напишу вам полный код и просто продолжу.
В этом коде я беру imageview в макете, и два класса, один класс активности и другой класс imageview.
Я создам две кнопки, где одна кнопка используется для выбора изображения из галереи и отображения его ( для распознавания лиц), а вторая кнопка-для обнаружения лиц на выбранном изображении.
Во-первых, mainlayout.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.simpleapps.facedetection.MyView android:id="@+id/faceview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="top"> <ImageView android:id="@+id/gallery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:layout_weight="1" android:background="@drawable/gallery" /> <ImageView android:id="@+id/detectf" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:layout_weight="1" android:background="@drawable/detect" /> </LinearLayout> </FrameLayout>
Теперь активность класс
Основная активность.java
public class MainActivity extends Activity { public MyView faceview; public static Bitmap defaultBitmap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.activity_main); DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); screenHeight = displaymetrics.heightPixels; screenWidth = displaymetrics.widthPixels; faceview = (MyView)findViewById(R.id.faceview); myGallery = (LinearLayout)findViewById(R.id.mygallery); gallery=(ImageView)findViewById(R.id.gallery); detectf=(ImageView)findViewById(R.id.detectf); BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options(); bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565; defaultBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.face,bitmapFatoryOptions); faceview.setImage(defaultBitmap); gallery.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, 0 ); } }); detectf.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub faceview.facedetect(); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if(requestCode==0){ imageURI = data.getData(); try { BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options(); bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565; Bitmap b = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageURI), null, bitmapFatoryOptions); faceview.myBitmap=b; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } faceview.invalidate(); } faceview.invalidate(); } else { System.exit(0); Log.e("result", "BAD"); } } }
Теперь класс view.
Мой взгляд.java
public class MyView extends View { private FaceDetector.Face[] detectedFaces; private int NUMBER_OF_FACES=10; private FaceDetector faceDetector; private int NUMBER_OF_FACE_DETECTED; private float eyeDistance; public Paint myPaint; public Bitmap resultBmp; public Bitmap myBitmap,HairBitmap; public PointF midPoint1; public MyView(Context context, AttributeSet attrs) { super(context,attrs); // TODO Auto-generated constructor stub BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options(); bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565; } public void setImage(Bitmap bitmap) { myBitmap = bitmap; invalidate(); } public void facedetect(){ myPaint = new Paint(); myPaint.setColor(Color.GREEN); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeWidth(3); detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES]; faceDetector=new FaceDetector(resultBmp.getWidth(),resultBmp.getHeight(),NUMBER_OF_FACES); NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(resultBmp, detectedFaces); System.out.println("faces detected are"+NUMBER_OF_FACE_DETECTED); Canvas facec=new Canvas(); for(int count=0;count<NUMBER_OF_FACE_DETECTED;count++) { if(count==0){ face1=detectedFaces[count]; midPoint1=new PointF(); face1.getMidPoint(midPoint1); eyeDistance=face1.eyesDistance(); } } invalidate(); if(NUMBER_OF_FACE_DETECTED==0){ Toast.makeText(getContext(), "no faces detected", Toast.LENGTH_LONG).show(); }else if(NUMBER_OF_FACE_DETECTED!=0){ Toast.makeText(getContext(), "faces detected "+NUMBER_OF_FACE_DETECTED, Toast.LENGTH_LONG).show(); } } protected void onDraw(Canvas canvas) { if(myBitmap!=null) { w = myBitmap.getWidth(); h = myBitmap.getHeight(); resultBmp = null; int widthofBitMap = MainActivity.screenWidth ; int heightofBitMap = widthofBitMap*h/w; resultBmp = Bitmap.createScaledBitmap(myBitmap, widthofBitMap, heightofBitMap, true); canvas.drawBitmap(resultBmp, (MainActivity.screenWidth-widthofBitMap)/2,(MainActivity.screenHeight-heightofBitMap)/2, null); } } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); switch(action){ case MotionEvent.ACTION_MOVE: x = event.getX(); y = event.getY(); break; case MotionEvent.ACTION_DOWN: x = event.getX(); y = event.getY(); break; case MotionEvent.ACTION_UP: default: } invalidate(); return true; } }
Мне потребовалось некоторое время, чтобы написать этот код. Надеюсь, это поможет. Если вы получите какую-то ошибку, просто спросите.