查看: 469|回复: 7

[项目分享] 虚谷号体验(四)人工智能案例体验:文字识别

[复制链接]
本帖最后由 szjuliet 于 2019-8-21 11:09 编辑

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

当当当,最激动人心的时候到了,开始人工智能案例的体验了!!
本贴是依照虚谷号提供的《数字识别操作文档》进行体验的记录。

人工智能案例体验心得
体验过程异乎寻常的顺利。虚谷号在运行人工智能程序时还是非常稳定的,整个操作也非常顺畅,难度不大,很好上手。适合学生进行人工智能学习体验。

下面是演示视频

识别结果的音频文件见附件

1.设备连接:
我使用的是远程方式,所以只需要将虚谷号连接摄像头(罗技C170),并将虚谷号通电:
31AI_plug.png
注:因为识别时有语音输出,远程时语音无法在本地播出,所以外接了高清电视来输出语音。

2. 复制程序:

(也可直接在当前目录下运行脚本,无需复制到桌面)
运行桌面上的“134MB卷”打开文件处理器,进入图示目录下,将图中两个文件直接拖到桌面。一个是识别脚本程序,一个是字体文件,字体文件定义显示识别结果的字体。
27copyFiles.png

201908110842276228.png

3. 在文件管理器中进入Desktop目录,运行LX终端
28LX1.png

4. 输入命令python3 words.py,在当前目录下运行文字识别脚本

28LX2.png

5. 很快会新建一个窗口,标题为Magic Image,用于显示采集的摄像头图像。
29MagicImage.png


6. 输出结果。
识别速度还是比较快的,当识别成功后,会将识别结果显示在MagicImage窗口上方并朗读出来,同时LX终端会输出显示结果,桌面也会生成一个audio.mp3文件,是识别结果的语音文件。支持大段文字识别,效果还是比较令人满意的。
30result.png

30result1.png

26character_recog.png


程序代码
[Python] 纯文本查看 复制代码
#!/usr/bin/env python3# -*- coding: utf-8 -*-
"""
Date of establishment: November 27, 2018

@author: zhangzd
"""

import cv2  # 导入cv2 模块
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 模块
from aip import AipSpeech
import pygame
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import os
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

access_token = ""  # 定义sccess_token 变量
AppID = "15126848"
API_KEY = "BPaS8KCk1B6Io9EqEOw1pOH3"  # 定义API_KEY 变量
SECRET_KEY = "AL3B7XOmoRZojqFivCzvxuGYDDQZ7G58"  # 定义SECRET_KEY 变量
client = AipSpeech(AppID, API_KEY, SECRET_KEY)
frame = None  # 定义frame 变量
now_time = 0  # 定义now_time 变量
number = None  # 定义number 变量
audio_file = 'auido.mp3'
data = None

