Android 獲取人臉個(gè)數(shù)Demo

和你一起終身學(xué)習(xí),這里是程序員Android
經(jīng)典好文推薦,通過閱讀本文,您將收獲以下知識(shí)點(diǎn):
一、實(shí)現(xiàn)思路與步驟
二、創(chuàng)建布局文件
三、獲取相機(jī)信息
四、申請(qǐng)Camera 權(quán)限
五、獲取相機(jī)參數(shù)
六、開始相機(jī)配流
七、創(chuàng)建Capture 請(qǐng)求
八、實(shí)現(xiàn)預(yù)覽回調(diào)
九、Demo 所有代碼
一、實(shí)現(xiàn)思路與步驟
最近項(xiàng)目需求是統(tǒng)計(jì)當(dāng)前攝像頭中的人臉個(gè)數(shù),安卓有提供現(xiàn)成的Api,最終實(shí)現(xiàn)效果如下圖。

1.1 分析思路和步奏:
主要使用到的類:SurfaceView、CameraManager、CameraDevice.StateCallback、CameraCaptureSession.StateCallback。
1.通過SurfaceView展示預(yù)覽區(qū)。
2.在SurfaceView創(chuàng)建成功后通過CameraManager獲取當(dāng)前設(shè)備可用的攝像頭。
3.檢測(cè)攝像頭權(quán)限。
4.通過CameraManager打開攝像頭。
5.在打開成功的回調(diào)中通過CameraDevice創(chuàng)建會(huì)話。
6.在會(huì)話創(chuàng)建成功的回調(diào)方法中創(chuàng)建預(yù)覽請(qǐng)求。
7.在預(yù)覽請(qǐng)求的回調(diào)方法onCaptureCompleted()方法中獲取預(yù)覽界面中返回的人臉數(shù)。
以下是實(shí)現(xiàn)步奏:
二、創(chuàng)建布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
java
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
surfaceHolder = sv.getHolder();
surface = surfaceHolder.getSurface();
三、獲取相機(jī)信息
//獲取可用的相機(jī)列表
String[] cameraIdList = cameraManager.getCameraIdList();
四、申請(qǐng)Camera 權(quán)限
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
五、獲取相機(jī)參數(shù)
//獲取開啟相機(jī)的相關(guān)參數(shù)
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraIdList[1]);
//可用于判斷是否支持人臉檢測(cè),以及支持到哪種程度
faceDetectModes = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人臉檢測(cè)模式
cameraManager.openCamera(cameraIdList[1], mStateCallback, null);
六、開始相機(jī)配流
camera.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, new Handler());
七、創(chuàng)建Capture 請(qǐng)求
CaptureRequest.Builder captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequest.addTarget(surface);
captureRequest.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
captureRequest.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());
session.setRepeatingRequest(captureRequest.build(),captureCallback,new Handler());
八、實(shí)現(xiàn)預(yù)覽回調(diào)
/**
* 預(yù)覽回調(diào)
*/
private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
super.onCaptureProgressed(session, request, partialResult);
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Face faces[] = result.get(CaptureResult.STATISTICS_FACES);
if (faces.length != face) {
Log.e("lee", faces.length + "張臉");
}
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
@Override
public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, int sequenceId, long frameNumber) {
super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
}
@Override
public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, int sequenceId) {
super.onCaptureSequenceAborted(session, sequenceId);
}
@Override
public void onCaptureBufferLost(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) {
super.onCaptureBufferLost(session, request, target, frameNumber);
}
};
九、Demo 所有代碼
MainActivity.java
public class MainActivity extends AppCompatActivity {
private SurfaceView sv;
private SurfaceHolder surfaceHolder;
private CameraManager cameraManager;
private Surface surface;
int[] faceDetectModes;
int face;
List<Bitmap> bitmaps = new ArrayList<>();
/**
* 獲取支持的最高人臉檢測(cè)級(jí)別
*
* @return
*/
private int getFaceDetectMode() {
if (faceDetectModes == null) {
return CaptureRequest.STATISTICS_FACE_DETECT_MODE_FULL;
} else {
return faceDetectModes[faceDetectModes.length - 1];
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = findViewById(R.id.sv);
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
surfaceHolder = sv.getHolder();
surface = surfaceHolder.getSurface();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
//獲取可用的相機(jī)列表
String[] cameraIdList = cameraManager.getCameraIdList();
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
//獲取開啟相機(jī)的相關(guān)參數(shù)
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraIdList[1]);
//可用于判斷是否支持人臉檢測(cè),以及支持到哪種程度
faceDetectModes = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人臉檢測(cè)模式
cameraManager.openCamera(cameraIdList[1], mStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
}
/**
* 相機(jī)狀態(tài)回調(diào)
*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull final CameraDevice camera) {
//打開成功,可以獲取CameraDevice對(duì)象
try {
camera.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
CaptureRequest.Builder captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequest.addTarget(surface);
captureRequest.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
captureRequest.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());
session.setRepeatingRequest(captureRequest.build(),captureCallback,new Handler());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, new Handler());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
//斷開連接
Toast.makeText(MainActivity.this, "onDisconnected", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(@NonNull CameraDevice camera, final int error) {
//發(fā)生異常
Toast.makeText(MainActivity.this, "onError", Toast.LENGTH_SHORT).show();
}
};
/**
* 預(yù)覽回調(diào)
*/
private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
super.onCaptureProgressed(session, request, partialResult);
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Face faces[] = result.get(CaptureResult.STATISTICS_FACES);
if (faces.length != face) {
Log.e("lee", faces.length + "張臉");
face = faces.length;
}
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
@Override
public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, int sequenceId, long frameNumber) {
super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
}
@Override
public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, int sequenceId) {
super.onCaptureSequenceAborted(session, sequenceId);
}
@Override
public void onCaptureBufferLost(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) {
super.onCaptureBufferLost(session, request, target, frameNumber);
}
};
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
以上就能實(shí)現(xiàn)統(tǒng)計(jì)當(dāng)前攝像頭下有多少個(gè)人臉。
原文鏈接:https://blog.csdn.net/qq77485042/article/details/109176683
友情推薦:
至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,歡迎點(diǎn)擊閱讀原文,支持原創(chuàng)作者,如有侵權(quán),懇請(qǐng)聯(lián)系小編刪除,歡迎您的建議與指正。同時(shí)期待您的關(guān)注,感謝您的閱讀,謝謝!
點(diǎn)擊閱讀原文,為大佬點(diǎn)贊!
