///摄像头 #include // Include RealSense Cross Platform API #include #include "example.hpp" #include #include #include #include #include #include #include #include #include #include // opencv 用于图像数据读取与处理 #include #include #include // #include // 使用Eigen的Geometry模块处理3d运动 #include #include #include #include /*........................................................................*/ #include ///摄像头 #include // Include RealSense Cross Platform API #include #include "../include/example.hpp" #include /*........................................................................*/ // pcl #include #include #include #include //条件滤波器头文件 #include //直通滤波器头文件 #include //半径滤波器头文件 #include //统计滤波器头文件 #include //体素滤波器头文件 #include #include #include #include // boost.format 字符串处理 //#include #include "Yolo.hpp" #include "DepthProcessor.hpp" #include "IMUProcessor.hpp" // 语音 #include #include #include #include #include "serialport.h" #include #include using namespace std; // 超声波 #include "../include/dyp-a05/sonar_driver.h" #include #include #include #include // 蜂鸣器 #include #include /* Private variables ---------------------------------------------------------*/ static int addr = 0; static int error = 0; static int fdcom = 0; static PortInfo_t portinfo = {9600, 8, 0, 0, 1, 0}; /* ========================================= | header | id | 指令 | 校验和 | ----------------------------------------- | 0x55 0xaa | 0x01 | 0x01 | 0x01 | ========================================= */ static unsigned char tx_buffer[TX_BUFFER_MAX] = {0x55, 0xaa, 0x01, 0x01, 0x01}; /* ========================================= | 帧头 | 地址 | 指令 | 校验和 | ----------------------------------------- | 0x55 0xaa | 0x01 | 0x01 | 0x01 | ========================================= */ static unsigned char rx_buffer[RX_BUFFER_MAX]; static double Distance[4] = {0, 0, 0, 0}; std::string port = "/dev/ultrasound"; /*初始化参数定义*/ int ini = 0; int initial_times = 10; bool initial = false; double max_wrong =2.5; double min_wrong =0.25; double dis0[10]; double dis1[10]; bool end_this_program = false; // 差值 double dis0_d = 0.0; double dis1_d = 0.0; // 差值阈值 double Thr = 0.5; // 播报选择 static int voice_status = 0; std::mutex mtx; bool ToPlay = false; int distt; bool isObjectt; // declare void play_voice(string); // 检查校验和 int data_check(unsigned char buf[RX_BUFFER_MAX], int datalen) { int checksum = 0; if((buf[0]==0xFF) && datalen == 10) { for(int i=0; i Objects = { {"person", 0x51}, {"bicycle", 0x52}, {"motorcycle", 0x53}, {"bus", 0x54}, {"cat", 0x55}, {"dog", 0x56}, {"fire hydrant", 0x57}, {"bottle", 0x58}, {"cup", 0x59}, {"chair", 0x5a}, {"couch", 0x5b}, {"potted plant", 0x5c}, {"bed", 0x5d}, {"dining table", 0x5e}, {"toilet", 0x5f}, {"tv", 0x60}, {"refrigerator", 0x61}, {"object", 0x6e}, // 待增物体todo }; // 播报函数 // 10->16进制,conver使用 char tenTo16(int i){ char output = 'a' ; switch(i){ case 1: output = 0x01; break; case 2: output = 0x02; break; case 3: output = 0x03; break; case 4: output = 0x04; break; case 5: output = 0x05; break; case 6: output = 0x06; break; case 7: output = 0x07; break; case 8: output = 0x08; break; case 9: output = 0x09; break; case 0: output = 0x0e; break; } return output; } // 待传输数组,结合距离和物体,未用 void conver(char out[], double dis, string obj){ // todo 四舍五入一下 0.29->0.3 int ge = -1,shi=-1,bai=-1,qian=-1, dian= -1, dian2 = -1;; //char out[] = {0x8b}; //auto *beg = begin(out); int p = 0; //printf("qian: %d,bai:%d,shi:%d,ge:%d,dian:%d\n",qian,bai,shi,ge,dian); //将距离转为十六进制 if(dis >= 1000){ qian = (int)dis/1000; bai = (int)dis/100%10; shi = (int)dis/10%10; ge = (int)dis%10; }else if(dis >= 100){ bai = (int)dis/100; shi = (int)dis/10%10; ge = (int)dis%10; }else if(dis >= 10){ shi = (int)dis/10; ge = (int)dis%10; }else if(dis >=1){ ge = (int)dis%10; }else{ ge = 0; } dian = (int)(dis*10)%10; dian2 = (int)(dis*100)%10; //printf("qian: %d,bai:%d,shi:%d,ge:%d,dian:%d\n",qian,bai,shi,ge,dian); if(qian != -1){ out[p++] = tenTo16(qian); out[p++] = 0x0c; out[p++] = tenTo16(bai); out[p++] = 0x0b; out[p++] = tenTo16(shi); out[p++] = 0x0a; }else if(bai != -1){ out[p++] = tenTo16(bai); out[p++] = 0x0b; out[p++] = tenTo16(shi); out[p++] = 0x0a; }else if(shi != -1){ out[p++] = tenTo16(shi); out[p++] = 0x0a; } // 个位数 out[p++] = tenTo16(ge); // 点数 out[p++] = 0x0d; // 小数点后一位 out[p++] = tenTo16(dian); // 小数点后两位 out[p++] = tenTo16(dian2); //printf("p:%d, out[0]:%x\n",p,out[1]); //将string转换成对应的十六进制 auto iter = Objects.find(obj); if(iter != Objects.end()){ out[p++] = iter->second; } //return out; } // 串口发送起始120,十六进制78 bool serial_com(char n16){ SerialPort serialport; SerialPort::Port_INFO *pPort; // Init SerialPort int COM_id = 0; pPort = (SerialPort::Port_INFO *)malloc(sizeof(SerialPort::Port_INFO)); if(pPort == NULL) { fprintf(stderr, "Error malloc... [FAIL]\n"); } memset(pPort, 0, sizeof(SerialPort::Port_INFO)); int result = serialport.InitPort(pPort, COM_id); if(result < 0) { fprintf(stderr, "Error Running SerialPort... [FAIL]\n"); } // fprintf(stdout, "SerialPort [%s] running... [OK]\n", pPort->name); int send_size = 15; char serial_sendmsg[send_size] = {n16}; int msg_len = strlen(serial_sendmsg); int send_nbyte = serialport.sendnPort(pPort,const_cast(serial_sendmsg),msg_len); if (send_nbyte > 0) { // 收到数据 printf("Send: [%d] ... [OK]\n", send_nbyte); return true; } return false; } // 串口发送接口函数-发送单个物体 bool serial_com(string object){ SerialPort serialport; SerialPort::Port_INFO *pPort; // Init SerialPort int COM_id = 0; pPort = (SerialPort::Port_INFO *)malloc(sizeof(SerialPort::Port_INFO)); if(pPort == NULL) { fprintf(stderr, "Error malloc... [FAIL]\n"); } memset(pPort, 0, sizeof(SerialPort::Port_INFO)); int result = serialport.InitPort(pPort, COM_id); if(result < 0) { fprintf(stderr, "Error Running SerialPort... [FAIL]\n"); } // COM Send // 设置参数 // 物体 //string object= "bed"; // 距离 //double Distance= 5.5; int send_size = 15; char serial_sendmsg[send_size] = {}; auto iter = Objects.find(object); if(iter != Objects.end()){ serial_sendmsg[0] = iter->second; } // conver(serial_sendmsg, Distance, object); int msg_len = strlen(serial_sendmsg); int send_nbyte = serialport.sendnPort(pPort,const_cast(serial_sendmsg),msg_len); if (send_nbyte > 0) { // todo... fprintf(stdout, "Send: [%d] %s... [OK]\n", send_nbyte, serial_sendmsg); return true; } return false; } // 串口发送接口函数-发送多个物体类别 bool serial_com(set objects){ SerialPort serialport; SerialPort::Port_INFO *pPort; /* Init SerialPort */ int COM_id = 0; pPort = (SerialPort::Port_INFO *)malloc(sizeof(SerialPort::Port_INFO)); if(pPort == NULL) { fprintf(stderr, "Error malloc... [FAIL]\n"); } memset(pPort, 0, sizeof(SerialPort::Port_INFO)); int result = serialport.InitPort(pPort, COM_id); if(result < 0) { fprintf(stderr, "Error Running SerialPort... [FAIL]\n"); } int send_size = 50; char serial_sendmsg[send_size] = {0x02}; // conver(serial_sendmsg, distance, object); int p=0; for(auto e: objects){ // Objects auto iter = Objects.find(e); if(iter != Objects.end()){ // 找到 serial_sendmsg[p++] = iter->second; } } int msg_len = strlen(serial_sendmsg); int send_nbyte = serialport.sendnPort(pPort,const_cast(serial_sendmsg),msg_len); if (send_nbyte > 0) { // todo... fprintf(stdout, "Send: [%d] %s... [OK]\n", send_nbyte, serial_sendmsg); return true; } return false; } // 串口接收函数 void serial_receive(char response_buf[]){ SerialPort serialport; SerialPort::Port_INFO *pPort; // Init SerialPort int COM_id = 0; pPort = (SerialPort::Port_INFO *)malloc(sizeof(SerialPort::Port_INFO)); if(pPort == NULL) { fprintf(stderr, "Error malloc... [FAIL]\n"); } memset(pPort, 0, sizeof(SerialPort::Port_INFO)); int result = serialport.InitPort(pPort, COM_id); if(result < 0) { fprintf(stderr, "Error Running SerialPort... [FAIL]\n"); } // COM Receive int receive_nbyte = 0; int size = COM_BUFFER_SIZE; // char response_buf[COM_BUFFER_SIZE] = {'\0'}; while (1) { // 收取一次 receive_nbyte = serialport.signal_recvnPort(pPort, response_buf, size); if(receive_nbyte > 0) { for(int i = 0; i < receive_nbyte; i++) { response_buf[i] = response_buf[i]; } response_buf[receive_nbyte] = '\0'; break; } // if (receive_nbyte == 0) break; } // fprintf(stdout, "Receive: [%d] %s... [OK]\n", receive_nbyte, response_buf); } // 为了剔除类别中不属于检测出的类别 std::vector currentLabel= { "person", "bicycle", "motorcycle", "bus", "cat", "dog", "fire hydrant", "bottle", "cup", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "refrigerator", }; // 检查label是否在currentLabel中 bool labelCheck(std::string label){ // 使用 std::find() 在 vector 中查找目标字符串 auto it = std::find(currentLabel.begin(), currentLabel.end(), label); if(it != currentLabel.end()) { return 1; }else{ return 0; } } // 超声波检测线程函数 void ultrasound_play(){ fdcom = uart_init(port.c_str()); std::cout << fdcom << std::endl; if(fdcom > 0) { uart_set(fdcom, &portinfo); printf("[板卡%d通信参数]: %d, 8, 0, 0, 1, 0.\n",addr,9600); } while (true) { if(error) { Distance[0] = 0; Distance[1] = 0; Distance[2] = 0; Distance[3] = 0; // std::cout<< "串口打开错误!"< 0) { uart_set(fdcom, &portinfo); printf("fdcom:%d重启成功!!!!!!!!!!\n", fdcom); } continue; } else { uart_txd(fdcom, tx_buffer, TX_BUFFER_MAX); // 接收数据 int datalen = uart_rxd(fdcom, rx_buffer, RX_BUFFER_MAX, portinfo.baudrate); if(data_check(rx_buffer, datalen)) { Distance[0] = double(data_merge(rx_buffer[1], rx_buffer[2]))/1000;// 前一个为high,后一个为low Distance[1] = double(data_merge(rx_buffer[3], rx_buffer[4]))/1000; Distance[2] = double(data_merge(rx_buffer[5], rx_buffer[6]))/1000; Distance[3] = double(data_merge(rx_buffer[7], rx_buffer[8]))/1000; // std::cout<<"Distance[0]:"<min_wrong)) || ((Distance[1] <= Thr)&&(Distance[1]>min_wrong))){ // 定义全局变量 { std::cout<<"Distance[0]:"< classes = {}; // 播报全部类别, 新开一个线程等待串口的指令 void play_all_class(){ // 接收到202就发送全部物体类别 char resp[COM_BUFFER_SIZE]; std::string resp_s; while(1){ usleep(200000); serial_receive(resp); resp_s = resp; if(resp_s == "202"){ if(classes.empty()){ // std::cout<< "wbw111"<< std::endl; if(!serial_com(0x73)){ std::cout<< "115发送失败,没有物体不播报"<< std::endl; } }else{ voice_status = 4; // 任意传入,不会播报传入的物体 play_voice("cup"); } } } } // 语音播报 play_voice(label) void play_voice(string object){ // 上锁 std::lock_guard lock(mtx); // 发送开始的200 if(!serial_com(0x78)){ std::cout<< "200发送失败,此次不播报"<< std::endl; } switch(voice_status){ case 1: { // 发送距离和障碍物 if(serial_com(object)){ std::cout << "finish_object_label" << std::endl; } break; } case 2:{ // 发送距离 if(serial_com("object")){ std::cout << "finish_object" << std::endl; } break; } case 3:{ // 超声波检测,传入无用的一个字符,语音不做处理 if(serial_com(0x0f)){ std::cout << "finish_ultrasound" << std::endl; } break; } case 4:{ // 全部类别播报 if(serial_com(classes)){ std::cout<< classes.size() << std::endl; std::cout << "finish_all_classes" << std::endl; classes.clear(); } break; } case 0:{ std::cout << "仍在初始化阶段" << std::endl; } } } // 蜂鸣器播报 void signalHandler(int s) { end_this_program = true; } void Bee()// 启动 { int output_pin = 13; GPIO::setmode(GPIO::BCM); //signal(SIGINT, signalHandler); GPIO::setup(output_pin, GPIO::OUT, GPIO::LOW); std::cout << "Bee" << std::endl; while(!end_this_program){ if(ToPlay || (isObjectt && distt <= 0.5)) { // set pin as an output pin with optional initial state of HIGH GPIO::output(output_pin, GPIO::HIGH); usleep(100000);// 300000 GPIO::output(output_pin, GPIO::LOW); usleep(100000); }else if(isObjectt && distt > 0.5){ GPIO::output(output_pin, GPIO::HIGH); usleep(100000);// 300000 GPIO::output(output_pin, GPIO::LOW); usleep(300000); } else GPIO::output(output_pin, GPIO::LOW); } GPIO::cleanup(); } int main(){ rs2::log_to_console(RS2_LOG_SEVERITY_ERROR); // 声明 RealSense 管道,封装实际设备和传感器 rs2::pipeline cameraPipe, imuPipe; // 使用推荐的默认配置开始流式传输 // 默认视频配置包含深度流和色彩流 // 如果设备能够流式传输 IMU 数据,则默认启用陀螺仪和加速计 rs2::config cameraCfg, imuCfg; // IMU数据流设置帧率会报错,或是帧率设置过大? imuCfg.enable_stream(rs2_stream::RS2_STREAM_ACCEL, rs2_format::RS2_FORMAT_MOTION_XYZ32F); imuCfg.enable_stream(rs2_stream::RS2_STREAM_GYRO, rs2_format::RS2_FORMAT_MOTION_XYZ32F); // Declare object that handles camera pose calculations IMUProcessor imuProcessor; rs2::pipeline_profile imuProfile = imuPipe.start(imuCfg, [&](rs2::frame frame) { // Cast the frame that arrived to motion frame auto motion = frame.as(); // If casting succeeded and the arrived frame is from gyro stream if (motion && motion.get_profile().stream_type() == RS2_STREAM_GYRO && motion.get_profile().format() == RS2_FORMAT_MOTION_XYZ32F) { // Get the timestamp of the current frame double ts = motion.get_timestamp(); // Get gyro measures rs2_vector gyroData = motion.get_motion_data(); // Call function that computes the angle of motion based on the retrieved measures imuProcessor.process_gyro(gyroData, ts); } // If casting succeeded and the arrived frame is from accelerometer stream if (motion && motion.get_profile().stream_type() == RS2_STREAM_ACCEL && motion.get_profile().format() == RS2_FORMAT_MOTION_XYZ32F) { // Get accelerometer measures rs2_vector accelData = motion.get_motion_data(); // Call function that computes the angle of motion based on the retrieved measures imuProcessor.process_accel(accelData); } }); cameraCfg.enable_stream(rs2_stream::RS2_STREAM_COLOR, 640, 480, rs2_format::RS2_FORMAT_BGR8, 30); cameraCfg.enable_stream(rs2_stream::RS2_STREAM_DEPTH, 640, 480, rs2_format::RS2_FORMAT_Z16, 30); rs2::pipeline_profile cameraProfile = cameraPipe.start(cameraCfg); // 创建一个对齐模块 rs2::align align2Depth(RS2_STREAM_DEPTH); // 对掩码进行腐蚀,定义腐蚀核 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); // 创建yolov8 Yolo yoloV8("/home/jetson/tmp/obstacle-detection-new1/workspace/best.transd.engine"); // 创建点云处理器 string cfgPath = ""; cv::Mat mK(4, 4, CV_32F); DepthProcessor depthProcessor(cfgPath, mK); depthProcessor.fx = 388.588; depthProcessor.fy = 388.588; depthProcessor.cx = 322.771; depthProcessor.cy = 236.947; bool isObject = false, isLabel = false; std::string label = ""; auto startTime = std::chrono::high_resolution_clock::now(); int count = 1; // 初始化时必须让摄像头看到地面 rs2::frameset allFrames = cameraPipe.wait_for_frames(); float3 theta = imuProcessor.get_theta(); rs2::frameset alignedFrames = align2Depth.process(allFrames); rs2::depth_frame depthFrame = alignedFrames.get_depth_frame(); rs2::video_frame colorFrame = alignedFrames.get_color_frame(); //获取深度图的长宽 int widthD = depthFrame.get_width(); int heightD = depthFrame.get_height(); cv::Mat depthMat(cv::Size(widthD, heightD), CV_16U, (void*)depthFrame.get_data(), cv::Mat::AUTO_STEP); // 将彩色图像转换为cv::Mat类型 int widthC = colorFrame.get_width(); int heightC = colorFrame.get_height(); cv::Mat colorMat(cv::Size(widthC, heightC), CV_8UC3, (void*)colorFrame.get_data(), cv::Mat::AUTO_STEP); // 定义变换矩阵(平移和旋转) Eigen::Affine3f transform = Eigen::Affine3f::Identity(); transform.translation() << 0.0, 0.0, 0.0; // 平移 transform.rotate(Eigen::AngleAxisf(-theta.x, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(0, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(theta.z + PI_FL/2, Eigen::Vector3f::UnitX())); int init_count = 0; float tmp_height = 0; // 关闭蜂鸣器 int output_pin_ = 13; GPIO::setmode(GPIO::BCM); //signal(SIGINT, signalHandler); GPIO::setup(output_pin_, GPIO::OUT, GPIO::LOW); GPIO::output(output_pin_, GPIO::LOW); //相机初始化 10次 while(true){ if(!depthProcessor.camHighInit(depthMat, transform)){ std::cout << "初始化失败" << std::endl; } else{ tmp_height += depthProcessor.camHigh; init_count ++; if(init_count == 10) break; } theta = imuProcessor.get_theta(); transform = Eigen::Affine3f::Identity(); transform.translation() << 0.0, 0.0, 0.0; transform.rotate(Eigen::AngleAxisf(-theta.x, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(0, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(theta.z + PI_FL/2, Eigen::Vector3f::UnitX())); allFrames = cameraPipe.wait_for_frames(); alignedFrames = align2Depth.process(allFrames); depthFrame = alignedFrames.get_depth_frame(); depthMat = cv::Mat(cv::Size(widthD, heightD), CV_16U, (void*)depthFrame.get_data(), cv::Mat::AUTO_STEP); } depthProcessor.camHigh = tmp_height / init_count; std::cout << "相机初始化:" << depthProcessor.camHigh << std::endl; // 超声波模块参数初始化 for(int i = 0 ; i < initial_times; i++)// 先初始化数组里的数为0 { dis0[i] = 0.0; dis1[i] = 0.0; } // 创建超声波线程 std::thread ultrasonicThread(ultrasound_play); ultrasonicThread.detach(); // 创建蜂鸣器线程 std::thread BeeThread(Bee); BeeThread.detach(); // // classes std::thread playAllClassThread(play_all_class); playAllClassThread.detach(); // 相机主循环 while(true) { //等待来自摄像机的下一组图像 rs2::frameset allFrames = cameraPipe.wait_for_frames(); float3 theta = imuProcessor.get_theta(); // 对齐深度图像和彩色图像 rs2::frameset alignedFrames = align2Depth.process(allFrames); // 获取对齐后的深度图像和彩色图像 rs2::depth_frame depthFrame = alignedFrames.get_depth_frame(); rs2::video_frame colorFrame = alignedFrames.get_color_frame(); // 检查是否成功获取数据 if (depthFrame && colorFrame) { auto start = std::chrono::high_resolution_clock::now(); // 将深度图像转换为cv::Mat类型 int widthD = depthFrame.get_width(); int heightD = depthFrame.get_height(); cv::Mat depthMat(cv::Size(widthD, heightD), CV_16U, (void*)depthFrame.get_data(), cv::Mat::AUTO_STEP); // 将彩色图像转换为cv::Mat类型 int widthC = colorFrame.get_width(); int heightC = colorFrame.get_height(); cv::Mat colorMat(cv::Size(widthC, heightC), CV_8UC3, (void*)colorFrame.get_data(), cv::Mat::AUTO_STEP); // 定义变换矩阵(平移和旋转) Eigen::Affine3f transform = Eigen::Affine3f::Identity(); transform.translation() << 0.0, 0.0, 0.0; // 平移 transform.rotate(Eigen::AngleAxisf(-theta.x, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(0, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(theta.z + PI_FL/2, Eigen::Vector3f::UnitX())); isObject = false; // 在深度图中检测最近障碍物,返回是否存在障碍物,0不存在,1存在 try { isObject = depthProcessor.obstacleDetect(depthMat, transform); if(isObject) { isObjectt = true; distt = depthProcessor.dist; } else isObjectt = false; } catch (const std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; isObject = false; } // YOLOv8分割+检测 BoxArray objs = yoloV8.detect(colorMat); if(isObject) { cv::rectangle(colorMat, cv::Point(depthProcessor.min_x, depthProcessor.min_y), cv::Point(depthProcessor.max_x, depthProcessor.max_y), cv::Scalar(0, 0, 255), 1); cv::String text = cv::format("dis:%.2f", depthProcessor.dist); cv::putText(colorMat, text, cv::Point(depthProcessor.min_x, depthProcessor.min_y+10), 0, 0.7, cv::Scalar(0,0,255), 1, 8); } float tmp_depth = 100; if(!classes.empty()){ classes.clear(); } // 输出识别框信息 for(Box &obj : objs) { cout << yoloV8.cocoLabels[obj.classLabel] << " "; } cout << endl; for(Box &obj : objs) { float depth = 0; int i = 0; cv::Mat mask(obj.seg->height, obj.seg->width, CV_8U, obj.seg->data); int objWidth = obj.right - obj.left; int objHeight = obj.bottom - obj.top; cv::resize(mask, mask, cv::Size(objWidth, objHeight)); // 进行腐蚀操作 cv::erode(mask, mask, kernel); // 将掩码绘制到RGB图像上 //cv::Rect roi(obj.left, obj.top, obj_width, obj_height); //cv::Mat maskColor; //cv::cvtColor(mask, maskColor, cv::COLOR_GRAY2BGR); //maskColor.copyTo(colorMat(roi)); for(int x = 0; x < objWidth; x++){ for(int y = 0 ;y < objHeight; y++){ if(mask.at(y, x) > 10){ uint16_t d = depthMat.at(obj.top + y, obj.left + x); if(d > 300) { depth += depthMat.at(obj.top + y, obj.left + x); i++; } } } } depth = depth/(i*1000); if(isObject){ if (depthProcessor.max_x > obj.left && depthProcessor.min_x < obj.right && depthProcessor.max_y > obj.top && depthProcessor.min_y < obj.bottom){ double rate = depthProcessor.IOU(depthProcessor.max_x, depthProcessor.min_x, depthProcessor.max_y, depthProcessor.min_y, obj.right, obj.left, obj.bottom, obj.top); if(rate >= 0.3){ isLabel = true; if(tmp_depth > depth){ tmp_depth = depth; label = yoloV8.cocoLabels[obj.classLabel]; } else isLabel = false; if(!labelCheck(label)){ // 如果标签不在所需要的标签中 isLabel = false; } } } } // if(/*isObject && */isLabel){ // // if(abs(depthProcessor.dist - depth) > 0.2){ // // isLabel = false; // // std::cout << " depthProcessor.dist = " << depthProcessor.dist << " depth =" << depth << std::endl; // // } // // else // if(tmp_depth > depth){ // tmp_depth = depth; // std::cout << "something near" <(endTime - startTime); // 语音播报,间隔大于等于秒在进行下一次 if(duration.count() >= 7 || count == 1){ if(ToPlay){ // 超声波播报 std::cout << std::endl << "************************有障碍物;dis0_d: " << dis0_d << "|| dis1_d: " << dis1_d << std::endl; // play_voice("object"); // Bee(300000); // 回置全局变量 // ToPlay = false; voice_status = 0; startTime = std::chrono::high_resolution_clock::now(); count++; }else{ // 相机播报 if(isObject && isLabel){ isLabel = false; std::cout << std::endl; std::cout << "前方" << depthProcessor.dist << "米存在" << label << std::endl; { voice_status = 1; } play_voice(label); voice_status = 0; startTime = std::chrono::high_resolution_clock::now(); count++; }else if(isObject){ std::cout << std::endl; std::cout << "前方" << depthProcessor.dist << "米有障碍物"<< std::endl; { voice_status = 2; } play_voice(label); voice_status = 0; startTime = std::chrono::high_resolution_clock::now(); count++; } } } isLabel = false; // 回置count if(count == 100){ count = 2; } cv::imshow("RGB Image", colorMat); if (cv::waitKey(5) == 27) break; auto end = std::chrono::high_resolution_clock::now(); auto duration_test = std::chrono::duration_cast(end - start).count(); std::cout << "Time taken: " << duration_test << " microseconds" << std::endl; } } return 0; }