用谷歌ML和CockroachDB建立一个简单的图像识别引擎

145 阅读10分钟

在这个代码实验室中,我们将走过创建一个图像识别引擎的过程。它的主要目的是识别进入大楼的员工,这些员工可能戴或不戴面具。了解在任何时间点上有多少员工戴着口罩,可以帮助返回办公室的情况和可能的联系人追踪。这反过来又会增强建筑物的安全和意识。

为了实现这一目标,我们将利用谷歌的机器学习能力,利用其Vision API产品和CockroachDB Serverless来存储和检索数据。这将使我们能够使用预先训练好的图像模型,在具有高度可扩展性和全球规模的安全关系数据库环境中识别人和穿戴个人防护设备(PPE)的可能性。

预计实验时间: 45分钟

Codelab概述

  • 设置CockroachDB无服务器集群
  • 创建视觉推荐数据库
  • 创建谷歌视觉AI应用

在我们进入一步一步的教程之前,让我们先澄清几个关键点。

什么是图像识别?

图像识别是帮助我们识别一张图片或图像的所有方面的软件。 你和我都可以轻松地看一张图片并识别其内容,但人工智能需要经过训练才能做到这一点。

深度学习被用来帮助训练机器学习算法,以提高其识别图像内容的能力。深度学习是机器学习和人工智能(AI)的一种类型,模仿人类获得某些类型知识的方式。

图像识别有许多用例,但一个常见的用例是提供元数据标记或标签,相对于一个给定的图像。

例如,你在下面的图片中看到了什么? 该图像包含两个戴面具的人,一个是男性,一个是女性,都穿着背包,夹克,长发,在户外,树木,建筑,人们在行走,主要的颜色是什么....etc。

机器学习还将为每个标签打出一个信心等级。 评级越高,人工智能就越有信心为图像正确打上标签。

Image Recogntion Example

这些标签随后被用于执行图像内容搜索,例如。向我展示所有包含带个人防护设备(口罩)的人的图片。在代码实验室中,我们使用googles Vision AI。

好吧,让我们开始建立一个图像识别引擎。

第一步:创建CockroachDB无服务器实例

开始使用CockroachDB无服务器是很容易的。 通过几个快速步骤,你可以选择在谷歌云上开始使用CockroachDB Serverless。

  1. 导航到:https://cockroachlabs.cloud/现在,创建一个账户(创建账户不需要信用卡)。

  2. 当你选择一个计划时,有几个选项是预先填写的,比如云提供商(GCP)、地区(us-central1)和动态创建的集群名称。 注意:人们可以将集群名称改为更有意义的名称。

  3. 要批准你的集群设置。

你的集群将在大约20-30秒内被创建,并将显示连接对话框。

  1. 一旦你的集群准备好了,你会看到一个窗口,里面有关于如何连接到你的集群的信息。

将 "选择你的操作系统 "选项改为。Linux

Choose your OS

  1. 将每个命令行提示和连接字符串(单独的标签)复制到一个单独的记事本上,以便以后在本实验中使用。

注意:确保在每个命令行命令上标注其用途:CRDB客户端、CA证书、数据库连接和连接字符串

第二步:配置我们的谷歌云平台账户

  1. 进入cloud.google.com,用你的谷歌账户登录。如果你没有谷歌账户,请按照这个链接的说明创建一个免费试用账户。

  2. 如果还没有,请转到console.cloud.google.com/

  3. 创建一个新的项目,在左上方选择以下下拉菜单。

  4. 一个新的窗口将弹出。 在其中,选择右上方的 "新项目"。

  5. 给你的Vision API演示一个新的项目名称。 让我们用 "cockroach-vision-demo",然后点击 "创建 "按钮。

  6. 在你的新项目创建完成后,回到步骤3的下拉菜单,选择你的新项目名称

  7. 当选择了正确的项目后,名称将改变以反映在你控制台左上方的下拉菜单中。

  8. 使用这里的说明创建一个Debian Linux GCE VM实例。

注意:在创建实例时,请确保在 "访问范围 "下启用 "允许完全访问所有云API"。

  1. 在顶部的搜索框中,输入 "防火墙",并在 "VPC网络 "下选择匹配的建议 "防火墙"

  2. 点击顶部的 "创建防火墙规则",创建一个新规则,为我们的新服务器开放所需的端口。

  3. 输入以下细节并点击 "创建"。

    • 名称: port8080

    • 目标。网络中的所有实例

    • 源IP范围。[您的特定源IP/范围]

    • 协议和端口。

    注意:你可以用谷歌搜索 "what is my ip "来输入你的IP。

Cloud Firewall Rule

  1. 在上面的搜索栏中,输入 "计算引擎 "并选择建议。

  2. 在你的实例创建后,通过点击你的实例的SSH按钮,SSH到你的实例。

