提交Android版实时识别功能
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
package pr.platerecognization;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ImageFormat;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.YuvImage;
|
||||
import android.hardware.Camera;
|
||||
import android.media.Image;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.Policy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author by hs-johnny
|
||||
* Created on 2019/6/17
|
||||
*/
|
||||
public class CameraPreviews extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
|
||||
|
||||
private static final String TAG = "CameraPreview";
|
||||
private Camera mCamera;
|
||||
private SurfaceHolder mHolder;
|
||||
public long handle;
|
||||
private byte[] lock = new byte[0];
|
||||
private List<String> mResultList = new ArrayList<>();
|
||||
private String currentPlate = "";
|
||||
private Paint mPaint;
|
||||
private float oldDist = 1f;
|
||||
/** 停止识别*/
|
||||
private boolean isStopReg;
|
||||
|
||||
public CameraPreviews(Context context) {
|
||||
super(context);
|
||||
mHolder = getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setStrokeWidth(2);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setColor(ContextCompat.getColor(context, R.color.colorAccent));
|
||||
}
|
||||
public Camera getCameraInstance(){
|
||||
if (mCamera == null){
|
||||
try {
|
||||
CameraHandlerThread mThread = new CameraHandlerThread("camera thread");
|
||||
synchronized (mThread){
|
||||
mThread.openCamera();
|
||||
}
|
||||
}catch (Exception e){
|
||||
Log.e(TAG, "camera is not available" );
|
||||
}
|
||||
}
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
mCamera = getCameraInstance();
|
||||
mCamera.setPreviewCallback(this);
|
||||
try {
|
||||
mCamera.setPreviewDisplay(mHolder);
|
||||
mCamera.startPreview();
|
||||
setPreviewFocus(mCamera);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
int rotation = getDisplayOrientation();
|
||||
mCamera.setDisplayOrientation(rotation);
|
||||
Camera.Parameters parameters = mCamera.getParameters();
|
||||
parameters.setRotation(rotation);
|
||||
mCamera.setParameters(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
mHolder.removeCallback(this);
|
||||
mCamera.setPreviewCallback(null);
|
||||
mCamera.stopPreview();
|
||||
mCamera.release();
|
||||
mCamera = null;
|
||||
}
|
||||
|
||||
public int getDisplayOrientation(){
|
||||
Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
int rotation = display.getRotation();
|
||||
int degrees = 0;
|
||||
switch (rotation){
|
||||
case Surface.ROTATION_0:
|
||||
degrees = 0;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
degrees = 90;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
degrees = 180;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
degrees = 270;
|
||||
break;
|
||||
}
|
||||
Camera.CameraInfo info = new Camera.CameraInfo();
|
||||
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
|
||||
int result = (info.orientation - degrees + 360) % 360;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreviewFrame(final byte[] data, final Camera camera) {
|
||||
synchronized (lock){
|
||||
//处理data
|
||||
Camera.Size previewSize = camera.getParameters().getPreviewSize();
|
||||
BitmapFactory.Options newOpts = new BitmapFactory.Options();
|
||||
newOpts.inJustDecodeBounds = true;
|
||||
YuvImage yuvimage = new YuvImage(
|
||||
data,
|
||||
ImageFormat.NV21,
|
||||
previewSize.width,
|
||||
previewSize.height,
|
||||
null);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos);
|
||||
byte[] rawImage = baos.toByteArray();
|
||||
//将rawImage转换成bitmap
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
|
||||
PlateInfo result = MainActivity.simpleRecog(rotateBitmap(bitmap), 8);
|
||||
bitmap.recycle();
|
||||
Log.e(TAG, "onPreviewFrame: "+result.plateName + "----time: "+ System.currentTimeMillis());
|
||||
if(!isStopReg && result != null && !TextUtils.isEmpty(result.plateName)) {
|
||||
isStopReg = true;
|
||||
sendPlate(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPlate(PlateInfo plate){
|
||||
EventBus.getDefault().post(plate);
|
||||
}
|
||||
|
||||
private Bitmap rotateBitmap(Bitmap bmp){
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(90);
|
||||
Bitmap rotatedBitMap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
|
||||
return rotatedBitMap;
|
||||
}
|
||||
|
||||
private void openCameraOriginal(){
|
||||
try {
|
||||
mCamera = Camera.open();
|
||||
}catch (Exception e){
|
||||
Log.e(TAG, "camera is not available");
|
||||
}
|
||||
}
|
||||
|
||||
private class CameraHandlerThread extends HandlerThread {
|
||||
Handler handler;
|
||||
public CameraHandlerThread(String name) {
|
||||
super(name);
|
||||
start();
|
||||
handler = new Handler(getLooper());
|
||||
}
|
||||
|
||||
synchronized void notifyCameraOpened(){
|
||||
notify();
|
||||
}
|
||||
|
||||
void openCamera(){
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
openCameraOriginal();
|
||||
notifyCameraOpened();
|
||||
}
|
||||
});
|
||||
try {
|
||||
wait();
|
||||
}catch (Exception e){
|
||||
Log.e(TAG, "wait was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(event.getPointerCount() == 2){
|
||||
switch (event.getAction()){
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
oldDist = getFingerSpacing(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float newDist = getFingerSpacing(event);
|
||||
if(newDist > oldDist){
|
||||
handleZoom(true, mCamera);
|
||||
}else if(newDist < oldDist){
|
||||
handleZoom(false, mCamera);
|
||||
}
|
||||
oldDist = newDist;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private float getFingerSpacing(MotionEvent event){
|
||||
float x = event.getX(0) - event.getX(1);
|
||||
float y = event.getY(0) - event.getY(1);
|
||||
return (float) Math.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
private void handleZoom(boolean isZoomIn, Camera camera){
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
if (parameters.isZoomSupported()){
|
||||
int maxZoom = parameters.getMaxZoom();
|
||||
int zoom = parameters.getZoom();
|
||||
if (isZoomIn && zoom < maxZoom){
|
||||
zoom++;
|
||||
}else if(zoom > 0){
|
||||
zoom--;
|
||||
}
|
||||
parameters.setZoom(zoom);
|
||||
camera.setParameters(parameters);
|
||||
}else {
|
||||
Log.e(TAG, "handleZoom: "+"the device is not support zoom");
|
||||
}
|
||||
}
|
||||
|
||||
private void setPreviewFocus(Camera camera){
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
List<String> focusList = parameters.getSupportedFocusModes();
|
||||
if(focusList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
|
||||
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
||||
}
|
||||
camera.setParameters(parameters);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user