He estado buscando todo el día una solución. He revisado varios hilos con respecto a mi problema.
Pero no me ayudó mucho. Básicamente, quiero que la Vista previa de la cámara sea de pantalla completa, pero el texto solo se reconoce en el centro de la pantalla, donde se dibuja un Rectángulo.
Tecnologías que estoy usando:
- API de Google Mobile Vision para reconocimiento óptico de caracteres (OCR)
- Dependencia:
play-services-vision
Mi estado actual: creé una clase BoxDetector:
public class BoxDetector extends Detector {
private Detector mDelegate;
private int mBoxWidth, mBoxHeight;
public BoxDetector(Detector delegate, int boxWidth, int boxHeight) {
mDelegate = delegate;
mBoxWidth = boxWidth;
mBoxHeight = boxHeight;
}
public SparseArray detect(Frame frame) {
int width = frame.getMetadata().getWidth();
int height = frame.getMetadata().getHeight();
int right = (width / 2) + (mBoxHeight / 2);
int left = (width / 2) - (mBoxHeight / 2);
int bottom = (height / 2) + (mBoxWidth / 2);
int top = (height / 2) - (mBoxWidth / 2);
YuvImage yuvImage = new YuvImage(frame.getGrayscaleImageData().array(), ImageFormat.NV21, width, height, null);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(left, top, right, bottom), 100, byteArrayOutputStream);
byte[] jpegArray = byteArrayOutputStream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length);
Frame croppedFrame =
new Frame.Builder()
.setBitmap(bitmap)
.setRotation(frame.getMetadata().getRotation())
.build();
return mDelegate.detect(croppedFrame);
}
public boolean isOperational() {
return mDelegate.isOperational();
}
public boolean setFocus(int id) {
return mDelegate.setFocus(id);
}
@Override
public void receiveFrame(Frame frame) {
mDelegate.receiveFrame(frame);
}
}
E implementó una instancia de esta clase aquí:
final TextRecognizer textRecognizer = new TextRecognizer.Builder(App.getContext()).build();
// Instantiate the created box detector in order to limit the Text Detector scan area
BoxDetector boxDetector = new BoxDetector(textRecognizer, width, height);
//Set the TextRecognizer's Processor but using the box collider
boxDetector.setProcessor(new Detector.Processor<TextBlock>() {
@Override
public void release() {
}
/*
Detect all the text from camera using TextBlock
and the values into a stringBuilder which will then be set to the textView.
*/
@Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> items = detections.getDetectedItems();
if (items.size() != 0) {
mTextView.post(new Runnable() {
@Override
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
TextBlock item = items.valueAt(i);
stringBuilder.append(item.getValue());
stringBuilder.append("\n");
}
mTextView.setText(stringBuilder.toString());
}
});
}
}
});
mCameraSource = new CameraSource.Builder(App.getContext(), boxDetector)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(height, width)
.setAutoFocusEnabled(true)
.setRequestedFps(15.0f)
.build();
En la ejecución se lanza esta excepción:
Exception thrown from receiver.
java.lang.IllegalStateException: Detector processor must first be set with setProcessor in order to receive detection results.
at com.google.android.gms.vision.Detector.receiveFrame(com.google.android.gms:play-services-vision-common@@19.0.0:17)
at com.spectures.shopendings.Helpers.BoxDetector.receiveFrame(BoxDetector.java:62)
at com.google.android.gms.vision.CameraSource$zzb.run(com.google.android.gms:play-services-vision-common@@19.0.0:47)
at java.lang.Thread.run(Thread.java:919)
Si alguien tiene una pista, cuál es mi culpa o tiene alguna alternativa, realmente lo agradecería. ¡Gracias!
Esto es lo que quiero lograr, un Rect. Escáner de área de texto:
mDetector.receiveFrame(outputFrame);
En google-vision puede obtener las coordenadas de un texto detectado como se describe en ¿Cómo obtener la posición del texto en una imagen usando la API de Mobile Vision?
Obtiene el
TextBlocks
deTextRecognizer
, luego filtra elTextBlock
por sus coordenadas, que se pueden determinar por el métodogetBoundingBox()
ogetCornerPoints()
deTextBlocks
clase:fuente: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextRecognizer
fuente: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextBlock
¿Entonces básicamente procedes como en Cómo obtener la posición del texto en una imagen usando la API de Mobile Vision? sin embargo, no divide ningún bloque en líneas y luego ninguna línea en palabras como
en su lugar, obtiene el cuadro de límite de todos los bloques de texto y luego selecciona el cuadro de límite con las coordenadas más cercanas al centro de la pantalla / marco o el rectángulo que especifique (es decir, ¿cómo puedo obtener el centro x, y de mi vista en Android? ) Para esto, utiliza el método
getBoundingBox()
o ...getCornerPoints()
TextBlocks
fuente