虚谷号体验(五)人工智能案例体验:动植物识别
本帖最后由 szjuliet 于 2019-8-13 13:53 编辑虚谷号体验(一)开箱及基本功能体验
虚谷号体验(二) 安装远程桌面及蓝牙设备
虚谷号体验(三) 主机模式体验
虚谷号体验(四)人工智能案例体验:文字识别
虚谷号体验(五)人工智能案例体验:动植物识别
虚谷号体验(六)人工智能案例体验:人脸识别
摄像头获取图像来识别动物还是植物,并依据匹配度从高到底输出五种动植物名称
演示视频如下:
https://v.qq.com/x/page/t0912uw5lyh.html
本贴依照虚谷号体验文档记录
虚谷号技术文档中动物和植物的识别是分开的,但是体验案例动植物识别是在一个程序里进行识别的,由于体验文档是PDF文件,里面的python代码缩进全部丢失,因此对代码进行了校正并添加了部分注释,修改了个别bug和注释。
[*]条件判断的条件有错。函数的返回值是"error","error_msg"是识别次数超过限制才会返回的值:
[*]Waiting和第一行的score显示发生重叠:
原因如下:
[*]还有一个问题。刚开始脚本可以正常识别,但是调试过次几次就不再反应,而animal.py和plant.py都正常,怀疑是免费识别的次数超过了每日上限500次,调试后发现果然如此。重新申请了API_KEY和SECRET_KEY,更新到程序中,重新运行后正常。
完整代码如下(其中的API_KEY和SECRET_KEY可以自己申请,也可以用体验文档中的,注意有免费次数的上限):
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Date of establishment: November 27, 2018
@author: zhangzd
"""
import cv2# 导入opencv库
import requests# 导入requests 模块
import json# 导入json 模块
import threading# 导入threading 模块
import time# 导入时间模块
import base64# 导入base64 模块
import numpy as np# 导入numpy 库
from PIL import Image, ImageDraw, ImageFont# 导入PIL 模块
# 定义sccess_token 变量
# access_token = "24.81acc2d9a6d24ef7d68f3c50e758b5e9.2592000.1550214272.282335-14971110"
access_token = "" #初始值为空,根据API_KEY和SECRET_KEY获取
# API_KEY = "3aLzdywTatbd0G2KiTyf0xpB"# 定义API_KEY 变量
API_KEY = ""# 填入自己的API_KEY
# SECRET_KEY = "kHcn44C866AXer6XE2BInIDe2m5iuqNh"# 定义SECRET_KEY 变量
SECRET_KEY = "" #填入自己的SECRET_KEY
frame = None# 定义frame 变量
now_time = 0# 定义now_time 变量
animal_info = None# 定义animal_info 变量,保存动物信息
plant_info = None# 定义plant_info 变量,保存植物信息
def cvimg_to_b64(img):
"""
图片转换函数,将二进制图片转换为base64加密格式
"""
try:
image = cv2.imencode('.jpg', img)# 将图片格式转换(编码)成流数据,赋值到内存缓存中
base64_data = str(base64.b64encode(image))# 将图片加密成base64格式的数据
return base64_data# 返回加密后的结果
except Exception as e:
return "error"
def get_ai_access_token():
"""
获取百度开发平台ai_access_token值
"""
url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=" + \
"client_credentials&client_id=%s&client_secret=%s" % (
API_KEY, SECRET_KEY)
try:
response = requests.get(url)
res_text = response.text
res_json = json.loads(res_text)
return str(res_json["access_token"])
except Exception:
return "error"
def request_post(url, data):
"""
将图片信息上传到百度AI平台进行识别
"""
try:
response = requests.post(url, data=data)# 将图片信息上传到AI平台并并获取响应
res_text = response.content.decode("utf-8")# 获取响应后的结果并将结果转化为字符串格式
res_json = json.loads(res_text)# 将字符串转化为json 格式
return res_json# 返回json 数据
except Exception:
return "error"
def get_animal(img64):
"""
将图片进行动物识别
"""
url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/animal"
url = url + "?access_token=" + access_token
data = {
"image": img64, "type": 'animal'
}
return request_post(url, data)# 返回识别结果的Json数据
def get_plant(img64):
"""
将图片进行植物识别
"""
url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/plant"
url = url + "?access_token=" + access_token
data = {
"image": img64, "type": 'plant'
}
return request_post(url, data)# 返回识别结果的Json数据
def post_request(frame, nt):
"""
判断识别的是动物还是植物,并提取有效数据
"""
if time.time() - nt > 3:# 判断时间差是否大于3
global now_time# 声明now_time 是全局变量
now_time = time.time()# 给now_time 重新赋值为当前秒数
img64 = cvimg_to_b64(frame)# 调用cvimg_to_b64 函数将图片转换为base64格式
res = get_animal(img64)# 调用get_animal 函数,进行动物识别,并返回识别结果的Json值
global animal_info# 声明animal_info 是全局变量
global plant_info# 声明plant_info 是全局变量
if "error" not in res:# 判断识别是否出错(体验文档中此处应error_msg,有错)
if len(res["result"]) > 1:# 如果result的长度>1,说明在动物识别中有返回结果,识别到的是动物
plant_info = None# 如果是动物就将植物信息赋值为None
animal_info = res["result"]# 将识别出来的结果赋值给animal_info
return# 退出函数
elif len(res["result"]) == 1:# 在动物识别中返回结果为1,说明不是动物
animal_info = None# 如果不是动物就将动物信息赋值为None
res = get_plant(img64)# 调用get_plant 函数,对图像进行植物识别
if "error" not in res:# 判断识别是否出错(体验文档中此处应error_msg,有错)
if len(res["result"]) > 1:# 如果result的长度>1,说明在植物识别中有返回结果,识别到的是植物
plant_info = res["result"]# 将识别出来的结果赋值给plant_info
return# 退出函数
else:
plant_info = None# 如果result的长度不大于1,说明不是植物,将植物信息赋值为None
def put_Text(cvimg, text, location, size=30):
"""
将动植物信息显示在屏幕上
"""
cvimg = Image.fromarray(cv2.cvtColor(cvimg, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(cvimg)
fontText = ImageFont.truetype(
"./simsun.ttc", size, encoding="utf-8")# 使用宋体显示结果,编码方式是utf-8
draw.text(location, text, (255, 0, 0), font=fontText)# 输出字体为红色
cvimg = cv2.cvtColor(np.array(cvimg), cv2.COLOR_RGB2BGR)
return cvimg
def check_token():
"""
检查授权令牌的有效性
"""
if int(time.time()) - 1547622271 >= 2592000:# 2592000等于30天 1547622271为2019-01-16 15:04:31,如果当前时间与上述时间的间隔大于等于30天
global access_token
token = get_ai_access_token()
if token != "error":
access_token = get_ai_access_token()
def main():
"""
程序主函数
"""
check_token()
cap = cv2.VideoCapture(0)# 创建摄像头对象
global now_time# 声明now_time 为全局变量
now_time = time.time()# 将当前时间秒数赋值给now_time
while (True):# 创建一个永久循环用于循环读取摄像头数据
ret, frame = cap.read()# 从摄像头中读取一张图片
if ret == True:# 判断是否读取成功
# 创建一个1280x800 的窗口
frame1 = cv2.resize(frame, (1280, 800), interpolation=cv2.INTER_LINEAR)
# 创建一个线程用于处理读取到的图片
t = threading.Thread(target=post_request, args=(
frame, now_time,), name='POST_REQUEST')
t.start()# 启动这个线程
if animal_info == None and plant_info == None:# 判断动植物信息是否都为None
# 如果没有识别到动植物,则在窗口左上方显示Waiting
frame1 = put_Text(frame1, "Waiting...", (50, 50))
cv2.moveWindow("frame1", 100, 100)
else:
if animal_info != None:# 判断动物信息是否为None
print(animal_info)# 如果识别到动物,则在终端显示动物信息
try:
# 在frame1窗口中写字
for i in range(5):# 按匹配度从高到低显示五种可能的动物信息(匹配度和名字)
frame1 = put_Text(frame1, str(
animal_info["score"][:4]), (150, (i + 1) * 70 + 50))# 输出匹配度
frame1 = put_Text(frame1, str(
animal_info["name"]), (320, (i + 1) * 70 + 50))# 输出动物名字
except Exception:
pass
else:
print(plant_info)# 识别到的是植物,打印植物信息
try:
for i in range(5):# 按匹配度从高到低显示五种可能植物信息(匹配度和名字)
frame1 = put_Text(frame1, str(plant_info["score"])[
:4], (150, (i + 1) * 70 + 50))# 输出匹配度
frame1 = put_Text(frame1, str(
plant_info["name"]), (320, (i + 1) * 70 + 50))# 输出植物名字
except Exception:
pass
try:
for i in range(5):# 成功读取图片,但既不是动物也不是植物则连续输出5行,score:和name:,后面内容为空
frame1 = put_Text(frame1, "score:",
(50, (i + 1) * 70 + 50))
frame1 = put_Text(
frame1, "name:", (250, (i + 1) * 70 + 50))
except Exception:
pass
cv2.imshow('Magic Image', frame1)# 新建窗口的标题是Magic Image
if cv2.waitKey(1) & 0xFF == ord('q'):# 如果检测到键盘输入了“q”,则退出识别程序
break
cap.release()# 释放摄像头
cv2.destroyAllWindows()# 关闭所有窗口
if __name__ == "__main__":
main()
1. 在电脑上使用Python编辑器将上述代码编辑并保存
2. 设备连接
虚谷号连接高清电视、摄像头,通电
3. 将程序上传(复制)到虚谷号中
方法一:U盘方法
将虚谷号接到电脑,先用U盘模式把程序复制到虚谷号中,再切换到主机模式运行
方法二:主机方法
使用sftp软件如FileZilla将程序上传到虚谷号相应目录下
因为远程传输图像延迟比较严重,所以使用外接显示器来进行体验。程序在电脑上修改,在虚谷上测试,脚本通过FileZilla传输到虚谷号上(方法见体验四)。这样非常的有效率。
4. 在文件管理器中进入Desktop目录,运行LX终端
https://mc.dfrobot.com.cn/data/attachment/forum/201908/11/025114otz7xnwo3whp2paz.png
5. 输入命令python3 *.py(文件名自己定义),在当前目录下运行动植物识别脚本。识别效果参见前面的视频
参考资料:
https://www.jb51.net/article/137562.htm,设置窗口的起始位置
命令是cv2.moveWindow("frame1", 100, 100)
但执行时感觉并没有起作用,窗口还是在原来的位置
http://www.matools.com/timestamp,在线时间转换(毫秒转换为日期)
https://ai.baidu.com/tech/imagerecognition,百度图像识别
学习了 用python,挺先进的
页:
[1]