You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smartglasses/code/CameraActivity.java

399 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.yeyupiaoling.teststadiometry;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.ImageReader;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.opencv.android.OpenCVLoader;
import java.util.Arrays;
import java.util.List;
public class CameraActivity extends AppCompatActivity {
private static final String TAG = CameraActivity.class.getSimpleName();
private CameraCaptureSession mCaptureSession;
private CameraDevice mCameraDevice;
private HandlerThread mCaptureThread;
private Handler mCaptureHandler;
private ImageReader mImageReader;
private boolean isFont = false;
private Size mPreviewSize;
private boolean mCapturing;
private AutoFitTextureView mTextureView;
private ImageView imageViewLeft;
private ImageView imageViewRight;
private ImageView imageViewResult;
private int sensorOrientation = 0;
private View bgView;
private LinearLayout ll;
private TextView textView;
private StereoBMUtil stereoBMUtil;
private Bitmap leftBitmap;
private Bitmap rightBitmap;
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// 权限申请
if (!hasPermission()) {
requestPermission();
}
//初始化
if (OpenCVLoader.initDebug()) {
Log.d(TAG, "OpenCVLoader初始化成功");
}
stereoBMUtil = new StereoBMUtil();
mTextureView = findViewById(R.id.texture_view);
imageViewLeft = findViewById(R.id.imageViewLeft);
imageViewRight = findViewById(R.id.imageViewRight);
imageViewResult = findViewById(R.id.imageViewResult);
bgView = findViewById(R.id.bg_view);
ll = findViewById(R.id.show_ll);
textView = findViewById(R.id.result_tv);
Button button2 = findViewById(R.id.button2);
Button button3 = findViewById(R.id.button3);
Button button4 = findViewById(R.id.button4);
// 拍照获取左右摄像头的图像
button2.setOnClickListener(v -> {
bgView.setVisibility(View.VISIBLE);
ll.setVisibility(View.VISIBLE);
Bitmap imgBitmap = mTextureView.getBitmap();
Bitmap b = Utils.rotateBitmap(imgBitmap, 360 - sensorOrientation);
List<Bitmap> bitmapList = Utils.bisectionBitmap(b);
// 左右目摄像头的图像
leftBitmap = bitmapList.get(0);
rightBitmap = bitmapList.get(1);
imageViewLeft.setImageBitmap(leftBitmap);
imageViewRight.setImageBitmap(rightBitmap);
});
// 显示相机预览
button3.setOnClickListener(v -> {
bgView.setVisibility(View.GONE);
ll.setVisibility(View.GONE);
});
// 执行StereoBM算法
button4.setOnClickListener(v -> {
Bitmap result = stereoBMUtil.compute(leftBitmap, rightBitmap);
imageViewResult.setImageBitmap(result);
});
// 点击计算后的图片,获取三维坐标数据
imageViewResult.setOnTouchListener((v, event) -> {
// 获取触摸点的坐标 x, y
float x = event.getX();
float y = event.getY();
float[] dst = new float[2];
Matrix imageMatrix = imageViewResult.getImageMatrix();
Matrix inverseMatrix = new Matrix();
imageMatrix.invert(inverseMatrix);
inverseMatrix.mapPoints(dst, new float[]{x, y});
int dstX = (int) dst[0];
int dstY = (int) dst[1];
// 获取该点的三维坐标
double[] c = stereoBMUtil.getCoordinate(dstX, dstY);
String s = String.format("点(%d, %d) 三维坐标:[%.2f, %.2f, %.2f]", dstX, dstY, c[0], c[1], c[2]);
Log.d(TAG, s);
textView.setText(s);
return true;
});
}
// 初始化以下变量和状态
private void initStatus() {
// 启动线程
startCaptureThread();
// 判断SurfaceTexture是否可用可用就直接启动捕获图片
if (mTextureView.isAvailable()) {
startCapture();
} else {
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
startCapture();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
}
// 启动捕获图片
private void startCapture() {
// 判断是否正处于捕获图片的状态
if (mCapturing) return;
mCapturing = true;
final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraIdAvailable = null;
try {
assert manager != null;
for (final String cameraId : manager.getCameraIdList()) {
final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
// 设置相机前摄像头或者后摄像头
if (isFont) {
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
cameraIdAvailable = cameraId;
break;
}
} else {
if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
cameraIdAvailable = cameraId;
break;
}
}
}
} catch (CameraAccessException e) {
Log.e(TAG, "启动图片捕获异常 ", e);
}
try {
assert cameraIdAvailable != null;
final CameraCharacteristics characteristics =
manager.getCameraCharacteristics(cameraIdAvailable);
final StreamConfigurationMap map =
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
try {
sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
Log.i(TAG, "orientation: " + sensorOrientation);
} catch (Exception e) {
e.printStackTrace();
}
assert map != null;
mPreviewSize = Utils.chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
mTextureView.getWidth(),
mTextureView.getHeight());
Log.d("mPreviewSize", String.valueOf(mPreviewSize));
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
manager.openCamera(cameraIdAvailable, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
mCameraDevice = camera;
createCaptureSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
camera.close();
mCameraDevice = null;
mCapturing = false;
}
@Override
public void onError(@NonNull CameraDevice camera, final int error) {
Log.e(TAG, "打开相机错误 = " + error);
camera.close();
mCameraDevice = null;
mCapturing = false;
}
}, mCaptureHandler);
} catch (CameraAccessException | SecurityException e) {
mCapturing = false;
Log.e(TAG, "启动图片捕获异常 ", e);
}
}
// 创建捕获图片session
private void createCaptureSession() {
try {
final SurfaceTexture texture = mTextureView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
final Surface surface = new Surface(texture);
final CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
mImageReader = ImageReader.newInstance(
mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.JPEG, 10);
mCameraDevice.createCaptureSession(
Arrays.asList(surface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
if (null == mCameraDevice) {
return;
}
mCaptureSession = cameraCaptureSession;
try {
captureRequestBuilder.set(
CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(
CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
CaptureRequest previewRequest = captureRequestBuilder.build();
mCaptureSession.setRepeatingRequest(
previewRequest, new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
super.onCaptureProgressed(session, request, partialResult);
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
Log.d(TAG, "onCaptureFailed = " + failure.getReason());
}
@Override
public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, int sequenceId, long frameNumber) {
super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
Log.d(TAG, "onCaptureSequenceCompleted");
}
}, mCaptureHandler);
} catch (final CameraAccessException e) {
Log.e(TAG, "onConfigured exception ", e);
}
}
@Override
public void onConfigureFailed(@NonNull final CameraCaptureSession cameraCaptureSession) {
Log.e(TAG, "onConfigureFailed ");
}
},
null);
} catch (final CameraAccessException e) {
Log.e(TAG, "创建捕获图片session异常 ", e);
}
}
// 关闭相机
private void closeCamera() {
if (mCaptureSession != null) {
mCaptureSession.close();
mCaptureSession = null;
}
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if (mImageReader != null) {
mImageReader.close();
mImageReader = null;
}
mCapturing = false;
}
// 关闭捕获图片线程
private void stopCaptureThread() {
try {
if (mCaptureThread != null) {
mCaptureThread.quitSafely();
mCaptureThread.join();
}
mCaptureThread = null;
mCaptureHandler = null;
} catch (final Exception e) {
e.printStackTrace();
}
}
@Override
protected void onPause() {
// 关闭相机
closeCamera();
stopCaptureThread();
super.onPause();
}
@Override
protected void onStop() {
// 关闭相机
closeCamera();
stopCaptureThread();
super.onStop();
}
// 启动捕获图片线程
private void startCaptureThread() {
mCaptureThread = new HandlerThread("capture");
mCaptureThread.start();
mCaptureHandler = new Handler(mCaptureThread.getLooper());
}
@Override
protected void onResume() {
initStatus();
super.onResume();
}
// check had permission
private boolean hasPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
} else {
return true;
}
}
// request permission
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
}
}
}