【人工智能Ⅰ】实验5:AI实验箱应用之贝叶斯

news2024/11/13 11:09:19

实验5 AI实验箱应用之贝叶斯

一、实验目的

1. 用实验箱的摄像头拍摄方块上数字的图片,在图像处理的基础上,应用贝叶斯方法识别图像中的数字并进行分类。

二、实验内容和步骤

1. 应用实验箱机械手臂上的摄像头拍摄图像;

2. Opencv处理图像;

3. 用贝叶斯方法识别处理后图像中的数字;

4. 驱动机械臂移动识别出的数字方块。

三、实验结果和分析

1. 对给出程序的主要模块添加注释,并运行完成实验步骤

程序主要模块的注释

(1)bayes_classify_movethings\img_rec\bayes_classfier.py

import numpy as np      # 导入numpy库,用于数学运算

import cv2              # 导入opencv库,用于图像处理

# 图像二值化函数

def imgBinaryzation(imgs):

    global cv_img                           # 定义全局变量cv_img

    for i in range(len(imgs)):              # 遍历图像数组

        cv_img = imgs[i].astype(np.uint8)   # 将图像转换为uint8类型    

        cv2.threshold(cv_img, 50, 1, cv2.THRESH_BINARY_INV, cv_img) # 应用阈值操作进行图像二值化

        imgs[i] = cv_img                    # 更新原图像数组

        print(cv_img.reshape(28, 28))       # 打印变换后的图像

    return imgs                             # 返回二值化后的图像数组

# 训练贝叶斯分类器函数

def train(imgs, labels, classNum, featureNum, valueZone):

    priPro = np.zeros(classNum)             # 初始化先验概率数组

    condPro = np.zeros((classNum, featureNum, valueZone))  # 初始化条件概率数组

    # 计算先验概率和条件概率

    for i in range(len(labels)):            # 遍历所有标签

        img = imgs[i]                       # 获取对应的图像

        label = labels[i][0]                # 获取图像对应的标签

        priPro[label] += 1                  # 更新先验概率

       

        for j in range(featureNum):         # 遍历所有特征

            condPro[label][j][img[j]] += 1  # 更新条件概率

    # 对条件概率进行平滑处理

    for i in range(classNum):               # 遍历所有类别

        for j in range(featureNum):         # 遍历所有特征

            total = 0                       # 初始化特定特征的总计数

            for k in range(valueZone):      # 遍历所有可能的特征值

                total += condPro[i][j][k]   # 累加特定类别和特征下的特征值计数

            for k in range(valueZone):      # 再次遍历所有可能的特征值

                # 计算平滑后的条件概率

                pro_k = (float(condPro[i][j][k]) / float(total)) * 100000 + 1

                condPro[i][j][k] = pro_k    # 更新条件概率数组

    return priPro, condPro                  # 返回先验概率和条件概率

# 计算特定图像和标签的概率

def cal_pro(img, label, priPro, condPro):

    pro = int(priPro[label])                # 获取先验概率

    print("len(img): ", len(img))

    for i in range(len(img)):               # 遍历图像的每个特征

        pro *= int(condPro[label][i][img[i]])  # 计算最终概率

    return pro  # 返回概率

# 分类器准确率计算函数

def classfier_acc(imgs, priPro, condPro, classNum):

    pred = []                               # 初始化预测结果列表

    for img in imgs:                        # 遍历所有图像

        predLabel = -1                      # 初始化预测标签

        maxPro = -1                         # 初始化最大概率

        for i in range(classNum):           # 遍历所有类别

            pro = cal_pro(img, i, priPro, condPro)  # 计算概率

            if maxPro < pro:                # 如果找到更大的概率

                maxPro = pro                # 更新最大概率

                predLabel = i               # 更新预测标签

        pred.append(predLabel)              # 将预测标签加入结果列表

    print("pred: ", pred)

    return pred                             # 返回预测结果

