查看: 616|回复: 2

[项目分享] 虚谷号体验(五)人工智能案例体验:动植物识别

[复制链接]
本帖最后由 szjuliet 于 2019-8-13 13:53 编辑

虚谷号体验(一)开箱及基本功能体验
虚谷号体验(二) 安装远程桌面及蓝牙设备
虚谷号体验(三) 主机模式体验
虚谷号体验(四)人工智能案例体验:文字识别
虚谷号体验(五)人工智能案例体验:动植物识别
虚谷号体验(六)  人工智能案例体验:人脸识别

摄像头获取图像来识别动物还是植物,并依据匹配度从高到底输出五种动植物名称

演示视频如下:


本贴依照虚谷号体验文档记录

虚谷号技术文档中动物和植物的识别是分开的,但是体验案例动植物识别是在一个程序里进行识别的,由于体验文档是PDF文件,里面的python代码缩进全部丢失,因此对代码进行了校正并添加了部分注释,修改了个别bug和注释。
  • 条件判断的条件有错。函数的返回值是"error","error_msg"是识别次数超过限制才会返回的值:

01error.png

01error1.png

  • Waiting和第一行的score显示发生重叠:

01error5.png

原因如下:
01error2.png

  • 还有一个问题。刚开始脚本可以正常识别,但是调试过次几次就不再反应,而animal.py和plant.py都正常,怀疑是免费识别的次数超过了每日上限500次,调试后发现果然如此。重新申请了API_KEY和SECRET_KEY,更新到程序中,重新运行后正常。

03limit.png


完整代码如下(其中的API_KEY和SECRET_KEY可以自己申请,也可以用体验文档中的,注意有免费次数的上限):
[Python] 纯文本查看 复制代码
#!/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)[1]  # 将图片格式转换(编码)成流数据,赋值到内存缓存中
        base64_data = str(base64.b64encode(image))[2:-1]  # 将图片加密成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. 设备连接
虚谷号连接高清电视、摄像头,通电
04connect.png

3. 将程序上传(复制)到虚谷号中
方法一:U盘方法
将虚谷号接到电脑,先用U盘模式把程序复制到虚谷号中,再切换到主机模式运行

方法二:主机方法
使用sftp软件如FileZilla将程序上传到虚谷号相应目录下
00vvb0ard_sftp1.png

00vvb0ard_sftp2.png

因为远程传输图像延迟比较严重,所以使用外接显示器来进行体验。程序在电脑上修改,在虚谷上测试,脚本通过FileZilla传输到虚谷号上(方法见体验四)。这样非常的有效率。

4. 在文件管理器中进入Desktop目录,运行LX终端


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,挺先进的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail