Estive procurando o dia inteiro por uma solução. Eu verifiquei vários tópicos em relação ao meu problema.
Mas isso não me ajudou muito. Basicamente, quero que a visualização da câmera seja de tela cheia, mas o texto seja reconhecido apenas no centro da tela, onde um retângulo é desenhado.
Tecnologias que estou usando:
- APIs do Google Mobile Vision para reconhecimento óptico de caracteres (OCR)
- Dependecy:
play-services-vision
Meu estado atual: criei uma 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);
}
}
E implementou uma instância desta classe aqui:
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();
Na execução, essa exceção é lançada:
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)
Se alguém tem uma pista, qual é minha culpa ou tem alguma alternativa, eu realmente aprecio isso. Obrigado!
É isso que eu quero alcançar, um Rect. Scanner de área de texto:
mDetector.receiveFrame(outputFrame);
No google-vision, você pode obter as coordenadas de um texto detectado, como descrito em Como obter a posição do texto em uma imagem usando a API do Mobile Vision?
Você obtém o
TextBlocks
from eTextRecognizer
, em seguida, filtra oTextBlock
por suas coordenadas, que podem ser determinadas pelo métodogetBoundingBox()
ougetCornerPoints()
daTextBlocks
classe:fonte: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextRecognizer
fonte: https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextBlock
Então você basicamente prossegue como em Como obter a posição do texto em uma imagem usando a API do Mobile Vision? no entanto, você não divide nenhum bloco em linhas e, em seguida, qualquer linha em palavras como
em vez disso, você obtém a caixa de limite de todos os blocos de texto e, em seguida, seleciona a caixa de limite com as coordenadas mais próximas do centro da tela / quadro ou o retângulo especificado (por exemplo, como posso obter o centro x, y da minha visão no android? ) Para isso, você usa o método
getBoundingBox()
ougetCornerPoints()
deTextBlocks
...fonte