【opencv】示例-videocapture_openni.cpp 深度数据获取和处理的示例

2d520a22982137dccb3510682f626946.png

该代码是一个与使用OpenCV进行深度传感器捕获和处理相关的程序的一部分。主要功能包括处理Kinect或XtionPRO等深度传感器数据,解析命令行参数,打开视频捕获设备,以及在GUI上显示深度图,彩色图像,和红外图像等。代码中使用了OpenCV库函数进行视频捕获和图像处理。

// 包含OpenCV库中处理视频的头文件
#include "opencv2/videoio/videoio.hpp"
// 包含OpenCV库中高级GUI的头文件
#include "opencv2/highgui.hpp"
// 包含OpenCV库中图像处理的头文件
#include "opencv2/imgproc.hpp"// 包含标准输入输出流库
#include <iostream>// 使用OpenCV命名空间中的所有名称
using namespace cv;
// 使用标准命名空间中的所有名称
using namespace std;// 帮助函数,用于输出程序的帮助信息
static void help()
{cout << "\nThis program demonstrates usage of depth sensors (Kinect, XtionPRO,...).\n""The user gets some of the supported output images.\n""\nAll supported output map types:\n"// 下面列出了各种支持的传感器输出类型以及它们的格式说明"1.) Data given from depth generator\n"// 深度图,以毫米为单位"   CAP_OPENNI_DEPTH_MAP            - depth values in mm (CV_16UC1)\n"// 点云数据,以米为单位"   CAP_OPENNI_POINT_CLOUD_MAP      - XYZ in meters (CV_32FC3)\n"// 视差图,以像素为单位"   CAP_OPENNI_DISPARITY_MAP        - disparity in pixels (CV_8UC1)\n"// 视差图的浮点格式"   CAP_OPENNI_DISPARITY_MAP_32F    - disparity in pixels (CV_32FC1)\n"// 有效深度掩码,标志有效的像素点"   CAP_OPENNI_VALID_DEPTH_MASK     - mask of valid pixels (not occluded, not shaded etc.) (CV_8UC1)\n""2.) Data given from RGB image generator\n"// RGB彩色图像"   CAP_OPENNI_BGR_IMAGE            - color image (CV_8UC3)\n"// 灰度图像"   CAP_OPENNI_GRAY_IMAGE           - gray image (CV_8UC1)\n""2.) Data given from IR image generator\n"// 红外图像"   CAP_OPENNI_IR_IMAGE             - gray image (CV_16UC1)\n"<< endl;
}// 定义一个函数,来为视差图像上色
static void colorizeDisparity( const Mat& gray, Mat& rgb, double maxDisp=-1.f)
{// 确保传入的灰度图像不为空,并且数据类型为CV_8UC1CV_Assert( !gray.empty() );CV_Assert( gray.type() == CV_8UC1 );// 如果maxDisp小于等于0,则重新计算maxDisp的最大值if( maxDisp <= 0 ){maxDisp = 0;minMaxLoc( gray, 0, &maxDisp );}// 创建大小和输入灰度图像相同,类型为CV_8UC3的彩色图像,并初始化为全0rgb.create( gray.size(), CV_8UC3 );rgb = Scalar::all(0);// 如果最大视差小于1,则直接返回if( maxDisp < 1 )return;// 创建临时矩阵,将灰度图像转换为彩色图像,并进行彩色映射Mat tmp;convertScaleAbs(gray, tmp, 255.f / maxDisp);applyColorMap(tmp, rgb, COLORMAP_JET);
}// 定义一个函数,获取最大视差值
static float getMaxDisparity( VideoCapture& capture )
{// 定义最小检测深度为400毫米const int minDistance = 400; // mm// 获取深度生成器的基线距离值float b = (float)capture.get( CAP_OPENNI_DEPTH_GENERATOR_BASELINE ); // mm// 获取深度生成器的焦距值float F = (float)capture.get( CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); // pixels// 计算并返回最大视差return b * F / minDistance;
}// 定义一个函数,用于打印命令行参数的帮助信息
static void printCommandLineParams()
{cout << "-cd=       Colorized disparity? (0 or 1; 1 by default) Ignored if disparity map is not selected to show." << endl;cout << "-fmd=      Fixed max disparity? (0 or 1; 0 by default) Ignored if disparity map is not colorized (-cd 0)." << endl;cout << "-mode=     image mode: resolution and fps, supported three values:  0 - CAP_OPENNI_VGA_30HZ, 1 - CAP_OPENNI_SXGA_15HZ," << endl;cout << "          2 - CAP_OPENNI_SXGA_30HZ (0 by default). Ignored if rgb image or gray image are not selected to show." << endl;cout << "-m=        Mask to set which output images are need. It is a string of size 6. Each element of this is '0' or '1' and" << endl;cout << "          determine: is depth map, disparity map, valid pixels mask, rgb image, gray image need or not (correspondently), ir image" << endl ;cout << "          By default -m=010100 i.e. disparity map and rgb image will be shown." << endl ;cout << "-r=        Filename of .oni video file. The data will grabbed from it." << endl ;
}
// 打印命令行参数信息
static void printCommandLineParams2()
{cout << "-cd=       是否对视差进行彩色着色?(0 或 1;默认为 1)如果未选择视差图像,则忽略。" << endl;cout << "-fmd=      是否使用固定的最大视差值?(0 或 1;默认为 0)如果未对视差图进行彩色着色(-cd 0),则忽略。" << endl;cout << "-mode=     图像模式:分辨率和帧率,支持三个值:0 - CAP_OPENNI_VGA_30HZ,1 - CAP_OPENNI_SXGA_15HZ," << endl;cout << "          2 - CAP_OPENNI_SXGA_30HZ(默认为 0)。如果未选择 RGB 图像或灰度图像进行显示,则忽略。" << endl;cout << "-m=        设置需要的输出图像的掩码。它是一个长度为 6 的字符串。每个元素为 '0' 或 '1'," << endl;cout << "          分别表示是否需要深度图、视差图、有效像素掩码、彩色图像、灰度图像、红外图像(对应)。" << endl;cout << "          默认为 -m=010100,即显示视差图和彩色图像。" << endl;cout << "-r=        .oni 视频文件的文件名。数据将从该文件中获取。" << endl;
}
// 定义一个函数用于解析命令行参数,并根据参数设定程序的行为
static void parseCommandLine( int argc, char* argv[], bool& isColorizeDisp, bool& isFixedMaxDisp, int& imageMode, bool retrievedImageFlags[],string& filename, bool& isFileReading )
{// 清理filename以准备新的输入filename.clear();// 创建命令行解析器对象,并使用定义的参数格式初始化cv::CommandLineParser parser(argc, argv, "{h help||}{cd|1|}{fmd|0|}{mode|-1|}{m|010100|}{r||}");// 如果命令行中有帮助标志,则打印帮助信息后退出程序if (parser.has("h")){help();printCommandLineParams();exit(0);}// 根据命令行参数设置是否为视差图上色等变量的值isColorizeDisp = (parser.get<int>("cd") != 0);isFixedMaxDisp = (parser.get<int>("fmd") != 0);imageMode = parser.get<int>("mode");// 获取"-m"标志的参数值,用于确定需要哪些输出图像int flags = parser.get<int>("m");// 判断是否有"-r"标志,并根据这个标志设置是否从文件中读取数据以及文件名称isFileReading = parser.has("r");if (isFileReading)filename = parser.get<string>("r");// 检查解析的参数是否有错误,如果有,则打印错误信息并退出程序if (!parser.check()){parser.printErrors();help();exit(-1);}// 判断"-m"标志的参数值是否正确,如果没有选中任何输出图像,则退出程序if (flags % 1000000 == 0){cout << "No one output image is selected." << endl;exit(0);}// 解析"-m"标志的参数值,设置哪些图像将被程序获取和显示for (int i = 0; i < 6; i++){retrievedImageFlags[5 - i] = (flags % 10 != 0);flags /= 10;}
}
/** To work with Kinect or XtionPRO the user must install OpenNI library and PrimeSensorModule for OpenNI and* configure OpenCV with WITH_OPENNI flag is ON (using CMake).*/
// 主函数,定义程序入口
int main( int argc, char* argv[] )
{// 定义了一系列变量来存储从命令行解析后的参数bool isColorizeDisp, isFixedMaxDisp;   // 是否给视差图上色,是否固定最大视差值int imageMode;                         // 图像模式参数bool retrievedImageFlags[6];           // 提取图像的标志位数组string filename;                       // 视频文件名bool isVideoReading;                   // 标志是否从视频文件中读取数据// 解析命令行参数,并将解析结果存储在之前定义的变量中parseCommandLine( argc, argv, isColorizeDisp, isFixedMaxDisp, imageMode, retrievedImageFlags, filename, isVideoReading );cout << "Device opening ..." << endl;  // 通知用户设备正在打开VideoCapture capture;                   // 定义视频捕获对象// 根据是否是读取视频文件的标志位来确定打开视频文件还是打开相机设备if( isVideoReading )capture.open( filename );          // 打开视频文件else{capture.open( CAP_OPENNI2 );       // 尝试使用OpenNI2接口打开相机设备if( !capture.isOpened() )          // 如果使用OpenNI2接口打开失败capture.open( CAP_OPENNI );    // 尝试使用更旧版本的OpenNI接口打开相机设备}cout << "done." << endl;               // 设备打开完成// 检查视频捕获对象是否成功打开if( !capture.isOpened() ){cout << "Can not open a capture object." << endl; // 如果打开失败,输出错误信息return -1;                                        // 返回错误码-1}// 如果不是从视频文件中读取并且已指定图像模式,则设置相应的图像模式if( !isVideoReading && imageMode >= 0 ){bool modeRes = false;               // 用于存储设置图像模式的操作结果// 使用switch结构来根据图像模式参数设置对应的图像输出模式switch ( imageMode ){case 0:// 设置VGA分辨率下30HZ的刷新率modeRes = capture.set( CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CAP_OPENNI_VGA_30HZ );break;case 1:// 设置SXGA分辨率下15HZ的刷新率modeRes = capture.set( CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CAP_OPENNI_SXGA_15HZ );break;case 2:// 设置SXGA分辨率下30HZ的刷新率modeRes = capture.set( CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CAP_OPENNI_SXGA_30HZ );break;// 下面的模式仅被Xtion Pro Live支持case 3:// 设置QVGA分辨率下30HZ的刷新率modeRes = capture.set( CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CAP_OPENNI_QVGA_30HZ );break;case 4:// 设置QVGA分辨率下60HZ的刷新率modeRes = capture.set( CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CAP_OPENNI_QVGA_60HZ );break;default:// 报告不支持的图像模式属性错误CV_Error( Error::StsBadArg, "Unsupported image mode property.\n");}// 如果设备不支持当前设置的图像模式,使用默认模式if (!modeRes)cout << "\nThis image mode is not supported by the device, the default value (CV_CAP_OPENNI_SXGA_15HZ) will be used.\n" << endl;}// 根据需要开启深度、颜色和红外图像生成器if (retrievedImageFlags[0] || retrievedImageFlags[1] || retrievedImageFlags[2])capture.set(CAP_OPENNI_DEPTH_GENERATOR_PRESENT, true);  // 如果需要深度图像,开启深度生成器elsecapture.set(CAP_OPENNI_DEPTH_GENERATOR_PRESENT, false); // 否则关闭深度生成器if (retrievedImageFlags[3] || retrievedImageFlags[4])capture.set(CAP_OPENNI_IMAGE_GENERATOR_PRESENT, true);  // 如果需要彩色或灰度图像,开启图像生成器elsecapture.set(CAP_OPENNI_IMAGE_GENERATOR_PRESENT, false); // 否则关闭图像生成器if (retrievedImageFlags[5])capture.set(CAP_OPENNI_IR_GENERATOR_PRESENT, true);     // 如果需要红外图像,开启红外生成器elsecapture.set(CAP_OPENNI_IR_GENERATOR_PRESENT, false);    // 否则关闭红外生成器// 打印摄像头相关设置的信息if (capture.get(CAP_OPENNI_DEPTH_GENERATOR_PRESENT))  // 如果深度生成器已启用{// 打印深度生成器的输出模式相关信息cout << "\nDepth generator output mode:" << endl <<"FRAME_WIDTH      " << capture.get(CAP_PROP_FRAME_WIDTH) << endl <<  // 输出帧宽度"FRAME_HEIGHT     " << capture.get(CAP_PROP_FRAME_HEIGHT) << endl << // 输出帧高度"FRAME_MAX_DEPTH  " << capture.get(CAP_PROP_OPENNI_FRAME_MAX_DEPTH) << " mm" << endl <<  // 输出最大深度值,单位毫米"FPS              " << capture.get(CAP_PROP_FPS) << endl <<  // 输出帧率"REGISTRATION     " << capture.get(CAP_PROP_OPENNI_REGISTRATION) << endl;  // 输出是否进行深度到彩色图像的配准}else{cout << "\nDevice doesn't contain depth generator or it is not selected." << endl;  // 如果没有启用深度生成器,输出提示}if( capture.get( CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) ) // 如果图像生成器已启用{// 打印图像生成器的输出模式相关信息cout <<"\nImage generator output mode:" << endl <<"FRAME_WIDTH   " << capture.get( CAP_OPENNI_IMAGE_GENERATOR+CAP_PROP_FRAME_WIDTH ) << endl <<  // 输出帧宽度"FRAME_HEIGHT  " << capture.get( CAP_OPENNI_IMAGE_GENERATOR+CAP_PROP_FRAME_HEIGHT ) << endl << // 输出帧高度"FPS           " << capture.get( CAP_OPENNI_IMAGE_GENERATOR+CAP_PROP_FPS ) << endl;  // 输出帧率}else{cout << "\nDevice doesn't contain image generator or it is not selected." << endl;  // 如果没有启用图像生成器,输出提示}if( capture.get(CAP_OPENNI_IR_GENERATOR_PRESENT) )  // 如果红外生成器已启用{// 打印红外生成器的输出模式相关信息cout <<"\nIR generator output mode:" << endl <<"FRAME_WIDTH   " << capture.get(CAP_OPENNI_IR_GENERATOR + CAP_PROP_FRAME_WIDTH) << endl <<  // 输出帧宽度"FRAME_HEIGHT  " << capture.get(CAP_OPENNI_IR_GENERATOR + CAP_PROP_FRAME_HEIGHT) << endl << // 输出帧高度"FPS           " << capture.get(CAP_OPENNI_IR_GENERATOR + CAP_PROP_FPS) << endl;  // 输出帧率}else{cout << "\nDevice doesn't contain IR generator or it is not selected." << endl;  // 如果没有启用红外生成器,输出提示}// 进入无限循环,不断捕获并显示图像for(;;){// 声明多个Mat类型的变量,用于存储不同种类的图像数据Mat depthMap; // 存储深度图像Mat validDepthMap; // 存储有效深度掩膜Mat disparityMap; // 存储视差图Mat bgrImage; // 存储彩色图像Mat grayImage; // 存储灰度图像Mat irImage; // 存储红外图像// 尝试从捕获设备中抓取一帧数据if( !capture.grab() ){cout << "Can not grab images." << endl; // 如果抓取失败,输出错误信息return -1; // 返回-1,结束程序}else // 如果成功抓取到数据{// 判断是否抓取到深度图if( retrievedImageFlags[0] && capture.retrieve( depthMap, CAP_OPENNI_DEPTH_MAP ) ){const float scaleFactor = 0.05f; // 设置深度图的显示比例因子Mat show; // 用于显示的图像depthMap.convertTo( show, CV_8UC1, scaleFactor ); // 将深度图转换为8位无符号单通道图像用于显示imshow( "depth map", show ); // 显示深度图}// 判断是否抓取到视差图if( retrievedImageFlags[1] && capture.retrieve( disparityMap, CAP_OPENNI_DISPARITY_MAP ) ){if( isColorizeDisp ) // 如果需要给视差图上色{Mat colorDisparityMap; // 存储上色后的视差图// 上色视差图,并根据是否固定最大视差来决定颜色化的方式colorizeDisparity( disparityMap, colorDisparityMap, isFixedMaxDisp ? getMaxDisparity(capture) : -1 );Mat validColorDisparityMap; // 存储有效的上色视差图(非零部分)// 只复制视差图中的非零部分colorDisparityMap.copyTo( validColorDisparityMap, disparityMap != 0 );imshow( "colorized disparity map", validColorDisparityMap ); // 显示上色后的视差图}else{imshow( "original disparity map", disparityMap ); // 显示原始视差图}}// 判断是否抓取到有效深度掩膜,并进行显示if( retrievedImageFlags[2] && capture.retrieve( validDepthMap, CAP_OPENNI_VALID_DEPTH_MASK ) )imshow( "valid depth mask", validDepthMap );// 判断是否抓取到彩色图像,并进行显示if( retrievedImageFlags[3] && capture.retrieve( bgrImage, CAP_OPENNI_BGR_IMAGE ) )imshow( "rgb image", bgrImage );// 判断是否抓取到灰度图像,并进行显示if( retrievedImageFlags[4] && capture.retrieve( grayImage, CAP_OPENNI_GRAY_IMAGE ) )imshow( "gray image", grayImage );// 判断是否抓取到红外图像,并进行转换和显示if( retrievedImageFlags[5] && capture.retrieve( irImage, CAP_OPENNI_IR_IMAGE ) ){Mat ir8; // 存储用于显示的8位红外图像irImage.convertTo(ir8, CV_8U, 256.0 / 3500, 0.0); // 将红外图像转换为8位格式以显示更多细节imshow("IR image", ir8); // 显示红外图像}}// 等待30毫秒,检查是否有按键操作if( waitKey( 30 ) >= 0 )break; // 如果有按键按下,则退出循环}return 0; // 程序运行成功,返回0
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 自定义快捷指令(docker

vi /root/.bashrc alias disdocker images alias dpsdocker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}" 保存退出后使用sourece /root/.bashrc 让其立即生效 sourece /root/.bashrc

byobu

byobu 终端多路复用器 一、byobu 安装二、byobu 使用三、其他终端多路复用器四、ssh byobu 远程协作 系统环境: linux(ubuntu,debian,kali) 一、byobu 安装 byobu 是包装过的tmux #sudo apt install tmux sudo apt install byobubyobu二、byobu 使用 创建窗口: Ctrl a c…

HashMap的扩容看这一篇足够

在Java中&#xff0c;对于HashMap这样的实现&#xff0c;put方法是用来将一个键值对插入到Map中的核心方法。以下是HashMap类中put方法的大致执行流程&#xff1a; 计算Hash值&#xff1a; 首先&#xff0c;put方法会接收一个键&#xff08;Key&#xff09;和一个值&#xff0…

攻防世界13-simple_php

13-simple_php <?php show_source(*__FILE__*);//高亮文件 include("config.php");//文件包含在内 $a$_GET[a];//获得a $b$_GET[b];//获得b if($a0 and $a){ //判断a是否满足条件echo $flag1; //满足就输出flag1 } if(is_numeric($b)){ //判断b的条件&#x…

Python | Leetcode Python题解之第26题删除有序数组中的重复项

题目&#xff1a; 题解&#xff1a; class Solution:def removeDuplicates(self, nums: List[int]) -> int:if not nums:return 0n len(nums)fast slow 1while fast < n:if nums[fast] ! nums[fast - 1]:nums[slow] nums[fast]slow 1fast 1return slow

Git可视化工具 - 推荐

概述 Git版本管理工具是我们日常开发中常用的工具&#xff0c;熟练使用它可以提高我们的工作效率。 当然老司机基本使用命令行的方式进行操作&#xff0c;新手可借助可视化工具来进行过渡&#xff0c;命令行与可视化工具结合使用来加深对Git的熟悉程度。 下面推荐两个较受欢迎…

MySQL 试图

视图功能在 5.0 以后的版本启用 视图是一张虚表。数据表确实包含了具体数据并且保存到硬盘中的实表。视图使用数据检索语句动态生 成的一张虚表。每一次数据服务重启或者系统重启之后&#xff0c;在数据库服务启动期间&#xff0c;会使用创建视图的语 句重新生成视图中的数据&…

BERT论文解读及情感分类实战

文章目录 简介BERT文章主要贡献BERT模型架构技术细节任务1 Masked LM&#xff08;MLM&#xff09;任务2 Next Sentence Prediction (NSP)模型输入 下游任务微调GLUE数据集SQuAD v1.1 和 v2.0NER 情感分类实战IMDB影评情感数据集数据集构建模型构建超参数设置训练结果注意事项 简…

学习Rust的第三天:猜谜游戏

基于Steve Klabnik的《The Rust Programming Language》一书。今天我们在rust中建立一个猜谜游戏。 Introduction 介绍 We will build a game that will pick a random number between 1 to 100 and the user has to guess the number on a correct guess the user wins. 我们将…

Nginx内存池相关源码剖析(六)外部资源释放和内存池销毁

ngx_destroy_pool函数 先执行回调函数释放所有的外部资源&#xff0c;然后free释放所有的大块内存和小块内存。 // 释放外部资源&#xff0c;销毁内存池 void ngx_destroy_pool(ngx_pool_t *pool) {ngx_pool_t *p, *n;ngx_pool_large_t *l;ngx_pool_cleanup_t *…

用海豚调度器定时调度从Kafka到HDFS的kettle任务脚本

在实际项目中&#xff0c;从Kafka到HDFS的数据是每天自动生成一个文件&#xff0c;按日期区分。而且Kafka在不断生产数据&#xff0c;因此看看kettle是不是需要时刻运行&#xff1f;能不能按照每日自动生成数据文件&#xff1f; 为了测试实际项目中的海豚定时调度从Kafka到HDF…

【计算机网络】常用编码方式+例题(曼彻斯特编码、差分曼彻斯特编码...)

常用编码方式例题 常用编码方式练习画出四种编码20221题342015题342013题34 常用编码方式 练习 画出四种编码 20221题34 这个题目的考察是差分曼彻斯特编码。 差分曼彻斯特编码在每个码元的中间时刻电平都会发生跳变。与曼彻斯特编码不同的是&#xff1a;电平的跳变仅代表时钟…

C++ ─── 操作符重载和赋值重载

目录 赋值运算符重载 运算符重载 赋值运算符重载&#xff08;赋值重载operator&#xff09; 前置和后置重载 赋值运算符重载 运算符重载 C为了增强代码的可读性引入了运算符重载 &#xff0c; 运算符重载是具有特殊函数名的函数 &#xff0c;也具有其返回值类型&#xff0c…

SQL Server 存储函数(funGetId):唯一ID

系统测试时批量生成模拟数据&#xff0c;通过存储函数生成唯一ID。 根据当前时间生成唯一ID&#xff08;17位&#xff09; --自定义函数&#xff1a;根据当前时间组合成一个唯一ID字符串:yearmonthdayhourminutesecondmillisecond drop function funGetId;go--自定义函数&…

PHP Storm 2024.1使用

本文讲的是phpstorm 2024.1最新版本激活使用教程&#xff0c;本教程适用于windows操作系统。 1.先去idea官网下载phpstorm包&#xff0c;我这里以2023.2最新版本为例 官网地址&#xff1a;https://www.jetbrains.com/zh-cn/phpstorm/ 2.下载下来后安装&#xff0c;点下一步 …

RAG 如何消除大模型幻觉

什么是大模型幻觉 假设我们有一个基于大型生成模型&#xff08;如GPT-3&#xff09;的问答系统&#xff0c;该系统用于回答药企内部知识库中的问题。我们向其提出一个问题&#xff1a;“阿司匹林的主要药理作用是什么&#xff1f;” 正确的答案应该是&#xff1a;“阿司匹林主…

记录一次汇川PLC通信的问题(06,16功能码相关)

先看下图&#xff0c;使用的06功能码&#xff0c;但其实在汇川的功能码选项内选择的是16&#xff0c;汇川的软件内根本没有06功能码&#xff0c;它会在你使用16功能码的时候去判断如果写寄存器的个数是1个就默认切换到06功能码&#xff0c;这就非常难受了&#xff0c;因为对接设…

【数据可视化包Matplotlib】Matplotlib基本绘图方法

目录 一、Matplotlib绘图的基本流程&#xff08;一&#xff09;最简单的绘图&#xff08;仅指定y的值&#xff09;&#xff08;二&#xff09;更一般的绘图&#xff08;同时指定x和y的值&#xff09;&#xff08;三&#xff09;增加更多的绘图元素 二、布局相关的对象——Figur…

SAP 技巧篇:Script脚本模拟人工操作批量录入数据

“ 现在大环境都讲人工智能、自动化办公等场景的应用&#xff0c;这里我们介绍一下SAP本身自带的自动化工具” 文章最后附最终脚本 01 — 背景需求 SAP&#xff1a;批量录入工具&#xff1a;LSMW/BDC/Script 三大工具 LSMW&#xff1a;应用场景多&#xff0c;实现方法多&am…

测出Bug就完了?从4个方面教你Bug根因分析

01 现状及场景 &#x1f3af; 1.缺失bug根因分析环节 工作10年&#xff0c;虽然不是一线城市&#xff0c;也经历过几家公司&#xff0c;规模大的、规模小的都有&#xff0c;针对于测试行业很少有Bug根因环节&#xff0c;主流程基本上都是测试提交bug-开发修改-测试验证-发送报…