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

本文介绍了如何使用AI实验箱中的摄像头捕捉数字图像,通过Opencv处理、贝叶斯方法识别,并驱动机械臂移动识别出的数字。实验中,作者分析了影响识别准确率的因素,并提出提高准确性的策略,包括改善光照、增加训练数据多样性和优化算法等。
摘要由CSDN通过智能技术生成

实验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的灯一直闪烁,直到配置成功(灯处于长亮)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MorleyOlsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值