# 单个图像分类函数

def classfier(img, priPro, condPro, classNum):

    pred = []                               # 初始化预测结果列表

    predLabel = -1                          # 初始化预测标签

    maxPro = -1                             # 初始化最大概率

    for i in range(classNum):               # 遍历所有类别

        pro = cal_pro(img, i, priPro, condPro)  # 计算概率

        if maxPro < pro:                    # 如果找到更大的概率

            maxPro = pro                    # 更新最大概率

            predLabel = i                   # 更新预测标签

    pred.append(predLabel)                  # 将预测标签加入结果列表

    print("pred: ", pred)

    return pred                             # 返回预测结果

# 准确率计算函数

def accuracyRate(pred, labels):

    count = 0                               # 初始化计数器

    for i in range(len(pred)):              # 遍历所有预测结果

        if pred[i] == int(labels[i][0]):    # 如果预测结果与实际标签相同

            count += 1                      # 增加计数器

    acRate = float(count) / float(len(pred))  # 计算准确率

    return acRate                           # 返回准确率

(2)bayes_classify_movethings\main.py

    import threading

import cv2

from img_rec import img_rec

from robotic_arm.my_serial import MySerial

# 单片机功能选择

SINGLE_CHIP_FUNCTION_DATA = "3001070155a1ff"

# 控制机械臂位置

CONTROL_ROBOTIC_ARM_POSITION_DATA = "3001070155a11131"

# 控制机械臂抓取

CONTROL_ROBOTIC_ARM_GRAB_DATA = "3002070155a131"

vs = cv2.VideoCapture(0)

image_processing = img_rec.ImageProcessing()

# 创建串口对象

my_serial = MySerial('/dev/ttyS4', baudrate=115200, timeout=1)

# 创建串口接收远程

t_serial = threading.Thread(target=my_serial.receive_msg)

t_serial.start()

current_state = 0       # 当前状态

next_state = 0          # 下一个状态

is_grab = True          # 判断是否抓取(初始是false),进行搬运需要改为true

source_location = 0     # 最终搬运的源位置

# my_serial.send_msg(SINGLE_CHIP_FUNCTION_DATA + "31")

while True:

    current_state = next_state

    if current_state == 0:

        my_serial.send_msg(CONTROL_ROBOTIC_ARM_POSITION_DATA)

        print("控制机械臂移动。")

        next_state = 1

    elif current_state == 1:

        if my_serial.recv_msg[12:16] == "2131":

            print("机械臂已到达仓库1")

            next_state = 2

            my_serial.recv_msg = ""

    elif current_state == 2:

        print("开始拍摄照片。")

        for i in range(30):

            ret, frame = vs.read()

        cv2.imwrite("./pic.jpg", frame)

        # cv2.imshow("frame", frame)

        # cv2.waitKey(0)

        print("拍摄照片完成,照片保存在当前目录下的pic.jpg,开始识别。")

        image_thresh, cargo_location = image_processing.image_position(frame)

        cargo_location_sort = image_processing.image_sort(cargo_location)

        rec_result = image_processing.image_recognize(cargo_location, cargo_location_sort, frame)

        print("识别结束,结果为{}".format(rec_result))

        if is_grab and rec_result != {}:

            # sorted 可以对所有可迭代的对象进行排序操作。

            # sorted(iterable, key=None, reverse=False)

            # iterable -- 可迭代对象。

            # key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。

            # reverse -- 排序规则,reverse = True 降序 reverse = False 升序(默认)。

            # 返回值 -- 返回重新排序的列表。

            list_sort = sorted(rec_result.items(), key=lambda kv: (kv[1], kv[0]), reverse=False)

            print("排序结束,结果为{}".format(list_sort))

            source_location = list_sort[0][0] + 1

            next_state = 3

        else:

            break

    elif current_state == 3:

        my_serial.send_msg(CONTROL_ROBOTIC_ARM_GRAB_DATA + "1{}21".format(source_location))

        next_state = 4

    elif current_state == 4:

        if my_serial.recv_msg[12:16] == "4131":

            print("机械臂已搬运完毕。")

            break

        break

    else:

        break

