【ArchSummit架构师峰会】精华内容上线75%,AI大模型中台从理念到实践的探索!>>> 了解详情
写点什么

在实时音视频领域,如何基于 TensorFlow 实现图像识别

  • 2019-09-02
  • 本文字数:4351 字

    阅读完需:约 14 分钟

在实时音视频领域,如何基于 TensorFlow 实现图像识别

近两年来,Python 在众多编程语言中的热度一直稳居前五,热门程度可见一斑。 Python 拥有很活跃的社区和丰富的第三方库,Web 框架、爬虫框架、数据分析框架、机器学习框架等,开发者无需重复造轮子,可以用 Python 进行 Web 编程、网络编程,开发多媒体应用,进行数据分析,或实现图像识别等应用。其中图像识别是最热门的应用场景之一,也是与实时音视频契合度最高的应用场景之一。


本文将分享 TensorFlow 图像识别的实现。然后,我们尝试将 TensorFlow 与 Agora Python SDK 结合,来实现在实时音视频通话下的图像识别。我们利用 Agora Python SDK 来完成音视频的编解码、降噪、回声消除、低延时传输等任务,并将视频图像以 RGB 格式传输给 TensorFlow,然后我们通过 TensorFlow 来进行图像识别,将识别结果返回给客户端。


先分享一下 Demo 的识别效果。左图是对端的视频图像,右下角是我们本地的视频图像,在识别对端图像后,右侧的文本框中会显示出识别结果。注意,这个🙂贴纸只是后期 P 上去的,我们在 Demo 中还没有加入贴图的功能,如果你感兴趣,可以试着在 Demo 基础上做改进,丰富功能。



首先,我们还是要先介绍一下 TensorFlow 的图像识别原理与方法。

TensorFlow 图片及物体识别

TensorFlow 是 Google 的开源深度学习库,你可以使用这个框架以及 Python 编程语言,构建大量基于机器学习的应用程序。而且还有很多人把 TensorFlow 构建的应用程序或者其他框架,开源发布到 GitHub 上。所以我们今天主要基于 Tensorflow 学习下物体识别。


TensorFlow 提供了用于检测图片或视频中所包含物体的 API,详情点击此处。


物体检测是检测图片中所出现的全部物体并且用矩形(Anchor Box)进行标注,物体的类别可以包括多种,例如人、车、动物、路标等。举个例子了解 TensorFlow 物体检测 API 的使用方法,这里使用预训练好的 ssd_mobilenet_v1_coco 模型(Single Shot MultiBox Detector),更多可用的物体检测模型可以点击这里

加载库

# -*- coding:utf-8 -*- import numpy asnpimporttensorflow as tfimportmatplotlib.pyplot as pltfrom PIL importImage from utilsimport label_map_utilfrom utilsimport visualization_utils as vis_util
复制代码

定义部分常量

PATH_TO_CKPT = 'ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb'PATH_TO_LABELS = 'ssd_mobilenet_v1_coco_2017_11_17/mscoco_label_map.pbtxt'NUM_CLASSES = 90
复制代码

加载预训练好的模型

detection_graph = tf.Graph()with detection_graph.as_default():  od_graph_def = tf.GraphDef()  with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:    od_graph_def.ParseFromString(fid.read())    tf.import_graph_def(od_graph_def, name='')
复制代码

加载分类标签数据

label_map = label_map_util.load_labelmap(PATH_TO_LABELS) categories = label_map_util.convert_label_map_to_categories(label_map,max_num_classes=NUM_CLASSES, use_display_name=True)category_index = label_map_util.create_category_index(categories)
复制代码

将图片转化为数组,并测试图片路径

def load_image_into_numpy_array(image):  (im_width, im_height) = image.size  return np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
TEST_IMAGE_PATHS = ['test_images/image1.jpg', 'test_images/image2.jpg']
复制代码

使用模型进行物体检测

with detection_graph.as_default():  with tf.Session(graph=detection_graph) as sess:      image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')      detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')      detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')      detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')      num_detections = detection_graph.get_tensor_by_name('num_detections:0')      for image_path in TEST_IMAGE_PATHS:        image = Image.open(image_path)        image_np = load_image_into_numpy_array(image)        image_np_expanded = np.expand_dims(image_np, axis=0)        (boxes, scores, classes, num) = sess.run(          [detection_boxes, detection_scores, detection_classes, num_detections],           feed_dict={image_tensor: image_np_expanded})                vis_util.visualize_boxes_and_labels_on_image_array(image_np, np.squeeze(boxes), np.squeeze(classes).astype(np.int32), np.squeeze(scores), category_index, use_normalized_coordinates=True, line_thickness=8)        plt.figure(figsize=[12, 8])        plt.imshow(image_np)        plt.show()
复制代码


