综合实验二 利用智能小车探测环境

 一、实验简介

在病毒环境、生化环境、爆炸环境、火灾环境等特殊环境下,人不能直接进入探测,考虑借助于智能设备完成探测环境、搜救、搬运等任务,考虑采用带摄像头的智能小车实现具体探测功能。

二、实验目的

通过本实验能够综合利用智能小车行走、避障、照相、识别图片色彩和语音播报的功能。

三、实验步骤与结果

1、实验实现功能说明

    本实验通过二维码识别“start”开始运行,语音播报系统,颜色识别算法,小车控制指令,实现了小车识别到包含start信息的二维码时,小车起步,之后边走边识别颜色,并且记录,最后识别到包含stop信息的二维码时,小车停止并返回初始位置,最终播报识别到的颜色。

2、实验整体设计思路

本实验的要求:小车边走路边识别颜色,并且将识别的颜色记录下来,故传统的单线程无法满足需求,所以要引入多线程,我们引入一条线程thread1,令它执行颜色识别和二维码识别的功能,主线程控制小车的运动。

设置开始标志stopFlag为0,在thread1线程中不断捕获摄像头的图像,扫描到start信号后,置开始标志stopFlag为1,跳出死循环,直行-左转,之后设置停止标志stopFlag为0,让小车一直向前走,在thread1中继续不断捕获摄像头,扫描到stop信号后,置停止标志stopFlag为1,跳出直行循环,之后设置程序让小车返回原处。

颜色识别,由于小车一秒捕获的图像较多,颜色识别到像素块颜色过多,会有重复,因此我们书写了比较算法,利用数组统计每种颜色像素块的数量,比较颜色块数量,令数组数值-即数量最多的为识别到的颜色。

3、实验程序

#bgr8转jpeg格式

import enum

import cv2

import time

import numpy as np

import traitlets

import threading

import inspect

import ctypes

#语音播报# 下面的key要换成自己的

import pygame from aip

import AipSpeech

""" 语音技术 APPID AK SK """

SpeechAPP_ID = '17852430'

SpeechAPI_KEY ='eGeO4iQGAjHCrzBTYd1uvTtf'

SpeechSECRET_KEY = 'Cn1EVsUngZDbRLv4OxAFrDHSo8PsvFVP'

#连接客户端

Speechclient = AipSpeech(SpeechAPP_ID, SpeechAPI_KEY, SpeechSECRET_KEY)

#语音播报初始化

pygame.mixer.init()

def voice_play(text, name,sped=2):

    rst = Speechclient.synthesis(text, 'zh', 1, {'spd': sped, 'vol': 10, 'per': 3})#语音文字text

    with open(f'./{name}.mp3', 'wb') as f:

        f.write(rst)#播报text

    pygame.mixer.init()

    pygame.mixer.music.load(f'./{name}.mp3')

    pygame.mixer.music.play()

    time.sleep(0.1)  

#二维码识别。标志位转换函数

stopFlag = 0def  detect_control(info):

    global stopFlag

    if stopFlag == 0:

        if info == "stop":

            robot.Speed_axis_Yawhold_control(0,  0)   #停车

            stopFlag = 1

            voice_play("停止","stop")

    # 代表往回走

    else:

        pass

def bgr8_to_jpeg(value, quality=75):

return bytes(cv2.imencode('.jpg', value)[1])

#导入库并显示摄像头显示组件

# import the necessary packages

#import simple_barcode_detection

import cv2

import pyzbar.pyzbar as pyzbar

from PIL import Image

import ipywidgets.widgets as widgets

#底层驱动方法

from Raspblock import Raspblockrobot = Raspblock()

origin_widget=widgets.Image(format='jpeg',width=280, height=160)

mask_widget = widgets.Image(format='jpeg',width=280,height=160)

result_widget=widgets.Image(format='jpeg',width=280,height=160)

image_container=widgets.HBox([origin_widget,mask_widget,result_widget])

display(image_container)# 二维码

def decodeDisplay(image):

    urls = []

    barcodes = pyzbar.decode(image)

    for barcode in barcodes:

        # 提取二维码的边界框的位置

        # 画出图像中条形码的边界框

        (x, y, w, h) = barcode.rect

        # 提取二维码数据为字节对象,所以如果想在输出图像上

        # 画出来,就需要先将它转换成字符串

        barcodeData = barcode.data.decode("utf-8")

        barcodeType = barcode.type

        # 向终端打印条形码数据和条形码类型

        print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))

        urls.append(barcodeData)

    if len(urls) > 0:

        return urls[0]

#线程def _async_raise(tid, exctype):

    tid = ctypes.c_long(tid)

    if not inspect.isclass(exctype):

        exctype = type(exctype)

    res=ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))

    if res == 0:

        raise ValueError("invalid thread id")

    elif res != 1:

        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)

        def stop_thread(thread):

_async_raise(thread.ident, SystemExit)

# 摄像头参数

cap = cv2.VideoCapture(0)

cap.set(3, 560)

cap.set(4, 420)

cap.set(5, 10)  

cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))

width  =280   

height =160   

color = [0,0,0,0,0,0,0,0,0]

#color数组初始化

# #红色区间

red_color_lower = np.array([0, 43, 46])red_color_upper = np.array([10, 255, 255])