my_serial.THREAD_CONTROL = False

2. 描述整个执行过程

实验步骤操作内容

(1)应用实验箱机械手臂上的摄像头拍摄图像

    执行该操作时,程序会把摄像头拍摄的图像存入根目录下,并命名为pic.jpg图像。pic.jpg图像示例如下图所示:

(2)Opencv处理图像

    执行该操作时,程序会利用pic.jpg图像进行图像定位(将黄色色块从整个图像中取出)、图像排序(将数字图像的位置进行排序)。

(3)用贝叶斯方法识别处理后图像中的数字

执行该操作时,程序会利用pic.jpg图像进行图像识别(对各个位置处的数 字进行分类)。分类结果会在实验箱终端进行显示,如下图所示:

(4)驱动机械臂移动识别出的数字方块

执行该操作时,程序会将识别出的4个数字分类结果进行排序,并搬运其中的最值数字方块。机械臂移动过程如下图所示:

3. 测试不同数字块,得出本次实验中数字识别的准确率

(1)每个数字的测试

待测数字方块

1

2

3

4

5

6

7

8

9

程序识别结果

1

2

3

9

3

9

1

3

9

上表中,蓝色部分为识别准确的数字,橘色部分为识别错误的数字。

因此,本次实验中数字识别的大致准确率为:4 / 9 = 44.4%

(2)一组方块的测试

测试序号

4个方块的内容

预测的4个结果

预测准确率

1

4513

9313

50%

2

4913

9913

75%

3

6193

6193

100%

4

6513

5313

50%

5

7513

1313

50%

6

8513

3313

50%

7

9913

4913

75%

我们在实验的过程中均录制了视频,但是由于视频文件过大,无法全部发送到平台,因此此处只给出测试7的视频结果。

4. 分析准确率不高的原因,给出提高准确率的可能方法

准确率低的原因

(1)光线因素

我们在测试实验箱自带的识别应用软件中发现,在二值化图形的情况下,有些数字方块由于光线太强直接显示为白色,有些数字方块由于光线太弱直接显示为黑色。切换到RGB图形的情况时,发现光线也存在类似的情况,大致对应二值化图形情况下的内容。多次实验后,我们发现光线的强弱的确会影响识别的准确率。

(2)测试集因素

Bayes识别存在识别错误的情况可能由以下因素导致的:数字6和数字9存在中心对称的情况;数字4和数字9的拓扑结构类似,均包含一个封闭图案和半封闭图案;数字5和数字3的拓扑结构类似;数字7和数字1的拓扑结构类似;数字8的一半可以作为数字3。

(3)特征的独立性假设难以达到

    朴素贝叶斯分类器基于特征之间相互独立的假设。然而,在图像数据中,像素之间通常是高度相关的。例如,在数字图像中,相邻像素往往有相关性,这违背了朴素贝叶斯的独立性假设。

(4)训练集因素

首先,如果训练数据不足或缺乏多样性,例如数字样式的差异,模型可能无法泛化到新样本。其次,在训练数据中某些数字出现得更频繁,导致模型对这些数字的识别效果更好,即存在类别不平衡。

提高准确率的可能方法

(1)均匀打光,保证每个数字方块处于同一个光照强度下。

(2)增加更多样化的训练数据,或者使用数据增强技术(如旋转、缩放、平移图像)来增加样本的多样性。

(3)使用类别平衡技术,如过采样少数类或欠采样多数类,以确保每个类别都有相似的表示。

(4)优化平滑参数,通过交叉验证来找到更优的平滑系数。

(5)改进特征提取和预处理步骤。使用更复杂的图像处理技术,如直方图均衡化、边缘检测或降维技术(如PCA),有助于提取更有意义的特征。