SSH to your instance

  1. 你应该看到一个类似这样的CloudShell窗口打开...

CloudShell window

第四步:连接到CockroachDB无服务器

现在我们已经创建了一个GCE虚拟机和防火墙规则,让我们来验证一下我们是否可以连接并运行一些查询。 使用CloudShell来完成以下步骤。

注意:你需要在本实验的步骤1.4中提到的复制的DB连接信息来进行。

作为本博客的一部分,我们将使用命令行参数。

  1. 首先,我们需要下载CockroachDB linux二进制文件。 这将使我们能够使用命令行sql。
curl https://binaries.cockroachdb.com/cockroach-v21.1.9.linux-amd64.tgz | tar -xz && sudo cp -i cockroach-v21.1.9.linux-amd64/cockroach /usr/local/bin/
  1. 第二,下载证书以安全地访问集群。这将用于我们要连接到数据库的时候。

粘贴从步骤1.4复制的CA证书

例子。

curl --create-dirs -o $HOME/.postgresql/root.crt -O https://cockroachlabs.cloud/clusters/ff666371-a7d2-4e24-abd4-d5da3d767a05/cert
  1. 现在,使用从步骤1.4复制的命令行连接到数据库。 结果将显示sql命令行提示。 该数据库将是 "defaultdb"。 我们将在下面为我们的应用程序创建一个单独的数据库。

例子。

cockroach sql --url 'postgresql://{DB_USER_NAME}:{DB_PASSWORD}@free-tier.gcp-us-central1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt&options=--cluster%3Dvisual-rec-3713'
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
# Client version: CockroachDB CCL v21.1.7 (x86_64-apple-darwin19, built 2021/08/09 17:58:36, go1.15.14)
# Server version: CockroachDB CCL v21.1.6 (x86_64-unknown-linux-gnu, built 2021/07/20 15:30:39, go1.15.11)

warning: server version older than client! proceed with caution; some features may not be available.

# Cluster ID: c0854300-2c35-44b4-a7d1-2af71acd3e4c
#
# Enter \? for a brief introduction.
#
jeff@free-tier.gcp-us-central1.cockroachlabs.cloud:26257/defaultdb>
  1. 使用熟悉的ANSI SQL而不需要学习新的语言,使得使用CockroachDB Serverless变得快速而简单。

让我们来创建我们的应用数据库。我们将把这个数据库命名为visual_recommendations_store。

语法很简单。CREATE DATABASE content_identification_store;

jeff@free-tier.gcp-us-central1.cockroachlabs.cloud:26257/defaultdb> create database content_identification;
CREATE DATABASE

Time: 73ms total (execution 14ms / network 59ms)
  1. 现在我们已经创建了我们的数据库,我们将需要创建将被我们的应用程序使用的表。

运行下面的sql语句来创建应用程序所需的数据库表。

create table content_identification_store.Labels(
  run_time timestamp, 
  filename varchar(150), 
  description varchar(150), 
  score decimal(10, 10)
);
create table content_identification_store.click_events (
  id UUID NOT NULL DEFAULT gen_random_uuid(), 
  action_time timestamp
);
  1. 退出交互式SQL shell,但要输入 "退出 "或 "退出"。
  2. 通过执行以下命令安装Node.js和Express。

注意:本节中的命令可能会产生一个 "WARN "消息。 为了这个代码实验的目的,可以继续进行,没有问题。

sudo apt-get update

sudo apt-get install -y nodejs

sudo apt-get install npm

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -

sudo apt-get install -y build-essential

npm install nconf

npm install express --save

  1. 安装Node.js的PostgreSQL扩展。 CockroachDB支持PostgreSQL有线协议和大部分PostgreSQL语法。这意味着现有的建立在PostgreSQL上的应用程序通常可以迁移到CockroachDB而不需要改变应用程序代码。

npm install pg

npm install --save @google-cloud/vision

npm install --save @google-cloud/storage

gcloud services enable vision.googleapis.com

  1. 现在我们将为你的项目创建一个有名字的GCS桶。 将[bucketname]替换为你的独特名称。

注意:GCS桶必须有一个全球唯一的名字才能被接受。

gsutil mb gs://[bucketname]

gsutil defacl set public-read gs://[bucketname]

  1. 让我们切换回控制台,导航到我们新的谷歌云存储桶,在搜索查询中输入 "存储 "并选择建议。 请验证你的新存储桶是否存在并选择它。

  2. 选定后,你可以拖放几张戴着医院面具的人的图片样本,让我们的演示服务器进行处理。

注意:选择多个图像。确保你至少有一张戴面具的人的图像和一张不戴面具的人的图像。

  1. 切换回你的SSH窗口,让我们为我们的应用代码创建一个文件夹需求,命名为。"nodejs-express-cockroach "和一个子文件夹 "public"。