def save_audio(number):
    result  = client.synthesis(number, 'zh', 1, {
        'vol': 5,
        })
    if not isinstance(result, dict):
        with open(audio_file, 'wb') as f:
            f.write(result)
        os.system("play *mp3") 


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():
"""
获取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 get_number(img64):
    url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
    url = url + "?access_token=" + access_token
    data = {
        "image": img64, "type": 'commontext'
    }
    try:
        response = requests.post(url,data=data) #向url 地址发送请求并获取响应
        res_text = response.content.decode("utf-8") #此处与操作文档不同:res_text = response.text #获取响应后的结果并将结果转化为字符串格式
        res_json = json.loads(res_text) #将字符串转化为json 格式
        return res_json #返回json 数据
    except Exception:
        return "error"


def psyst_request(frame, nt):
    global number
    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 函数
        res = get_number(img64) #调用get_number 函数
        try:
            if res["words_result"]: #判断res 字典中是否含有words_result
                if len(res["words_result"]) == 1: #判断长度
                    number = res["words_result"][0]["words"
                else:
                #将多行内容合并成一行赋值给number
                    number = res["words_result"][0]["words"
                    for i in range(1, len(res["words_result"])):
                        number += (res["words_result"][i]["words"])
             [/i]   return
            else:
                number = None
        except:
            number = None

def put_Text(cvimg, text, location, size=50):
"""
将字符信息显示在屏幕上
"""
    cvimg = Image.fromarray(cv2.cvtColor(cvimg, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(cvimg)
    fontText = ImageFont.truetype("./simsun.ttc", size, encoding="utf-8")
    draw.text(location, text, (255,0,0), font=fontText)
    cvimg = cv2.cvtColor(np.array(cvimg), cv2.COLOR_RGB2BGR)
    return cvimg

def main():
"""
程序主函数
"""
    token = get_ai_access_token()
    if token != "error":
        global access_token
        access_token = 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: #判断是否读取成功
            frame1 = cv2.resize(frame, (1280, 800), interpolation=cv2.INTER_LINEAR) #创建一个1280x800 的窗口
            t = threading.Thread(target=psyst_request, args=(frame, now_time,), name='PsysT_REQUEST') #创建一个线程用于处理读取到的图片
            t.start() #启动这个线程
            print(number) #打印文字信息
            #在画布上写字
            if number == None: 
                frame1 = put_Text(frame1, "Waiting...", (50, 50))
            else:
                try:
                    frame1 = put_Text(frame1, str(number), (200, 50))
                    frame1 = put_Text(frame1, "words:", (50, 50))
                except Exception:
                    pass
                global data
                if data != number:
                    p = threading.Thread(target=save_audio, args=(number,))
                    p.start()
                    data = number
            cv2.imshow('Magic Image', frame1)
        if cv2.waitKey(1) & 0xFF == ord('q'): #等待键盘输入q 后退出程序
            break
    cap.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()


注意事项:
1. 虚谷号外接显示器、摄像头等外设后会供电不足,不要将虚谷接在电脑上供电,而应直接供电,否则系统可能会启动不起来
2. 识别效果与获取的文字属性相关,如是否是印刷体、是否过于倾斜等

待解决问题:1. 远程时如果将语音输出到本地?如下设置在远程windows系统时可以正常播放声音,但是远程虚谷号声音播不出来,只能外接高清电视输出声音。
32audio_setup.png

2. 如何定位MagicImagic窗口?
MagicImage窗口打开后会靠近屏幕右下方的位置,窗口显示不完全,必须向左上方拖动才行。但是当识别程序打开后,系统响应速度会非常慢,操作起来很困难。可否在程序中对窗口的位置进行定位。
对应语句
[Python] 纯文本查看 复制代码
frame1 = cv2.resize(frame, (1280, 800), interpolation=cv2.INTER_LINEAR) #创建一个1280x800 的窗口
要如何修改代码来定位窗口的位置,试着加进位置参数貌似都出错了。PS:
定位命令是cv2.moveWindow("filename", x, y),但是貌似不起作用








audio.zip

129.56 KB, 下载次数: 0, 下载积分: 创造力 -1

识别结果音频文件

汤果  初级技匠

发表于 2019-8-11 09:35:06

我想音视频是通过 Mini HDMI 接口输出的,所以就没法通过远程输出了吧。比如我办公室的电脑不接耳机,任务栏的喇叭上就有个叉,即使远程也是无法播放声音的。
回复 支持 反对

使用道具 举报

szjuliet  版主
 楼主|

发表于 2019-8-11 10:02:40

汤果 发表于 2019-8-11 09:35
我想音视频是通过 Mini HDMI 接口输出的,所以就没法通过远程输出了吧。比如我办公室的电脑不接耳机,任务 ...

不会哦。我学校电脑是在服务器上做的虚拟机,任何时候都是要远程的。只要设置正确,声音都是通过本地电脑的音频设备输出。

但是虚谷号在远程播放音频时,虽然两边的音量都已经开启,但是声音无法播出,除非外接一个高清电视或蓝牙音箱。没有树莓派的音频输出口还是不太方便,以前用树莓派时也没有留意,不知道树莓派是不是也存在同样的的问题。
回复 支持 反对

使用道具 举报

汤果  初级技匠

发表于 2019-8-11 10:08:03

szjuliet 发表于 2019-8-11 10:02
不会哦。我学校电脑是在服务器上做的虚拟机,任何时候都是要远程的。只要设置正确,声音都是通过本地电脑 ...

那应该是特定电脑音频驱动的问题。那我那个台式机,连剪辑软件都打不开,因为任务栏音量图标是个红色的叉。当且仅当插入耳机或音响才可以打开视频剪辑软件……所以远程的时候别指望听到声音了。。
回复 支持 反对

使用道具 举报

szjuliet  版主
 楼主|

发表于 2019-8-11 10:19:21

汤果 发表于 2019-8-11 10:08
那应该是特定电脑音频驱动的问题。那我那个台式机,连剪辑软件都打不开,因为任务栏音量图标是个红色的叉 ...

重新装一下驱动或者换个声卡
没有声音的电脑......那岂不是很痛苦
回复 支持 反对

使用道具 举报

Nplus实验室  初级技师

发表于 2019-8-12 09:59:40

点赞,学习一下
回复 支持 反对

使用道具 举报

gada888  版主

发表于 3 天前

商城里有吗
回复 支持 反对

使用道具 举报

szjuliet  版主
 楼主|

发表于 3 天前


有扩展板,没有主板
回复 支持 反对

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail