szjuliet 发表于 2019-8-12 20:36:46

虚谷号体验(五)人工智能案例体验:动植物识别

本帖最后由 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,百度图像识别











DFHy4hWhYyr 发表于 2019-8-16 08:31:36

学习了

gada888 发表于 2019-9-15 07:34:42

用python,挺先进的
页: [1]
查看完整版本: 虚谷号体验(五)人工智能案例体验:动植物识别