Java 试图实施一项服务,该服务将查找对象(即车牌的一部分),然后通过OCR(已实施OCR)对其进行扫描
我的应用程序的目标是扫描车牌并仅返回车牌号。没有州或州代码,底部没有额外的文本(弗吉尼亚是情人节等) 我使用MLKit的FireBase作为我的OCR引擎。目前,OCR阅读器试图读取我写的弗吉尼亚号和车牌号。OCR是相当古老的,这就是为什么弗吉尼亚(它太小,无法正确阅读)翻译错误,但这一部分是不相关的。 我的最终目标是在文本区域中只显示车牌号 我在下面包含了相关的代码文件 MainActivity.javaJava 试图实施一项服务,该服务将查找对象(即车牌的一部分),然后通过OCR(已实施OCR)对其进行扫描,java,android,android-studio,Java,Android,Android Studio,我的应用程序的目标是扫描车牌并仅返回车牌号。没有州或州代码,底部没有额外的文本(弗吉尼亚是情人节等) 我使用MLKit的FireBase作为我的OCR引擎。目前,OCR阅读器试图读取我写的弗吉尼亚号和车牌号。OCR是相当古老的,这就是为什么弗吉尼亚(它太小,无法正确阅读)翻译错误,但这一部分是不相关的。 我的最终目标是在文本区域中只显示车牌号 我在下面包含了相关的代码文件 MainActivity.java package com.mvsolutions.snap; import androi
package com.mvsolutions.snap;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.navigation.NavigationView;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
R.id.nav_tools, R.id.nav_share, R.id.nav_send)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
HomeFragment.java
package com.mvsolutions.snap.ui.home;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.ml.vision.FirebaseVision;
import com.google.firebase.ml.vision.common.FirebaseVisionImage;
import com.google.firebase.ml.vision.text.FirebaseVisionText;
import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector;
import com.mvsolutions.snap.R;
import java.util.List;
import static android.app.Activity.RESULT_OK;
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private ImageView imageView;
private Button captureImageButton, detectButton;
private Bitmap imageBitmap;
private TextView capturedTextView;
static final int REQUEST_IMAGE_CAPTURE = 1;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
imageView = root.findViewById(R.id.home_image_view_img);
capturedTextView = root.findViewById(R.id.home_text_view_txt);
captureImageButton = root.findViewById(R.id.button_capture_image_btn);
detectButton = root.findViewById(R.id.button_detect_text_btn);
captureImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
detectButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
detectTextFromImage();
}
});
return root;
}
private void placeholder() {
//ignore this
}
private void detectTextFromImage() {
capturedTextView.setText("");
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(imageBitmap);
FirebaseVisionTextDetector visionTextDetector = FirebaseVision.getInstance().getVisionTextDetector();
visionTextDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
@Override
public void onSuccess(FirebaseVisionText firebaseVisionText) {
List<FirebaseVisionText.Block> textBlocks = firebaseVisionText.getBlocks();
if(textBlocks.size() == 0){
Toast.makeText(getContext(), "No Text Found", Toast.LENGTH_SHORT).show();
}else{
for(FirebaseVisionText.Block block : textBlocks){
String text = block.getText();
capturedTextView.setText(capturedTextView.getText() + " " + text);
}
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getContext(), "Something went wrong", Toast.LENGTH_SHORT).show();
Log.d("Error", e.getMessage());
}
});
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
imageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(imageBitmap);
}
}
}
package com.mvsolutions.snap.ui.home;
导入android.content.Intent;
导入android.graphics.Bitmap;
导入android.os.Bundle;
导入android.provider.MediaStore;
导入android.util.Log;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.Button;
导入android.widget.ImageView;
导入android.widget.TextView;
导入android.widget.Toast;
导入androidx.annotation.Nullable;
导入androidx.annotation.NonNull;
导入androidx.fragment.app.fragment;
导入androidx.lifecycle.Observer;
导入androidx.lifecycle.ViewModelProviders;
导入com.google.android.gms.tasks.OnFailureListener;
导入com.google.android.gms.tasks.OnSuccessListener;
导入com.google.firebase.ml.vision.FirebaseVision;
导入com.google.firebase.ml.vision.common.FirebaseVisionImage;
导入com.google.firebase.ml.vision.text.FirebaseVisionText;
导入com.google.firebase.ml.vision.text.FirebaseVisionTextDetector;
导入com.mvsolutions.snap.R;
导入java.util.List;
导入静态android.app.Activity.RESULT\u确定;
公共类HomeFragment扩展了片段{
私有HomeViewModel HomeViewModel;
私人影像视图;
专用按钮captureImageButton、detectButton;
私有位图;
私有文本视图capturedTextView;
静态最终整数请求\图像\捕获=1;
公共视图onCreateView(@NonNull layoutiner充气机,
视图组容器,捆绑包savedInstanceState){
homeViewModel=ViewModelProviders.of(this.get)(homeViewModel.class);
视图根=充气机。充气(R.layout.fragment\u home,container,false);
imageView=root.findViewById(R.id.home\u image\u view\u img);
capturedTextView=root.findViewById(R.id.home\u text\u view\u txt);
captureImageButton=root.findviewbyd(R.id.button\u capture\u image\u btn);
detectButton=root.findViewById(R.id.button\u detect\u text\u btn);
CaptureMageButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
DispatchTakePictureContent();
}
});
detectButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
detectTextFromImage();
}
});
返回根;
}
专用void占位符(){
//忽略这一点
}
私有无效检测TextFromImage(){
capturedTextView.setText(“”);
FirebaseVisionImage FirebaseVisionImage=FirebaseVisionImage.fromBitmap(图像位图);
FirebaseVisionTextDetector visionTextDetector=FirebaseVision.getInstance().getVisionTextDetector();
visionTextDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(新OnSuccessListener(){
@凌驾
成功时公共无效(FirebaseVisionText FirebaseVisionText){
List textBlocks=firebaseVisionText.getBlocks();
if(textBlocks.size()==0){
Toast.makeText(getContext(),“找不到文本”,Toast.LENGTH_SHORT.show();
}否则{
用于(FirebaseVisionText.Block:textBlocks){
String text=block.getText();
capturedTextView.setText(capturedTextView.getText()+“”+text);
}
}
}
}).addOnFailureListener(新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
Toast.makeText(getContext(),“出错了”,Toast.LENGTH_SHORT.show();
Log.d(“错误”,例如getMessage());
}
});
}
私有无效DispatchTakePictureContent(){
Intent takePictureIntent=新的意图(MediaStore.ACTION\u IMAGE\u CAPTURE);
if(takePictureContent.resolveActivity(getActivity().getPackageManager())!=null){
startActivityForResult(获取图片内容、请求图像捕获);
}
}
@凌驾
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
if(requestCode==REQUEST\u IMAGE\u CAPTURE&&resultCode==RESULT\u OK){
Bundle extras=data.getExtras();
imageBitmap=(位图)extras.get(“数据”);
设置图像位图(图像位图);
}
}
}
除了使用较新版本的FireBase之外,还有什么解决方案吗?也许可以使用文本
块的边界框
并过滤掉除最大高度块以外的所有高度块。假设许可证部分明显高于任何其他文本。所有的测量都是相对的,因为你们不能假设到物体的距离。在您发布的示例中返回了多少个块;如果这都是一个障碍,那么这个方法就失败了。@Andy我该怎么做?这是已经实施的吗?我必须实现一个新的API或SDK吗?block
(在textBlocks
循环中)有一个名为getBoundingBox
-lo的方法