mkdir -p nodejs-express-cockroach/public

  1. 改变目录到这个文件夹。

cd nodejs-express-cockroach

  1. 准备应用程序
  2. 用以下命令初始化package.json文件。

npm init

设置一个新的node项目。你可以按回车键接受默认设置,但当你到了入口处,输入 "server.js" 。

Setup a new node project

在提示时输入 "是",然后按回车键

  1. 为我们的服务器改变目录到 "public "文件夹,并选择它,输入以下命令。

cd public

  1. 让我们使用以下命令创建客户端文件,并将以下脚本内容复制到编辑器中。使用Ctrl + X保存该文件。

nano client.js

console.log('Client-side code running');
 
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
 console.log('Vision API Trigger button  was clicked');
 
 fetch('/clicked', {method: 'POST'})
   .then(function(response) {
     if(response.ok) {
       console.log('Label was recorded');
       return;
     }
     throw new Error('Request failed.');
   })
   .catch(function(error) {
     console.log(error);
   });
});
 
setInterval(function() {
 fetch('/clicks', {method: 'GET'})
   .then(function(response) {
     if(response.ok) return response.json();
     throw new Error('Request failed.');
   })
   .then(function(data) {
     document.getElementById('counter').innerHTML = `Number of total files processed ${data.length}`;
   })
   .catch(function(error) {
     console.log(error);
   });
}, 1000);
  1. 让我们使用下面的命令来创建Web服务器主页,并将下面的脚本内容输入编辑器。使用Ctrl + X保存文件。

nano index.html




    Using Google Machine Learning and CockroachDB to build a simple Image Recognition Engine for enhanced Safety and Awareness



 DEMO: Using Google Machine Learning and CockroachDB to build a simple Image Recognition Engine for Enhanced Safety and Awareness    
    
    Trigger batch Vision API job!
  
  
      

注意:请看下面代码中的高亮部分。这是你需要输入之前创建的GCS桶的名称和你的连接字符串的地方。不要忘记用你的数据库用户名和密码来编辑你的连接字符串。

需要更新的三个变量是。

  1. 你的CockroachDB Serverless的连接字符串需要更新以反映证书文件的绝对路径。

    a.运行以下命令以获得变量$HOME的输出。

echo $HOME

命令输出应该显示如下。

echo $HOME
/home/bob

b.从步骤1.4复制的连接字符串,需要更新以改变*'$HOME'*变量并反映步骤1a中的命令输出。

例子。 该连接字符串将被用于下面的代码server.js中。

'postgresql://bob:bobspassword@free-tier.gcp-us-central1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=/home/bob/.postgresql/root.crt&options=--cluster%3Dvisual-rec-3713';
  1. gcpbucket - 这是你创建的用于存储图片的桶。
  2. connectionString - 更新你在创建CockroachDB无服务器集群时提供的数据库连接字符串。 最终的连接字符串格式应该与上述步骤1.b相似。

nano server.js

console.log('NOTICE: Server-side code running');
const express = require('express');
const app = express();
const async = require('async');
const { Client } = require("pg");
////#####################
//User entered values: gcp bucket and CockroachCloud connection string. 
// the certificate root.crt needs to be local to the system running server.js
const gcpbucket = 'gs://[INSERT YOUR BUCKET STRING]';
const connectionString ='[INSERT YOUR CONNECTION STRING]';
const PORT = 8080;
//End user defined values
////#####################
var strOutput;
var strOutput2;
var strOutput3;
// serve files from the public directory
app.use("/", express.static('../public/'));
 
const CRDB_client = new Client({
 connectionString: connectionString
});
 
// Connect to database
CRDB_client.connect(function(err,database) {
 if(err) {
   return console.log(`ERROR: Connecting to your CockroachCloud Instance: ${err}`)
 }
   console.log("NOTICE: Successfully connected to the CockroachCloud Instance.");
   db = database;
  
// start the express web server listening on 8080
   console.log('NOTICE: Starting the express server on port: ' + PORT );
   app.listen(PORT, (err) => {
   if (err) console.log('ERROR: Unable to start the express web server.')
   console.log('NOTICE: Express web server listening on port: ' + PORT);
   console.log('NOTICE: Input GCP bucket is set to: ' + gcpbucket);
   });
 });
//
// serve the homepage
app.get('/', (req, res) => {
console.log('NOTICE: Serve the homepage.');
res.sendFile(__dirname + '/index.html');
});
 
 // add a document to the DB recording the click event
app.post('/clicked', (err, req, res) => {
 listFiles(gcpbucket);
console.log('NOTICE: Recording the click event.');
  const query = CRDB_client.query(new Client.Query("INSERT INTO content_identification_store.click_events(action_time) values (current_timestamp)"));
});
 
