第三期 【百度大脑新品体验】 通用物体与场景识别
busyboxs 发布于2019-06 浏览:5389 回复:3
2
收藏
最后编辑于2022-04

最近刚学习了QT开发,本文尝试将QT界面和百度的API结合使用,将通用物体与场景识别进行界面化。

API 介绍

通用物体与场景识别支持超过 10 万类常见物体和场景识别,接口返回图片内 1 个或多个物体的名称,并可获取百科信息。适用于图像或视频内容分析、拍照识图等业务场景。

支持识别动物、植物、商品、建筑、风景、动漫、食材、公众人物等10万个常见物体及场景,接口返回大类及细分类的名称结果。

接口描述

该请求用于通用物体及场景识别,即对于输入的一张图片(可正常解码,且长宽比适宜),输出图片中的多个物体及场景标签。

请求说明

请求 url

https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general

请求参数

返回说明

返回参数

返回实例

{
	"log_id": "1418961236584752678",
	"result_num": 5,
	"result": [
		{
			"score": 0.764778,
			"root": "商品-电脑办公",
			"baike_info": {
				"baike_url": "http://baike.baidu.com/item/%E7%AC%94%E8%AE%B0%E6%9C%AC%E7%94%B5%E8%84%91/213561",
				"image_url": "http://imgsrc.baidu.com/baike/pic/item/63d0f703918fa0ec125a44b4269759ee3c6ddbed.jpg",
				"description": "笔记本电脑(NoteBook Computer,简称为:NoteBook),亦称笔记型、手提或膝上电脑(英语:Laptop Computer,简称为Laptop),是一种小型、可方便携带的个人电脑。笔记本电脑的重量通常重1-3千克。其发展趋势是体积越来越小,重量越来越轻,而功能却越来越强大。像Netbook,也就是俗称的上网本。笔记本电脑跟PC的主要区别在于其便携带性。"
			},
			"keyword": "笔记本电脑"
		},
		{
			"score": 0.526428,
			"root": "商品-电脑办公",
			"keyword": "电脑"
		},
		{
			"score": 0.354558,
			"root": "商品-电脑办公",
			"keyword": "笔记本"
		},
		{
			"score": 0.181704,
			"root": "商品-数码产品",
			"keyword": "台式电脑"
		},
		{
			"score": 0.008778,
			"root": "商品-数码产品",
			"keyword": "平板电脑"
		}
	]
}

接口调用实现

获取 access_token

要调用百度 AI API 的接口,需要创建对应的应用并获取 access_token.

创建应用