# #绿色区间

green_color_lower = np.array([35, 43, 46])green_color_upper = np.array([77, 255, 255])

# #蓝色区间

blue_color_lower=np.array([100, 43, 46])blue_color_upper = np.array([124, 255, 255])

# #黄色区间

yellow_color_lower = np.array([26, 43, 46])yellow_color_upper = np.array([34, 255, 255])

# #橙色区间

orange_color_lower = np.array([11, 43, 46])orange_color_upper = np.array([25, 255, 255])

color_results = []gray = Nonedef Color_Recongnize():

    global gray

    while(1):

        ret, frame = cap.read()

        #cv2.imshow('Capture', frame)

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        im = decodeDisplay(gray)

        if im:

            detect_control(im)

            print(im)

        origin_widget.value = bgr8_to_jpeg(frame)

         # change to hsv model

        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        red_mask = cv2.inRange(hsv, red_color_lower, red_color_upper)

        orange_mask = cv2.inRange(hsv, orange_color_lower, orange_color_upper)

        yellow_mask = cv2.inRange(hsv, yellow_color_lower, yellow_color_upper)

        green_mask = cv2.inRange(hsv, green_color_lower, green_color_upper)

        blue_mask = cv2.inRange(hsv,blue_color_lower, blue_color_upper)

        # 247需要

        for i in range(height-10,height+10):

            for j in range(width-10,width+10):

                if red_mask[i,j] == 255:

                    color[1] +=1

                if orange_mask[i,j] == 255:

                    color[2] +=1

                if yellow_mask[i,j] == 255:

                    color[3] +=1

                if green_mask[i,j] == 255:

                    color[4] +=1

                if blue_mask[i,j] == 255:

                    color[5] +=1

        max = 0

        for i in range(8):

            if color[i]>color[max]:

                max = i

        result = [""]  

        if max ==1:

            result = ("红色", 'zh', 1, {'spd': 2, 'vol': 15, 'per': 1})

       ## if max ==2:

            #result = ("橙色", 'zh', 1, {'spd': 2, 'vol': 15, 'per': 1})

        if max ==3:

            result = ("黄色", 'zh', 1, {'spd': 2, 'vol': 15, 'per': 1})

        if max ==4:

            result = ("绿色", 'zh', 1, {'spd': 2, 'vol': 15, 'per': 1})

        #if max ==5:

            #result = ("蓝色", 'zh', 1, {'spd': 2, 'vol': 15, 'per': 1})

        colRst = result[0]

        if colRst not in color_results:

            color_results.append(colRst)

            

        print(colRst,end=" ")

        for i in range(len(color)):

            color[i] = 0

#启动进程

thread1=threading.Thread(target=Color_Recongnize)

thread1.setDaemon(True)thread1.start()robot = Raspblock()

# 开始标志startFlag = 0

while startFlag == 0:

    if type(gray) != type(None):

        ifo = decodeDisplay(gray)

        if ifo == "start":

            # 检测到开始信号,退出循环

            startFlag = 1

            break#初始检测到start信号后退

voice_play("down","down")for i in range(28):

    robot.Speed_axis_Yawhold_control(0,  -5)#后退

    time.sleep(0.1)   

    for i in range(24):

    robot.Speed_Wheel_control(-2, -2, -6, -6)#右后转

    time.sleep(0.1)    

# 让小车不停的倒退,直到检测到stop信号

voice_play("down","down")while stopFlag == 0:

    robot.Speed_axis_Yawhold_control(0,  -5)#后退

    time.sleep(0.1)

voice_play("forward","forward")for i in range(135):  #待调

    robot.Speed_axis_Yawhold_control(0,  5)

    time.sleep(0.1)

    voice_play("right","come back")for i in range(24):

    robot.Speed_Wheel_control(2, 2, 6, 6)#右转

    time.sleep(0.1)

    voice_play("forward","forward")for i in range(15):  #待调

    robot.Speed_axis_Yawhold_control(0,  5)

    time.sleep(0.1)

# 语音播报识别到的颜色t

ext = "识别颜色为" +",".join(color_results)voice_play(text,"rscolor")

# 语音播报识别到的颜色#结束进程,只有在结束时才需要执行此段代码

stop_thread(thread1)

4.实验结果

见文件夹中,以视频形式提交。

四、实验分析

1、实验总结与收获

实验通过程序设计达到预期。通过视觉识别、语音合成、图像处理、小车控制等完成实验目标。但是,识别效果达不到理想,主要原因是所用的算法无法高效规避误差。

2、实验收获

(1)实验中使用了多线程来实现同时进行图像处理和小车控制的功能。这有助于更好地理解了多线程编程的原理和应用。

(2)实验中,需要不断调试小车运动代码,以适应地形,需要非常多的耐心。

(3)颜色识别过程中,需精准的描述各颜色值区间,避免误判,并且,在不同光线环境条件下需不断调试颜色数值区间,来准确判断识别颜色。

(4)此外,释放线程、增加break、字符串与指令相互转换等操作,在后续的程序设计中都可以运用借鉴。

3、其他(实验建议或意见)

关于多线程,函数定义和opencv精准识别颜色方法的介绍,摄像头的使用注意事项提醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值