五、附录

1:操作系统互相连接的实验步骤

2:实验箱可使用的应用

(1)打开桌面上的“综合测试”,体验仓库货物识别及搬运功能。

(2)打开桌面上的“图像识别”,体验动物、水果、蔬菜等类别的识别。

3:WIFI连接注意事项

WIFI连接FSAIarm(屏幕右上角)。如果已经显示连接上,但仍然转圈,则点击disconnect,再重新连接自己的热点。M3配置wifi的灯一直闪烁,直到配置成功(灯处于长亮)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1273704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生成对抗网络(GAN)手写数字生成

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09; 二、什么是生成对抗网络1. 简单介绍2. 应用领域 三、网络结构四、构建生成器五、构建鉴别器六、训练模型1. 保存样例图片2. 训练模型 七、生成动图 一、前言 我的环境&#xff1…

可行性研究:2023年废旧金属回收行业前景及市场数据分析

废品收购是再生资源行业的重要业务之一。是指将各种废弃物品分类后按不同种类和性能卖给不同的生产厂商或直接出售给再制造厂家&#xff08;如重新使用报废汽车拆解的零件&#xff09;。废旧金属是指暂时失去使用价值的金属或合金制品&#xff0c;一般的废旧金属都含有有用的金…

车牌限行_分支结构的C语言实现xdoj7

试题名称 车牌限行 时间限制: 1 秒 内存限制: 256KB 问题描述 问题描述 受雾霾天气影响&#xff0c;某市决定当雾霾指数超过设定值时对车辆进行限行&#xff0c;假设车牌号全为数字&#xff0c;且长度不超过6位&#xff0c;限行规则如下&#xff1a; &#xff08;…

C++相关闲碎记录(2)

1、误用shared_ptr int* p new int; shared_ptr<int> sp1(p); shared_ptr<int> sp2(p); //error // 通过原始指针两次创建shared_ptr是错误的shared_ptr<int> sp1(new int); shared_ptr<int> sp2(sp1); //ok 如果对C相关闲碎记录(1)中记录的shar…

AI - Steering behaviorsII(碰撞避免,跟随)

Steering Behaviors系统中的碰撞避免&#xff0c;路径跟随&#xff0c;队长跟随 Collision Avoid 在物体前进的方向&#xff0c;延伸一定长度的向量进行检测。相当于物体对前方一定可使范围进行检测障碍物的碰撞 延伸的向量与碰撞物圆心的距离小于碰撞物的半径&#xff0c;则…

docker-compose脚本编写及常用命令

安装 linux DOCKER_CONFIG/usr/local/lib/docker/cli-plugins sudo mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://521github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose sudo c…

numpy知识库:深入理解numpy.resize函数和数组的resize方法

前言 numpy中的resize函数顾名思义&#xff0c;可以用于调整数组的大小。但具体如何调整&#xff1f;数组形状变了&#xff0c;意味着数组中的元素个数发生了变化(增加或减少)&#xff0c;如何确定resize后的新数组中每个元素的数值呢&#xff1f;本次博文就来探讨并试图回答这…

润申信息企业标准化管理系统 SQL注入漏洞复现

0x01 产品简介 润申信息科技企业标准化管理系统通过给客户提供各种灵活的标准法规信息化管理解决方案&#xff0c;帮助他们实现了高效的标准法规管理&#xff0c;完成个性化标准法规库的信息化建设。 0x02 漏洞概述 润申信息科技企业标准化管理系统 CommentStandardHandler.as…

蓝桥杯每日一题2023.11.30

题目描述 九数组分数 - 蓝桥云课 (lanqiao.cn) 题目分析 此题目实际上是使用dfs进行数字确定&#xff0c;每次循环中将当前数字与剩下的数字进行交换 eg.1与2、3、4、、、进行交换 2与3、4、、、进行交换 填空位置将其恢复原来位置即可&#xff0c;也就直接将其交换回去即可…