检测结果如下,第一张图片检测出了两只狗狗


实时音视频场景下 Tensorflow 物体识别

既然 Tensorflow 在静态图片的物体识别已经相对成熟,那在现实场景中,大量的实时音视频互动场景中,如何来做物体识别?我们现在基于声网实时视频的 SDK,阐述如何做物体识别。


首先我们了解视频其实就是由一帧一帧的图像组合而成,所以从这个层面来说,视频中的目标识别就是从每一帧图像中做目标识别,从这个层面上讲,二者没有本质区别。在理解这个前提的基础上,我们就可以相对简单地做实时音视频场景下 Tensorflow 物体识别。


1)读取 Agora 实时音视频,截取远端视频流的图片


def onRenderVideoFrame(uid, width, height, yStride,                            uStride, vStride, yBuffer, uBuffer, vBuffer,                            rotation, renderTimeMs, avsync_type):         # 用 isImageDetect 字段判断前一帧图像是否已完成识别,若完成置为True,执行以下代码,执行完置为false        if EventHandlerData.isImageDetect:            y_array = (ctypes.c_uint8 * (width * height)).from_address(yBuffer)            u_array = (ctypes.c_uint8 * ((width // 2) * (height // 2))).from_address(uBuffer)            v_array = (ctypes.c_uint8 * ((width // 2) * (height // 2))).from_address(vBuffer)
Y = np.frombuffer(y_array, dtype=np.uint8).reshape(height, width) U = np.frombuffer(u_array, dtype=np.uint8).reshape((height // 2, width // 2)).repeat(2, axis=0).repeat(2, axis=1) V = np.frombuffer(v_array, dtype=np.uint8).reshape((height // 2, width // 2)).repeat(2, axis=0).repeat(2, axis=1) YUV = np.dstack((Y, U, V))[:height, :width, :] # AI模型中大多数模型都是RGB格式训练,声网提供的视频回调数据源是YUV格式,我们做下格式转换 RGB = cv2.cvtColor(YUV, cv2.COLOR_YUV2RGB, 3) EventHandlerData.image = Image.fromarray(RGB) EventHandlerData.isImageDetect = False
复制代码


2)Tensorflow 对截取图片进行物体识别


class objectDetectThread(QThread):    objectSignal = pyqtSignal(str)    def __init__(self):        super().__init__()    def run(self):        detection_graph = EventHandlerData.detection_graph        with detection_graph.as_default():            with tf.Session(graph=detection_graph) as sess:                (im_width, im_height) = EventHandlerData.image.size                image_np = np.array(EventHandlerData.image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)                image_np_expanded = np.expand_dims(image_np, axis=0)                image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')                boxes = detection_graph.get_tensor_by_name('detection_boxes:0')                scores = detection_graph.get_tensor_by_name('detection_scores:0')                classes = detection_graph.get_tensor_by_name('detection_classes:0')                num_detections = detection_graph.get_tensor_by_name('num_detections:0')                (boxes, scores, classes, num_detections) = sess.run(                    [boxes, scores, classes, num_detections],                    feed_dict={image_tensor: image_np_expanded})                objectText = []                # 如果识别概率大于百分之四十,我们就在文本框内显示所识别物体                for i, c in enumerate(classes[0]):                    if scores[0][i] > 0.4                        object = EventHandlerData.category_index[int(c)]['name']                        if object not in objectText:                            objectText.append(object)                    else:                        break                self.objectSignal.emit(', '.join(objectText))                EventHandlerData.detectReady = True                # 本帧图片识别完,isImageDetect 字段置为True,再次开始读取并转换Agora远端实时音视频                EventHandlerData.isImageDetect = True
复制代码


我们已经将这个 Demo 以及 Agora Python SDK 上传至 Github,大家可以直接下载使用:Agora Python TensorFlow Demo

Agora Python TensorFlow Demo 编译指南

  • 点击下载Agora Python SDK

  • 若是 Windows,复制.pyd and .dll 文件到本项目文件夹根目录;若是 IOS,复制.so 文件到本文件夹根目录

  • 下载 Tensorflow 模型,然后把 object_detection 文件复制.到本文件夹根目录

  • 安装 Protobuf。然后运行:


 protoc object_detection/protos/*.proto --python_out=.
复制代码


  • 点击下载预先训练的模型

  • 推荐使用 ssd_mobilenet_v1_coco

  • 和 ssdlite_mobilenet_v2_coco,因为他们相对运行较快

  • 提取 frozen graph,命令行运行:


python extractGraph.py --model_file='FILE_NAME_OF_YOUR_MODEL'
复制代码


  • 最后,在 callBack.py 中修改 model name,在 demo.py 中修改 Appid,然后运行即可


请注意,这个 Demo 仅作为演示使用,从获取到远端实时视频画面,到 TensorFlow 进行识别处理,再到显示出识别效果,期间需要 2 至 4 秒。不同网络情况、设备性能、算法模型,其识别的效率也不同。感兴趣的开发者可以尝试更换自己的算法模型,来优化识别的延时。


如果 Demo 运行中遇到问题,请在 Github 直接提 issue。


作者介绍


金叶清,6 年研发运营经验,从事开发者社区领域工作近五年。曾负责华为开发者社区相关运营工作;目前就职于声网,从事开发者布道师工作。


公众号推荐:

2024 年 1 月,InfoQ 研究中心重磅发布《大语言模型综合能力测评报告 2024》,揭示了 10 个大模型在语义理解、文学创作、知识问答等领域的卓越表现。ChatGPT-4、文心一言等领先模型在编程、逻辑推理等方面展现出惊人的进步,预示着大模型将在 2024 年迎来更广泛的应用和创新。关注公众号「AI 前线」,回复「大模型报告」免费获取电子版研究报告。

AI 前线公众号
2019-09-02 11:555395

评论

发布
暂无评论
发现更多内容

容器、Docker、虚拟机,别再傻傻分不清

华为云开发者联盟

容器 虚拟化

TarsCpp 组件之 MySQL 操作

TARS基金会

c++ MySQL 数据库 微服务 TARS

「架构师训练营第 1 期」第六周作业

张国荣

OPPO安全重磅出击 剑指安全与隐私保护

OPPO安全

安全 隐私保护 个人隐私安全 OPPO安全

真爽!蚂蚁金服大牛整理SpringBoot+Cloud离线版

996小迁

架构 面试 springboot SpringCloud

积极参与数字货币等国际规则制定,塑造新的竞争优势

CECBC

疫情 经济

架构师训练营第二周

M.

嵌入式面试之《Linux系统编程100问》

哒宰的自我修养

Linux 线程 网络编程 进程

架构师训练营第 1 期 -- 第六周学习总结

发酵的死神

极客大学架构师训练营

2020年区块链行业十大趋势

CECBC

区块链 技术人才

架构师训练营第二周作业

lakers

极客大学架构师训练营

大企程序员亲身经历告诉你,CRM系统,自己的才是最好的

Philips

敏捷开发

架构师训练营第六周作业

邓昀垚

极客大学架构师训练营

架构师训练营第二周总结

lakers

极客大学架构师训练营

有状态软件如何在k8s上快速扩容甚至自动扩容

东风微鸣

Kubernetes DevOps openshift

快速掌握并发编程---Semaphore原理和实战

田维常

并发编程

LeetCode题解:90. 子集 II,递归+for循环+回溯,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

架构师训练营第 1 期 第 6 周作业

李循律

极客大学架构师训练营

TarsCpp 组件 之 智能指针详解

TARS基金会

c++ 微服务 智能指针 TARS

架构师训练营第 1 期 -- 第六周作业

发酵的死神

极客大学架构师训练营

当AI入职FBI,克格勃直呼内行

脑极体

快速掌握并发编程---深入学习Condition

田维常

并发编程

快速掌握并发编程---CountDownLatch原理和实战

田维常

并发编程

科大讯飞翻译系统变身“随身翻译官” 助力粤港澳大湾区一体化建设

Talk A.I.

2020年9月公有云性能评测:UCloud、腾讯云屈居二三名,冠军竟然是它?

博睿数据

云计算 公有云 评测 排行榜

CICD实战——服务自动测试

TARS基金会

微服务 单元测试 CI/CD

甲方日常42

句子

工作 随笔杂谈 日常

架构师训练营第六周总结

邓昀垚

极客大学架构师训练营

央行数字货币亮相 吹皱一池春水

CECBC

数字货币 银行

元模型驱动(三):构建我们自己的元模型-KAYA

KaYa

DDD Kaya MDA MDD 元建模

SpringCloud 和 SpringBoot 版本选型

hepingfly

微服务 springboot SpringCloud 选型

在实时音视频领域,如何基于 TensorFlow 实现图像识别_AI&大模型_金叶清_InfoQ精选文章