// get the click data from the database
app.get('/clicks', (req, res) => {
 console.log('NOTICE: Get the click data from the database.');
 
   const query = CRDB_client.query(new Client.Query("SELECT count(*) AS CLICK_COUNT FROM content_identification_store.click_events;"));
   query.on('row', (row) => {
       console.log("NOTICE: Number of visits", row);
   })
   query.on('ERROR:', (res) => {
      console.log(res);
   });
});
 
async function detectFulltext(fileName) {
 
// Imports the Google Cloud client library
const vision = require('@google-cloud/vision');
 
// Creates a client
const client = new vision.ImageAnnotatorClient();
 
// Performs label detection on the image file
 const [result] = await client.labelDetection(fileName);
 const labels = result.labelAnnotations;
 console.log('NOTICE: Evaluating Image: ' , fileName);
 strOutput = fileName + "  " + '\n' ;
 
 labels.forEach(label => {
 console.log(label.description);
 console.log(label.score);
  const query = CRDB_client.query(new Client.Query("INSERT INTO content_identification_store.labels(run_time, filename, description, score) values (current_timestamp, $1,$2,$3)",[fileName,label.description,label.score]));
 strOutput = strOutput + label.description + "  " + label.score + "  " + '\n';
 });
 
  const click = {visionAPIResult: strOutput};
  console.log(click);
 
}
 
async function listFiles(bucketName) {
// Imports the Google Cloud client library
 console.log('NOTICE: Getting File List.');
const {Storage} = require('@google-cloud/storage');
 
// Creates a client
const storage = new Storage();
 
// Lists files in the bucket
const [files] = await storage.bucket(bucketName).getFiles();
console.log('NOTICE: Starting Image Classification Process');
files.forEach(file => {
// Performs label detection on the image file
var  fileName = file.name;
 detectFulltext(bucketName + '/'  + fileName);
});
}
  1. 运行我们的应用程序。从nodejs-express-cockroach/public目录运行server.js

node server.js

第5步:从任何互联网客户终端启动批处理过程

1. 切换回控制台视图,查看 "Compute Engine "下的 "VM Instances"。 我们的外部IP地址就列在我们的实例旁边。

2. 2.使用支持网络的客户端终端,使用上一步中的外部URL访问你的新应用程序,并指定8080端口。 你应该看到一个与此类似的网页。

1. 在监控你的SSH控制台窗口时,点击 "触发批量Vision API工作 "按钮,启动我们的工作。 如果正确的话,你应该在几秒钟内看到大量的结果,因为它在你的GCS桶中梳理图像。 下面是一个完成后的例子。

注意:命令行的结果显示了它目前正在处理的图像(文件名)和这个雇员戴口罩的可能性(个人防护装备(PPE))。 在下面的例子中,概率是74%,这是一个好的结果。

2. 让我们切换到我们的蟑螂数据库并验证我们的结果。

CockroachDB带有一个内置的客户端,可以从交互式shell或直接从命令行执行SQL语句。

启动交互式SQL shell。

cockroach sql --url ‘’

从命令行执行SQL。

cockroach sql --url--execute=""

比如说

在下面的查询中,我们要返回描述为'个人防护设备'的数据。 个人防护设备 "是对面罩的描述。

让我们回顾一下Vision API过程的输出。 现在我们将针对我们的数据库运行一个简单的SQL查询来验证数据。 该查询将返回 "标签 "表中的所有数据。

SELECT * 
  FROM content_identification_store.labels 
 WHERE description ='Personal protective equipment';

在命令行中执行SQL。

cockroach sql --url 'postgresql://jeff:thisisademo1!@free-tier.gcp-us-central1.cockroachlabs.
cloud:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt&options=--cluster%3Dcarlson-free-tier-3709' --execute "SELECT * FROM content_identification_store.labels WHERE description ='Personal protective equipment';"

查询输出。

本文中利用的技术。

谷歌视觉API

使用预先训练好的视觉API模型来检测情绪,理解文本,以及更多。

检测多个物体并进行分类,包括每个物体在图像中的位置。了解更多关于使用Vision APIAutoML Vision进行物体检测的信息。

谷歌云存储

为各种规模的公司提供Blob对象存储。存储任何数量的数据。只要你愿意,就可以经常检索它。

CockroachDB无服务器

CockroachDB Serverless是CockroachDB的一个无服务器、免费启动的部署。它在云端以无操作性的SQL API形式提供,为你的应用提供了弹性扩展,为你的用户提供了低延迟的不间断数据访问。

CockroachDB从一开始就被设计成一个无共享的分布式SQL数据库。它保证了交易之间的可序列化隔离,完全符合ACID标准。

构建你的下一个突破性应用,而不必担心数据库连接和复杂的查询结构。