首先登陆百度 AI 控制台( https://console.bce.baidu.com/?fromai=1#/aip/overview ),然后点击右侧导航栏里面的 “图像识别”。

然后点击创建应用

填好“应用名称”和“应用描述”后点击“创建应用”。

创建好应用之后,进入“应用列表”,就能看到应用的相关信息,我们需要的是 API Key 和 Secret Key。

获取 access token

通过 API Key 和 Secret Key 获取的 access_token。更多关于 access_token 的获取方法参考 http://ai.baidu.com/docs#/Auth/top 。

下面代码是 python3 获取 access_token 的代码

import requests

def get_token_key():
    # client_id 为官网获取的AK, client_secret 为官网获取的SK
    client_id = '【百度云应用的AK】'
    client_secret = '【百度云应用的SK】'
    url = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials' \
        f'&client_id={client_id}&client_secret={client_secret}'
    headers = {'Content-Type': 'application/json; charset=UTF-8'}
    res = requests.post(url, headers=headers)
    token_content = res.json()
    assert "error" not in token_content, f"{token_content['error_description']}"
    token_key = token_content['access_token']
    return token_key

调用通用物体与场景识别接口

通用物体与场景识别接口类及调用的 python3 代码实现如下:

import requests
from utils import pic_base64, draw_zh, get_token_key

class General(object):

    def __init__(self, image_base64, token_key, baike_num=0):
        self.image_base64 = image_base64
        self.token_key = token_key
        self.baike_num = baike_num
        self.data = self.get_data()

    def get_data(self):
        request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general"
        params_d = dict()
        params_d['image'] = str(self.image_base64, encoding='utf-8')
        params_d['baike_num'] = self.baike_num
        access_token = self.token_key
        request_url = request_url + "?access_token=" + access_token
        res = requests.post(url=request_url,
                            data=params_d,
                            headers={'Content-Type': 'application/x-www-form-urlencoded'})
        data = res.json()
        assert 'error_code' not in data, f'Error: {data["error_msg"]}'
        return data

    def get_result_num(self):
        return self.data['result_num']

    def get_log_id(self):
        return self.data['log_id']

    def get_result(self):
        return self.data['result']

    def parse_data(self):
        result_num = self.get_result_num()
        result = self.get_result()
        res = list()
        for i in range(result_num):
            if i < self.baike_num:
                res.append((result[i]['keyword'], result[i]['score'], result[i]['baike_info']))
            else:
                res.append((result[i]['keyword'], result[i]['score'], None))
        return res
        
        
def detect(image_name, color):
    token_key = 'your token key'
    # image_name = 'images/001.png'
    image = cv2.imread(image_name)
    image_base64 = pic_base64(image_name)
    general = General(image_base64, token_key, 1)
    obj = ObjectDetect(image_base64, token_key)
    general_data = general.parse_data()
    bbox = obj.parse_data()
    name = general_data[0][0]
    score = general_data[0][1]
    baike = general_data[0][2]
    image = obj.draw_bbox(image, color)
    # draw_zh(image, name, bbox[0], bbox[1] - 16, color)
    cv2.cvtColor(image, cv2.COLOR_BGR2RGB, image)
    return image, name, score, baike

QT 实现界面展示

首先使用 qtdesigner 设计好界面,同时创建好按钮的槽函数,界面的设计如下图所示:

然后将 .ui 文件通过 PyUIC 转换为 .py 文件,并在生成的 .py 文件中添加槽函数的实现,具体的代码如下:

”上传图像“按钮对应的代码

def on_upload_clicked(self):
    self.groupBox.setVisible(False)
    self.pushButton.setEnabled(False)
    fname = QtWidgets.QFileDialog.getOpenFileName(QtWidgets.QWidget(), 'Open file', self.file_path,
                                                  'Image file (*.jpg *.gif *.png)')
    if fname[0] != '':
        self.file_path = os.path.dirname(fname[0])
        self.imagePath = fname[0]
    pixmap = QtGui.QPixmap(self.imagePath)
    height, width = pixmap.height(), pixmap.width()
    if width > height:
        pixmapscared = pixmap.scaledToWidth(800)
    else:
        pixmapscared = pixmap.scaledToHeight(600)
    self.label_img.setPixmap(pixmapscared)
    # self.label_img.setScaledContents(True)
    self.detect.setEnabled(True)
    self.pushButton_2.setEnabled(True)

 “图像识别”按钮对应的代码 ,该代码实现了图像通用物体与场景识别。

def on_recognition_clicked(self):
    self.isbaike.setVisible(True)
    str_warm = '未查到相关信息'
    img, name, score, baike = detect(self.imagePath, self.color)
    pixmap = QtGui.QPixmap(self.imagePath)
    height, width = pixmap.height(), pixmap.width()
    if width > height:
        pixmapscared = pixmap.scaledToWidth(800)
    else:
        pixmapscared = pixmap.scaledToHeight(600)
    self.label_img.setPixmap(pixmapscared)
    self.groupBox.setVisible(True)
    # self.label_img.setScaledContents(True)
    self.cls.setText(name)
    self.score.setText(str(score))
    self.detect.setEnabled(True)
    if baike:
        self.description.setText(baike['description'])
        self.baikeurl.setText(baike['baike_url'])
        self.picurl.setText(baike['image_url'])
    else:
        self.description.setText(str_warm)
        self.baikeurl.setText(str_warm)
        self.picurl.setText(str_warm)

 “主体检测”按钮对应的代码 ,该代码实现了图像主体检测

def on_detect_clicked(self):
    self.groupBox.setVisible(False)
    self.groupBox_2.setVisible(False)
    self.pushButton_2.setEnabled(False)
    self.isbaike.setVisible(False)
    self.cls.setText(" ")
    self.score.setText(" ")
    img, name, score, _ = detect(self.imagePath, self.color)
    height, width, bytesPerComponent = img.shape
    bytesPerLine = bytesPerComponent * width
    Qimg = QtGui.QImage(img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
    pixmap = QtGui.QPixmap.fromImage(Qimg)
    if width > height:
        pixmapscared = pixmap.scaledToWidth(800)
    else:
        pixmapscared = pixmap.scaledToHeight(600)
    self.label_img.setPixmap(pixmapscared)
    # self.label_img.setScaledContents(True)
    self.detect.setEnabled(False)
    self.pushButton.setEnabled(True)

 “边框颜色”按钮对应的代码, 该代码实现了改变主体检测中主体边框的颜色

def on_choose_color(self):
    self.groupBox.setVisible(False)
    color = QtWidgets.QColorDialog.getColor()
    self.color = color.getRgb()[:3]
    from detectimage import detect
    img, name, score, _ = detect(self.imagePath, self.color)
    height, width, bytesPerComponent = img.shape
    bytesPerLine = bytesPerComponent * width
    Qimg = QtGui.QImage(img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
    pixmap = QtGui.QPixmap.fromImage(Qimg)
    if width > height:
        pixmapscared = pixmap.scaledToWidth(800)
    else:
        pixmapscared = pixmap.scaledToHeight(600)
    self.label_img.setPixmap(pixmapscared)
    # self.label_img.setScaledContents(True)
    self.cls.setText(" ")
    self.score.setText(" ")

实例运行效果图

代码打包

可以使用 pyinstaller 将代码打包

首先安装 pyinstaller

pip install pyinstaller

 然后将代码打包

pyinstaller ruun.py

最终会在主文件下生成 dist 文件夹和 build 文件夹,可执行文件在 dist 文件夹下。

源码地址

  • 源代码:https://github.com/busyboxs/qt-baidu-image-recognizition
  • 可执行文件链接:https://pan.baidu.com/s/11J09VeWzl2W2pcNeHz0Ovw 提取码:tm9i

可执行文件路径 ~/BaiDuDetect/dist/ruun/ruun.exe

收藏
点赞
2
个赞
共3条回复 最后由用户已被禁言回复于2022-04
#4wangwei8638回复于2019-10

不错

0
#3liguanghui2588回复于2019-07

体验很好

0
#2尼基塔007不错回复于2019-07

也用QT来测试啊

0
TOP
切换版块