计算机视觉被认为是AI完全问题。 换句话说,解决它等同于创建一个像人类一样聪明的程序。 不用说,这样的程序尚未创建。 但是,如果您曾经使用过Google Goggles或Google Photos之类的应用程序,或者在Google I / O 2017的主题演讲中观看了Google Lens上的细分,您可能会意识到计算机视觉已经变得非常强大。
通过称为Cloud Cloud Vision API的基于REST的API ,Google与所有开发人员共享与革命性的视觉相关技术。 通过使用API,您可以毫不费力地向Android应用添加令人印象深刻的功能,例如面部检测,情感检测和光学字符识别。 在本教程中,我将向您展示如何进行。
先决条件
为了能够遵循本教程,您必须具备:
- Google Cloud Platform帐户
- Google Cloud 控制台上的项目
- 最新版本的Android Studio
- 和运行Android 4.4或更高版本的设备
1.启用Cloud Vision API
只有在Google Cloud控制台中启用了Cloud Vision API并获取了有效的API密钥后,才能在您的Android应用中使用Cloud Vision API。 因此,首先登录到控制台并导航到API Manager> Library> Vision API 。 在打开的页面中,只需按启用按钮。
如果您已经为您的Cloud Console项目生成了API密钥,则可以跳到下一步,因为您将可以在Cloud Vision API中重用它。 否则,请打开“ 凭证”选项卡,然后选择“ 创建凭证”>“ API密钥” 。
在弹出的对话框中,您将看到您的API密钥。
2.添加依赖项
与Google提供的大多数其他API一样,可以使用Google API客户端库访问Cloud Vision API。 要在您的Android Studio项目中使用该库,请在app
模块的build.gradle文件中添加以下compile
依赖项 :
compile 'com.google.api-client:google-api-client-android:1.22.0'
compile 'com.google.apis:google-api-services-vision:v1-rev357-1.22.0'
compile 'com.google.code.findbugs:jsr305:2.0.1'
此外,为了简化文件I / O操作,建议您还为Apache Commons IO库添加一个compile
依赖项。
compile 'commons-io:commons-io:2.5'
由于只有在您的应用程序具有INTERNET
权限的情况下,Google API客户端才能正常工作,因此请确保项目清单文件中包含以下行:
<uses-permission android:name="android.permission.INTERNET"/>
3.配置API客户端
您必须先配置Google API客户端,然后才能使用它与Cloud Vision API进行交互。 这样做主要涉及指定API密钥,HTTP传输以及应使用的JSON工厂。 如您所料,HTTP传输将负责与Google的服务器通信,而JSON工厂将负责将API生成的基于JSON的结果转换为Java对象。
对于现代Android应用,Google建议您将NetHttpTransport
类用作HTTP传输,将AndroidJsonFactory
类用作JSON工厂。
Vision
类代表适用于Cloud Vision的Google API客户端。 尽管可以使用其构造函数创建该类的实例,但是使用Vision.Builder
类可以更轻松,更灵活地进行创建。
使用Vision.Builder
类时,必须记住调用setVisionRequestInitializer()
方法来指定API密钥。 以下代码向您展示了如何:
Vision.Builder visionBuilder = new Vision.Builder(
new NetHttpTransport(),
new AndroidJsonFactory(),
null);
visionBuilder.setVisionRequestInitializer(
new VisionRequestInitializer("YOUR_API_KEY"));
一旦Vision.Builder
实例准备就绪,您就可以调用其build()
方法来生成一个新的Vision
实例,您可以在整个应用程序中使用它。
Vision vision = visionBuilder.build();
至此,您已具备开始使用Cloud Vision API所需的一切。
4.检测和分析人脸
在计算机视觉相关应用中,检测照片中的面部是非常普遍的要求。 使用Cloud Vision API,您可以创建一个高度准确的面部检测器,该面部检测器还可以识别情绪,光照条件和面部标志。
为了演示,我们将在下一张照片中运行人脸检测,该照片以Apollo 9的工作人员为特色:
我建议您从Wikimedia Commons下载高分辨率的照片,并将其放在项目的res / raw文件夹中。
步骤1:对照片进行编码
Cloud Vision API期望将其输入图像编码为放置在Image
对象内部的Base64字符串。 但是,在生成此类对象之前,必须将下载的照片(当前是原始图像资源)转换为byte
数组。 您可以使用Resources
类的openRawResource()
方法打开其输入流,并将其传递给IOUtils
类的toByteArray()
方法,以IOUtils
。
由于文件I / O操作不应在UI线程上运行,因此请确保在打开输入流之前生成新线程。 以下代码向您展示了如何:
// Create new thread
AsyncTask.execute(new Runnable() {
@Override
public void run() {
// Convert photo to byte array
InputStream inputStream =
getResources().openRawResource(R.raw.photo);
byte[] photoData = IOUtils.toByteArray(inputStream);
inputStream.close();
// More code here
}
});
现在,您可以通过调用其默认构造函数来创建Image
对象。 要将byte
数组作为Base64字符串添加到它,您需要做的就是将数组传递给它的encodeContent()
方法。
Image inputImage = new Image();
inputImage.encodeContent(photoData);
步骤2:提出要求
由于Cloud Vision API提供了几种不同的功能,因此您在向其发出请求时必须明确指定您感兴趣的功能。 为此,您必须创建一个Feature
对象并调用其setType()
方法。 以下代码显示了如何创建仅用于面部检测的Feature
对象:
Feature desiredFeature = new Feature();
desiredFeature.setType("FACE_DETECTION");
现在,使用Image
和Feature
对象,可以组成AnnotateImageRequest
实例。
AnnotateImageRequest request = new AnnotateImageRequest();
request.setImage(inputImage);
request.setFeatures(Arrays.asList(desiredFeature));
请注意, AnnotateImageRequest
对象必须始终属于BatchAnnotateImagesRequest
对象,因为Cloud Vision API旨在一次处理多个图像。 若要初始化包含单个AnnotateImageRequest
对象的BatchAnnotateImagesRequest
实例,可以使用Arrays.asList()
实用程序方法。
BatchAnnotateImagesRequest batchRequest =
new BatchAnnotateImagesRequest();
batchRequest.setRequests(Arrays.asList(request));
要实际发出面部检测请求,必须调用使用刚创建的BatchAnnotateImagesRequest
对象初始化的Annotate
对象的execute()
方法。 要生成这样的对象,您必须调用Google API Client for Cloud Vision提供的annotate()
方法。 这是如何做:
BatchAnnotateImagesResponse batchResponse =
vision.images().annotate(batchRequest).execute();
步骤3:使用回应
处理完请求后,您将获得一个包含API响应的BatchAnnotateImagesResponse
对象。 对于面部检测请求,响应包含API已检测到的每个面部的FaceAnnotation
对象。 您可以使用getFaceAnnotations()
方法获取所有FaceAnnotation
对象的列表。
List<FaceAnnotation> faces = batchResponse.getResponses()
.get(0).getFaceAnnotations();
FaceAnnotation
对象包含许多有关面Kong的有用信息,例如其位置,角度和所表达的情感。 从版本1开始,API只能检测以下情绪:喜悦,悲伤,愤怒和惊奇。
为了使本教程简短,现在让我们在Toast
简单显示以下信息:
- 脸数
- 他们表达喜悦的可能性
当然,您可以通过调用包含FaceAnnotation
对象的List
的size()
方法来获得面Kong的数量。 为了获得表达喜悦的表情,可以调用关联的FaceAnnotation
对象的直观命名为getJoyLikelihood()
方法。
请注意,由于一个简单的Toast
只能显示一个字符串,因此您必须将上述所有细节串联起来。 另外,仅可以从UI线程显示Toast
,因此请确保在调用runOnUiThread()
方法之后调用它。 以下代码向您展示了如何:
// Count faces
int numberOfFaces = faces.size();
// Get joy likelihood for each face
String likelihoods = "";
for(int i=0; i<numberOfFaces; i++) {
likelihoods += "\n It is " +
faces.get(i).getJoyLikelihood() +
" that face " + i + " is happy";
}
// Concatenate everything
final String message =
"This photo has " + numberOfFaces + " faces" + likelihoods;
// Display toast on UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
message, Toast.LENGTH_LONG).show();
}
});
现在,您可以继续运行该应用程序以查看以下结果:
5.阅读文字
从文本照片中提取字符串的过程称为光学字符识别,简称OCR。 Cloud Vision API使您可以轻松创建一个光学字符读取器,该读取器可以处理印刷文本和手写文本的照片。 而且,您创建的阅读器将不会出现倾斜的文本或覆盖在彩色图片上的文本的麻烦。
该API为OCR提供两种不同的功能:
-
TEXT_DETECTION
,用于阅读少量文字,例如招牌或书皮上的文字 - 和
DOCUMENT_TEXT_DETECTION
,用于阅读大量文本,例如小说页面上显示的文本
发出OCR请求所需遵循的步骤与发出面部检测请求所遵循的步骤相同,除了如何初始化Feature
对象。 对于OCR,必须将其类型设置为TEXT_DETECTION
或DOCUMENT_TEXT_DETECTION
。 现在,让我们来看前者。
Feature desiredFeature = new Feature();
desiredFeature.setType("TEXT_DETECTION");
当然,您还必须将包含文本的照片放在项目的res / raw文件夹中。 如果您没有这样的照片,可以使用这张显示路牌的照片:
您可以从Wikimedia Commons下载上述照片的高分辨率版本。
为了开始处理OCR操作的结果,在获取BatchAnnotateImagesResponse
对象之后,必须调用getFullTextAnnotation()
方法来获取包含所有提取文本的TextAnnotation
对象。
final TextAnnotation text = batchResponse.getResponses()
.get(0).getFullTextAnnotation();
然后,您可以调用TextAnnotation
对象的getText()
方法来实际获取对包含所提取文本的字符串的引用。
以下代码显示了如何使用Toast
显示提取的文本:
Toast.makeText(getApplicationContext(),
text.getText(), Toast.LENGTH_LONG).show();
如果现在运行您的应用程序,应该会看到类似以下内容:
结论
在本教程中,您学习了如何使用Cloud Vision API向Android应用程序添加面部检测,情感检测和光学字符识别功能。 当我说这些新功能将使您的应用程序提供更直观,更智能的用户界面时,我相信您会同意我的看法。
值得一提的是,Cloud Vision API中缺少一个重要功能:面部识别。 以目前的形式,API只能检测面部,而不能识别面部。
要了解有关API的更多信息,可以参考官方文档 。