J'ai cherché toute la journée une solution. J'ai vérifié plusieurs discussions concernant mon problème.
Mais cela ne m'a pas beaucoup aidé. Fondamentalement, je veux que l'aperçu de la caméra soit en plein écran, mais le texte n'est reconnu qu'au centre de l'écran, où un rectangle est dessiné.
Technologies que j'utilise:
- API Google Mobile Vision pour la reconnaissance optique de caractères (OCR)
- Dépendance:
play-services-vision
Mon état actuel: j'ai créé une classe 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);
}
}
Et implémenté une instance de cette classe ici:
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();
Lors de l'exécution, cette exception est levée:
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 quelqu'un a un indice, quelle est ma faute ou a des alternatives, je l'apprécierais vraiment. Je vous remercie!
C'est ce que je veux réaliser, un Rect. Scanner de zone de texte:
mDetector.receiveFrame(outputFrame);
Dans google-vision, vous pouvez obtenir les coordonnées d'un texte détecté comme décrit dans Comment obtenir la position du texte dans une image à l'aide de l'API Mobile Vision?
Vous obtenez le
TextBlocks
deTextRecognizer
, puis vous filtrez leTextBlock
par leurs coordonnées, qui peuvent être déterminées par la méthodegetBoundingBox()
ougetCornerPoints()
de laTextBlocks
classe:source: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextRecognizer
source: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextBlock
Donc, vous procédez essentiellement comme dans Comment obtenir la position du texte dans une image à l'aide de l'API Mobile Vision? mais vous ne divisez aucun bloc en lignes, puis aucune ligne de mots comme
au lieu de cela, vous obtenez la zone de délimitation de tous les blocs de texte, puis sélectionnez la zone de délimitation avec les coordonnées les plus proches du centre de l'écran / du cadre ou du rectangle que vous spécifiez (c'est-à-dire comment puis-je obtenir le centre x, y de ma vue dans Android? ). Pour cela, vous utilisez la méthode
getBoundingBox()
ougetCornerPoints()
deTextBlocks
...la source