Ich habe den ganzen Tag nach einer Lösung gesucht. Ich habe mehrere Threads zu meinem Problem ausgecheckt.
Aber es hat mir nicht viel geholfen. Grundsätzlich möchte ich, dass die Kameravorschau im Vollbildmodus angezeigt wird, Text jedoch nur in der Mitte des Bildschirms erkannt wird, in der ein Rechteck gezeichnet wird.
Technologien, die ich verwende:
- Google Mobile Vision-APIs für die optische Zeichenerkennung (OCR)
- Abhängigkeit:
play-services-vision
Mein aktueller Status: Ich habe eine BoxDetector-Klasse erstellt:
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);
}
}
Und hier eine Instanz dieser Klasse implementiert:
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();
Bei der Ausführung wird diese Ausnahme ausgelöst:
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)
Wenn jemand eine Ahnung hat, was meine Schuld ist oder welche Alternativen es gibt, würde ich es wirklich schätzen. Vielen Dank!
Das möchte ich erreichen, ein Rect. Textbereichsscanner:
mDetector.receiveFrame(outputFrame);
In Google Vision können Sie die Koordinaten eines erkannten Textes abrufen, wie unter So ermitteln Sie die Position von Text in einem Bild mithilfe der Mobile Vision-API beschrieben.
Sie erhalten die
TextBlocks
vonTextRecognizer
, dann filtern Sie dieTextBlock
nach ihren Koordinaten, die durch die MethodegetBoundingBox()
odergetCornerPoints()
derTextBlocks
Klasse bestimmt werden können:Quelle: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextRecognizer
Quelle: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextBlock
Sie verfahren also im Wesentlichen wie unter So ermitteln Sie die Position von Text in einem Bild mithilfe der Mobile Vision-API. Sie teilen jedoch keinen Block in Zeilen und dann keine Zeile in Wörter wie
Stattdessen erhalten Sie das Begrenzungsfeld aller Textblöcke und wählen dann das Begrenzungsfeld mit den Koordinaten aus, die der Mitte des Bildschirms / Rahmens oder dem von Ihnen angegebenen Rechteck am nächsten liegen (dh wie kann ich die Mitte x, y meiner Ansicht in Android erhalten? ). Hierfür verwenden Sie die Methode
getBoundingBox()
odergetCornerPoints()
vonTextBlocks
...quelle