鸿蒙原生应用/元服务开发-开发者如何进行真机测试

前提条件&#xff1a;已经完成鸿蒙原生应用/元服务开发&#xff0c;已经能相对熟练使用DevEco Studio,开发者自己有鸿蒙4.0及以上的真机设备。 真机测试具体流程如下 1.手机打开开发者模式 2.在项目中&#xff0c;左上角 文件(F)->项目结构 进行账号连接 3.运行

AS 之 gradle 命令

文章目录 1、命令大全2、编译命令2.1 检查依赖并编译打包2.2 编译并打 Debug 包2.3 编译打出 Debug 包并安装2.4 编译并打出 Release 包2.5 编译打出 Release 包并安装2.6 Debug/Release 编译并打印日志 3、清除命令4、卸载命令4.1 卸载 Debug/Release 安装包4.2 adb 卸载 5、调…

智能优化算法应用:基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.风驱动算法4.实验参数设定5.算法结果6.参考文献7.…

麒麟操作系统进入单用户模式

Kylin V4 桌面版&#xff1a; 启动系统后&#xff0c;在启动菜单界面选择 Kylin 4.0.2 高级选项后回车。 在高级模式选项下选择第二行 recovery mode 模式后&#xff0c;按 e 编辑。 按 e 后如下图&#xff0c;找到 linux 开头的一行&#xff0c;修改 ro 为 rw 后&#xff0c…

将项目放到gitee上

参考 将IDEA中的项目上传到Gitee仓库中_哔哩哔哩_bilibili 如果cmd运行ssh不行的话&#xff0c;要换成git bash 如果初始化后的命令用不了&#xff0c;直接用idea项放右键&#xff0c;用git工具操作

[原创][3]探究C#多线程开发细节-“用ConcurrentQueue<T>解决多线程的无顺序性的问题“

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…

数据中心布线解决方案比较: DAC 电缆和 AOC 光缆

在当今的数字时代&#xff0c;数据中心是无数行业的支柱&#xff0c;它确保了信息的交换并维护关键数据的完整性。为了保持这些数据中心高效运行&#xff0c;选择正确的布线解决方案至关重要。在这方面&#xff0c;两种流行的选择是直连铜缆 (DAC) 和有源光缆 (AOC)。在本文中&…

论文绘图——局部细节放大

文章目录 前言一、绘图1.0版二、绘图2.0版三、总结 前言 我们经常在论文中会看到下面这些样式的图片&#xff1a;在图片中使用矩形框框出感兴趣的区域&#xff0c;然后在底部或者其他位置附上对应的局部放大的细节图&#xff0c;简洁好看。✨ 曾尝试使用过PPT制作&#xff0c;也…

用于缓存一些固定名称的小组件

项目中&#xff0c;用于缓存姓名、地名、单位名称等一些较固定名称的id-name小组件。用于减少一些表的关连操作和冗余字段。优化代码结构。扩展也方便&#xff0c;写不同的枚举就行了。 具体用法&#xff1a; {NameCacheUser.USER.getName(userId);NameCacheUser.ACCOUNT.getN…

GAN:WGAN前作

WGAN前作&#xff1a;有原则的方法来训练GANs 论文&#xff1a;https://arxiv.org/abs/1701.04862 发表&#xff1a;ICLR 2017 本文是wgan三部曲的第一部。文中并没有引入新的算法&#xff0c;而是标是朝着完全理解生成对抗网络的训练动态过程迈进理论性的一步。 文中基本是…

Django 模板引擎 (四)

一、Django模板引擎 一个强大的工具&#xff0c;用于在HTML页面中嵌入动态内容。它使用一种被称为Django模板语言&#xff08;Django Template Language&#xff09;的简单而强大的语法来处理模板。该模板语言使用”{% %}”进行标记&#xff0c;用于执行各种操作。 二、Django…