如何在Android中创建Google Lens应用程序?
从照片或视频流中提取和分析文本的能力是一项宝贵的技能,可以显著提高Android应用程序的功能和用户体验。Google Lens是Google开发的一项先进的图像识别和增强现实技术,就是一个著名的例子。虽然复制Google Lens的全部功能是一项艰巨的任务,但我们可以研究一个更简单的实现,该实现使用Google Vision API在Android应用程序中专注于文本识别。
使用的方法
在Android中使用Google Vision API进行文本识别
在Android中使用Google Vision API进行文本识别
算法
步骤1 - 设置布局。
设计活动布局。创建一个包含用于相机预览的SurfaceView和用于显示识别文本的TextView的布局文件。
步骤2 - 创建活动。
创建一个新的活动类;我们将其命名为GoogleLensActivity。
在onCreate()方法中,初始化相机并在SurfaceView上启动相机预览。
设置相机回调,以便在相机预览可用时捕获图像。
步骤3 - 显示识别的文本。
实现文本识别器。Processor接口处理文本识别过程。
在TextRecognizer.Processor的receiveDetections()方法中,使用从相机图像中识别的文本更新识别的文本TextView。
步骤4 - 更新布局和清单。
更新布局XML文件以包含必要的视图(SurfaceView和TextView)。
向应用程序的AndroidManifest.xml文件中添加相机和互联网权限。
XML代码
<!-- below line is use to add camera feature in our app --> <uses-feature android:name="android.hardware.camera" android:required="true" /> <!-- permission for internet --> <uses-permission android:name="android.permission.INTERNET" />
<meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="label" />
XML程序
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.googlelens"> <!-- below line is use to add camera feature in our app --> <uses-feature android:name="android.hardware.camera" android:required="true" /> <!-- permission for internet --> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.GoogleLens"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="label" /> </application> </manifest>
XML程序
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--image view for displaying our image-->
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:scaleType="centerCrop" />
<LinearLayout
android:id="@+id/idLLButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/image"
android:orientation="horizontal">
<!--button for capturing our image-->
<Button
android:id="@+id/snapbtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_marginTop="30dp"
android:layout_weight="1"
android:lines="2"
android:text="Snap"
android:textAllCaps="false"
android:textSize="18sp"
android:textStyle="bold" />
<!--button for detecting the objects-->
<Button
android:id="@+id/idBtnSearchResuts"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_marginTop="30dp"
android:layout_weight="1"
android:lines="2"
android:text="Get Search Results"
android:textAllCaps="false"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<!--recycler view for displaying the list of result-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/idRVSearchResults"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/idLLButtons" />
</RelativeLayout>
Java程序
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
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.label.FirebaseVisionImageLabel;
import com.google.firebase.ml.vision.label.FirebaseVisionImageLabeler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
// variables for our image view, image bitmap,
// buttons, recycler view, adapter and array list.
private ImageView img;
private Button snap, searchResultsBtn;
private Bitmap imageBitmap;
private RecyclerView resultRV;
private SearchResultsRVAdapter searchResultsRVAdapter;
private ArrayList<DataModal> dataModalArrayList;
private String title, link, displayed_link, snippet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing all our variables for views
img = (ImageView) findViewById(R.id.image);
snap = (Button) findViewById(R.id.snapbtn);
searchResultsBtn = findViewById(R.id.idBtnSearchResuts);
resultRV = findViewById(R.id.idRVSearchResults);
// initializing our array list
dataModalArrayList = new ArrayList<>();
// initializing our adapter class.
searchResultsRVAdapter = new SearchResultsRVAdapter(dataModalArrayList, MainActivity.this);
// layout manager for our recycler view.
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
// on below line we are setting layout manager
// and adapter to our recycler view.
resultRV.setLayoutManager(manager);
resultRV.setAdapter(searchResultsRVAdapter);
// adding on click listener for our snap button.
snap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// calling a method to capture an image.
dispatchTakePictureIntent();
}
});
// adding on click listener for our button to search data.
searchResultsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// calling a method to get search results.
getResults();
}
});
}
private void getResults() {
// inside the label image method we are calling a firebase vision image
// and passing our image bitmap to it.
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(imageBitmap);
// on below line we are creating a labeler for our image bitmap and
// creating a variable for our firebase vision image labeler.
FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance().getOnDeviceImageLabeler();
// calling a method to process an image and adding on success listener method to it.
labeler.processImage(image).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionImageLabel>>() {
@Override
public void onSuccess(List<FirebaseVisionImageLabel> firebaseVisionImageLabels) {
String searchQuery = firebaseVisionImageLabels.get(0).getText();
searchData(searchQuery);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// displaying error message.
Toast.makeText(MainActivity.this, "Fail to detect image..", Toast.LENGTH_SHORT).show();
}
});
}
private void searchData(String searchQuery) {
String apiKey = "Enter your API key here";
String url = "https://serpapi.com/search.json?q=" + searchQuery.trim() + "&location=Delhi,India&hl=en&gl=us&google_domain=google.com&api_key=" + apiKey;
// creating a new variable for our request queue
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
// on below line we are extracting data from our json.
JSONArray organicResultsArray = response.getJSONArray("organic_results");
for (int i = 0; i < organicResultsArray.length(); i++) {
JSONObject organicObj = organicResultsArray.getJSONObject(i);
if (organicObj.has("title")) {
title = organicObj.getString("title");
}
if (organicObj.has("link")) {
link = organicObj.getString("link");
}
if (organicObj.has("displayed_link")) {
displayed_link = organicObj.getString("displayed_link");
}
if (organicObj.has("snippet")) {
snippet = organicObj.getString("snippet");
}
// on below line we are adding data to our array list.
dataModalArrayList.add(new DataModal(title, link, displayed_link, snippet));
}
// notifying our adapter class
// on data change in array list.
searchResultsRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// displaying error message.
Toast.makeText(MainActivity.this, "No Result found for the search query..", Toast.LENGTH_SHORT).show();
}
});
// adding json object request to our queue.
queue.add(jsonObjectRequest);
}
// method to capture image.
private void dispatchTakePictureIntent() {
// inside this method we are calling an implicit intent to capture an image.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// calling a start activity for result when image is captured.
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// inside on activity result method we are
// setting our image to our image view from bitmap.
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
imageBitmap = (Bitmap) extras.get("data");
// on below line we are setting our
// bitmap to our image view.
img.setImageBitmap(imageBitmap);
}
}
}
输出


结论
本文旨在介绍如何使用Google Vision API进行内容识别,并根据您的特定应用程序需求提供大量的修改和扩展空间。您可以通过添加诸如语言翻译、实体识别和问题识别等功能来增强其实用性。文本识别提供了无限的可能性,使您可以创建能够从图像中提取和翻译内容、辅助视力障碍用户、自动化数据输入等等的应用程序。
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP