2.RV1126-OPENCV Mat理解和AT函数
一.Mat概念
Mat 是整个图像存储的核心也是所有图像处理的最基础的类,Mat 主要存储图像的矩阵类型,包括向量、矩阵、灰度或者彩色图像等等。Mat由两部分组成:矩阵头,矩阵数据。矩阵头是存储图像的长度、宽度、色彩信息等头部信息;矩阵数据则是存储具体的图像数据。(我的理解就是,Mat是把图像分为一块一块矩阵类型保存,矩阵头显示这张图片基本信息,如这张图片多大,是不是彩色;具体的信息存储由矩阵数据存储)。
二.Mat通道
图中C1,C2,C3,C4代表几通道 ;前面CV_8U,8S,16U,16S,32U,32S代表用什么类型存储,例如:CV_8U就是用8位无符号类型存储,CV_8S就是用8位有符号存储。
- 单通道(灰度图),就是图片是灰色的
- 双通道(二值图像),就是黑白照片
- 三通道(RGB 彩色图像)
- 四通道(带 Alpha 的四通道图像),就是ARGB图像,更好看一点。
三.Mat创建和构造方法
- Mat(int rows, int cols, int type);
重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type
rows:行数,也指的是图像的高度,height。
cols:列数,也指的是图像的宽度,width。
type:通道类型,具体的看上面的图
示例:Mat t1 = Mat(300,300,CV_8UC1),这指的是创建一个 width:300,height:300,单通道的灰度图像.
- Mat(Size size, int type);
重载的构造函数,这个构造函数在创建的时候,需要传入 Size 类和类型。
第一个传参:Size 结构体,Size(width,height)
第二个传参:type 通道类型,具体的看上面的图
示例:Mat t2 = Mat(Size(300,300),CV_8SC3),这指的是创建一个 width:300,height:300,三通道的灰度图像
- Mat(int rows, int cols, int type, const Scalar& s);
重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols、存储类型 type、还有 Scalar 颜色标量。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
第四个传参:Scalar 颜色标量,Scalar(v0,v1,v2,v3),v0,v1,v2,v3 分别对应 OPENCV 颜色分量的四个值
示例: Mat mat = Mat(300,300,CV_8UC3,Scalar(255,255,255));表示的是创建cols:300,rows:300,三通道的灰度,颜色标量为白色的图像
- Mat::zeros(rows,cols,type);
重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type。ZEROS 相当于创建一张黑色的图片,每个像素通道为 0,并且 Scalar(0,0,0)。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
示例: Mat::zeros(300,300,CV_8SC3);,这指的是创建一个 width:300,height:300,三通道的彩色图像,Scalar(0,0,0),相当于Mat mat = Mat(300,300,CV_8SC3,Scalar(0,0,0));
- Mat::ones(rows,cols,type);
重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type。ONES 相当于每个像素第一个通道为 1,后面两个通道为 0。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
示例: Mat::ones(300,300,CV_8SC3),这指的是创建一个 width:300,height:300, 三通道的彩色图像,Scalar(1,0,0),这等同于 Mat mat = Mat(300,300,CV_8SC3,Scalar(1,0,0));
四. imread读取图片信息和imwrite写入数据
- imread:读取图片信息。
Mat imread( const String& filename, int flags = IMREAD_COLOR );
第一个参数:filename 图片的名称,名称可以是绝对路径也可以是相对路径
第二个参数:flags 标识符,flags 标识符默认为 IMREAD_COLOR。flags 一般分为三种:
IMREAD_UNCHANGED(<0)按原样加载图像(包括 alpha 通道(如果存在)
IMREAD_GRAYSCALE(0)将图像作为强度加载(灰白照片)
IMREAD_COLOR(> 0)以 RGB 格式加载图像(彩色照片)
返回值:Mat 矩阵
- 例如:读取彩色三通道图片
Mat img_mat = imread("frame1.jpg");
printf("width = %d, height = %d, channels = %d\n", img_mat.cols, img_mat.rows, img_mat.channels());
...........................................................................................
输出结果:width = 1920, height = 1080, channels = 3
- 例如:读取灰白单通道图片
Mat img_mat_gray = imread("gray_frame1.jpg", IMREAD_GRAYSCALE);
printf("img_mat_gray_width = %d, img_mat_gray_height = %d, img_mat_gray_channels = %d\n", img_mat_gray.cols,img_mat_gray.rows, img_mat_gray.channels());
.................................................................................................................
输出的结果:img_mat_gray_width = 1920, img_mat_gray_height = 1080, img_mat_gray_channels = 1
2. imwrite:保存图片
imwrite(const String& filename, InputArray image, const std::vector<int>& params);
第一个传参:filename 表示要保存的文件名
第二个传参:image 表示需要保存的图像数据
第三个传参:params 保存图像可选参数,主要是设置图像的质量,设置规则具体的我们来看看,该参数需要按照参数 id+参数值成对出现,可以出现多对参数值(比如 (paramId_1, paramValue_1, paramId_2, paramValue_2, ...)),但必须保证这些参数对是相关的,比如保存 JPG 图像时,只能使用和 JPEG 相关的参数 ID 进行组合使用。这里的 ID 基本上是 cv::ImwriteFlags。
- 例如:使用默认的方式 imwrite 保存图片
Mat mat = Mat(300,300,CV_8UC3,Scalar(218,112,214));
imwrite("mat_demo.jpg", mat);
。。。。。。。。。。。。。。。。。。
上面是使用默认的方法保存图片,这种方法的所有参数都是默认选项。出来图片就是:
- 使用 params 的方式 imwrite 保存图片
Mat quality_frame1_mat = imread("frame1.jpg");
std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 40};
imwrite("quality_mat_demo.jpg", quality_frame1_mat , params);
。。。。。。。。。。。。。。。。。。。。。。。。。
这种方法使用的是 params 参数的方式去设置,上面我们设置了图像的质量在 40,大家如果想设置其他功能可以参考上面的枚举进行设置。经过编码质量 40 的处理后的图像大小小于原图像大小,这说明编码质量关乎着文件的大小和画面的质量。
五.代码具体
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv; //Must Need Write cv
using namespace std;int main()
{//构造参数Mat t0 = Mat(300,300,CV_8UC1); //Create a 300x300 single channel matrixMat t1 = Mat(Size(200,200),CV_8UC1); //Create a 300x300 single channel matrixMat t2 = Mat(100,100,CV_8UC1,Scalar(255,255,255)); //Create a 300x300 single channel matrixMat t3 = Mat::zeros(300,300,CV_8UC1); //Create a 300x300 single channel matrixMat t4 = Mat::ones(200,200,CV_8UC1); //Create a 300x300 single channel matrixstd::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 40};//imwrite写入数据imwrite("t0.jpg",t0);imwrite("t1.jpg",t1);imwrite("t2.jpg",t2);imwrite("t3.jpg",t3,params);imwrite("t4.jpg",t4);//imread读取数据Mat a0 = imread("t0.jpg");Mat a1 = imread("t3.jpg");Mat a2 = imread("t4.jpg",IMREAD_GRAYSCALE);printf("a0 heigh:%d weigh: %d channel:%d\n",a0.rows,a0.cols,a0.channels());printf("a3 heigh:%d weigh: %d channel:%d\n",a2.rows,a2.cols,a2.channels());return 0;
}
六.AT函数
1.作用
AT函数:就是用于修改Mat矩阵的像素值(上面用Mat创建的图片,这个图片都是一格一格像素点形成的,我们要想修改图片颜色,就要用到AT函数对像素点值修改就行)。AT 函数的修改一般需要循环 cols 和 rows 然后对每个像素点进行修改。
2. 定义
at<typename>(int i, int j)
第一个参数:typename 指的是 OPENCV 的向量类型,(总结:1,2,3,4就是几通道,也可以理解为几维图像;后面b,s,w,i之类就是用什么类型读取,整型,还是字符读取),向量类型如下:
typedef Vec<uchar, 2> Vec2b:uchar 类型的数组,长度为 2, 它表示的是二维图像的位置信息、尺寸等等
typedef Vec<uchar, 3> Vec3b:uchar 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 uchar 类型
typedef Vec<uchar, 4> Vec4b:uchar 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 uchar 类型
typedef Vec<short, 2> Vec2s:short 类型的数组,长度为 2, 它表示的是二维图像的位置信息、尺寸等等,但不能做像素处理
typedef Vec<short, 3> Vec3s:short 类型的数组,长度为 3, 它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 short 类型
typedef Vec<short, 4> Vec4s:short 类型的数组,长度为 4, 它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 short 类型
typedef Vec<ushort, 2> Vec2w:ushort 类型的数组,长度为 2,它表示的是二维图像的位置信息、尺寸等等,但不能做像素处理
typedef Vec<ushort, 3> Vec3w:ushort 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 ushort 类型
typedef Vec<ushort, 4> Vec4w:ushort 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 ushort 类型
typedef Vec<int, 2> Vec2i: int 类型的数组,长度为 2, 它表示的是一个包含 2 个整数的元素向量,并不能直接表示通道数
typedef Vec<int, 4> Vec4i: int 类型的数组,长度为 4, 它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 int 类型
typedef Vec<int, 6> Vec6i: int 类型的数组,长度为 6, 它常用于表示六维图像,包括:坐标、描述子、颜色直方等等,但是不能对六维图像直接进行处理
typedef Vec<int, 8> Vec8i: int 类型的数组,长度为 8, 它常用于表示八维图像,包括:坐标、描述子、颜色直方等等,但是不能对八维图像直接进行处理
typedef Vec<float, 2> Vec2f:float 类型的数组,长度为 2,它表示的是二维图像的位置信息,但不能做通道处理
typedef Vec<float, 3> Vec3f:float 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是浮点数
typedef Vec<float, 4> Vec4f:float 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是浮点数
typedef Vec<float, 6> Vec6f: float 类型的数组,长度为 4,他用于处理 6 个维度的图像数据,需要注意的是 Vec6f 仅仅能表示具有 6 个维度的数据,并不可以对数据进行操作.
typedef Vec<double, 2> Vec2d:double 类型的数组,长度为 2,在图像处理中 Vec2d 仅仅只是表示具有 double 类型的图像数据,但是并不能直接操作数据像素
typedef Vec<double, 3> Vec3d:double 类型的数组,长度为 3,它常用于表示图像的彩色三通道,分别是 R(红色)、G(绿色)、B(蓝色),并且对于这三个通道的像素值进行 double 类型数据的处理
typedef Vec<double, 4> Vec4d:double 类型的数组,长度为 4,它常用于表示图像的彩色四通道,分别是 A(透明度)、R(红色)、G(绿色)、B(蓝色),并且对于这四个通道的像素值进行 double 类型数据的处理。
需要注意的是:一般 OPENCV 对像素的处理大部分都是用 uchar 类型,其他类型用的很少。
第二个参数:i,指的是 rows,图像的行数据
第三个参数:j,指的是 cols,图像的列数据
3.代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{//修改三通道图片像素点值Mat img_mat = imread("frame1.jpg");//读取图片//用at函数遍历整个图片三通道像素点并修改像素点值for (int i = 0; i < img_mat.rows; i++){for (int j = 0; j < img_mat.cols; j++){img_mat.at<Vec3b>(i, j)[0] = img_mat.at<Vec3b>(i, j)[0] - 10;img_mat.at<Vec3b>(i, j)[1] -= 50;img_mat.at<Vec3b>(i, j)[2] -= 10;} }//保存修改后的图片imwrite("frame2.jpg", img_mat);//修改单通道图片像素点值Mat grayImage;Mat before_Image;cvtColor(img_mat, before_Image, COLOR_RGB2GRAY);cvtColor(img_mat, grayImage, COLOR_RGB2GRAY);//用at函数遍历整个图片单通道像素点并修改像素点值for (int i = 0; i < grayImage.rows; i++){for (int j = 0; j < grayImage.cols; j++){grayImage.at<uchar>(i, j) = 50 - grayImage.at<uchar>(i, j);}}//保存修改后的图片imwrite("frame3.jpg", before_Image);imwrite("frame4.jpg", grayImage);return 0;
}
相关文章:

2.RV1126-OPENCV Mat理解和AT函数
一.Mat概念 Mat 是整个图像存储的核心也是所有图像处理的最基础的类,Mat 主要存储图像的矩阵类型,包括向量、矩阵、灰度或者彩色图像等等。Mat由两部分组成:矩阵头,矩阵数据。矩阵头是存储图像的长度、宽度、色彩信息等头部信息&a…...
Go 语言 + Word 文档模板:WordZero 引擎如何让企业文档处理效率提升 300%?
前言 在企业级应用开发中,自动化生成Word文档一直是个令人头疼的需求。传统的方案要么依赖于复杂的Office COM组件,要么使用功能有限的第三方库。今天为大家介绍一个纯Go语言实现的Word操作库——WordZero,特别是其强大的模板引擎功能&#…...

unidbg patch 初探 微博deviceId 案例
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向过程 看了b站迷人瑞信那个由于是…...

循序渐进 Android Binder(一):IPC 基本概念和 AIDL 跨进程通信的简单实例
Binder 给人的第一印象是”捆绑者“,即将两个需要建立关系的事物用某些工具束缚在一起。在 Android 中,Binder 是一种高效的跨进程通信(IPC)机制,它将可以将运行在不同进程中的组件进行绑定,以实现彼此通信…...

网络安全之Web渗透加解密
项目基本使用 准备环境:node.js python chrome npm install chrome-remote-interface pip install playwright playwright install chromium pip install mitmproxy ............... 第一步启动cdp.js。 第二步使用python .\cdp_load.py vue_demo,连…...
Leetcode 3567. Minimum Absolute Difference in Sliding Submatrix
Leetcode 3567. Minimum Absolute Difference in Sliding Submatrix 1. 解题思路2. 代码实现 题目链接:3567. Minimum Absolute Difference in Sliding Submatrix 1. 解题思路 这一题想了一下,没想到啥好的思路,就是暴力直接求解了一下&am…...

【LeetCode 题解】两数之和(C++/Python 双解法):从语法到算法的全面解析
【LeetCode题解】两数之和(C/Python双解法):从语法到算法的全面解析 一、题目描述 题目链接:1. 两数之和 难度:简单 要求:给定一个整数数组 nums 和一个整数目标值 target,在数组中找出两个数…...

【机器学习基础】机器学习入门核心算法:集成学习(Ensemble Learning)
机器学习入门核心算法:集成学习(Ensemble Learning) 1. 算法逻辑核心逻辑: 2. 算法原理与数学推导2.1 Bagging(Bootstrap Aggregating)2.2 Boosting2.3 Stacking 3. 模型评估评估指标基学习器选择策略 4. 应…...

【TMS570LC4357】之相关驱动开发学习记录1
系列文章目录 【TMS570LC4357】之工程创建 【TMS570LC4357】之工程配置修改 【TMS570LC4357】之HALCOGEN使用 【TMS570LC4357】之相关问题及解决 ——————————————————— 前言 记录笔者在第一次使用TMS570过程中对外设驱动的一些学习碎片。 1. RTI 1.1 添…...

RAG入门 - Retriever(1)
文章目录 环境准备知识库加载1. Retriever - embeddings 🗂️1.1 将文档拆分为chunks1.2 词嵌入1.3 构建向量数据库Nearest Neighbor search algorithm (最近邻搜索算法)Distances (距离)点积(Dot Product&…...

pyspark实践
1。pyspark是什么 PySpark 是 Apache Spark 的官方 Python 接口,它使得 Python 开发者能够访问 Spark 的核心功能,如: Spark SQL:用于执行 SQL 查询以及读取数据的库,支持多种数据格式和存储系统。py.qizhen.xyz Data…...
内网怎么映射外网ip? 内网的地址快速映射给外网访问用方法
本文章向大家介绍内网怎么映射外网ip,主要包括如何将内网 IP 端口的网络服务映射到外网使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。内容主要包括路由映射公网IP和无公网IP通过nat123映射…...

【深度学习新浪潮】多模态模型如何处理任意分辨率输入?
多模态模型处理任意分辨率输入的能力主要依赖于架构设计的灵活性和预处理技术的结合。以下是核心方法及技术细节: 一、图像模态的分辨率处理 1. 基于Transformer的可变补丁划分(ViT架构) 补丁化(Patch Embedding): 将图像分割为固定大小的补丁(如1616或3232像素),不…...
ZYNQ移植FreeRTOS和固化和openAMP双核
想象一下:一颗拥有“双脑”的ZYNQ芯片,左脑运行Linux处理复杂网络协议,右脑运行FreeRTOS以微秒级精度控制电机,双脑通过“量子纠缠”般的技术实时对话——这就是OpenAMP框架创造的工程奇迹!今天,我们将揭开这项技术的神秘面纱,带你从零构建一个双核异构的智能系统。 🧠…...

K-匿名模型
K-匿名模型是隐私保护领域的一项基础技术,防止通过链接攻击从公开数据中重新识别特定个体。其核心思想是让每个个体在发布的数据中“隐匿于人群”,确保任意一条记录至少与其他K-1条记录在准标识符(Quasi-Identifiers, QIDs)上不可…...

UE5蓝图暴露变量,在游戏运行时修改变量实时变化、看向目标跟随目标Find Look at Rotation、修改玩家自身弹簧臂
UE5蓝图中暴露变量,类似Unity中public一个变量,在游戏运行时修改变量实时变化 1,添加变量 2,设置变量的值 3,点开小眼睛,此变量显示在编辑器中,可以运行时修改 看向目标跟随目标Find Look at R…...
C语言进阶知识:深入探索编程的奥秘
一、指针:C语言的灵魂 指针是C语言中最核心的概念之一,它为程序员提供了对内存的直接操作能力。指针变量存储的是一个地址,通过这个地址可以访问和修改内存中的数据。 (一)指针的基本操作 指针的声明 指针的声明格式…...
机器视觉2D定位引导一般步骤
机器视觉的2D定位引导是工业自动化中的核心应用,主要用于精确确定目标物体的位置(X, Y坐标)和角度(旋转角度θ),并引导机器人或运动机构进行抓取、装配、对位、检测等操作。其一般步骤可概括如下: 一、系统规划与硬件选型 明确需求: 定位精度要求(多少毫米/像素,多少…...

Python-matplotlib中的Pyplot API和面向对象 API
matplotlib中的Pyplot API和面向对象 API Pyplot API(状态机模式)面向对象 API 详解二者差别核心区别方法命名差异注意事项差别举例 🍅 Pyplot API(状态机模式)和面向对象 API 是两种不同的编程接口.🍅 它们…...

FastAPI安全认证:从密码到令牌的魔法之旅
title: FastAPI安全认证:从密码到令牌的魔法之旅 date: 2025/06/02 13:24:43 updated: 2025/06/02 13:24:43 author: cmdragon excerpt: 在FastAPI中实现OAuth2密码流程的认证机制。通过创建令牌端点,用户可以使用用户名和密码获取JWT访问令牌。代码示例展示了如何使用Cry…...
人工智能时代教师角色的重塑与应对策略研究:从理论到实践的转型
一、引言 1.1 研究背景 近年来,人工智能技术迅猛发展,已经逐渐渗透到社会的各个领域,对人类的生产、生活和学习方式产生了深远影响。作为社会发展的重要组成部分,教育领域也不可避免地受到人工智能的冲击,正经历着前…...

java对接bacnet ip协议(跨网段方式)
1、环境准备 #maven环境<repositories><repository><id>ias-releases</id><url>https://maven.mangoautomation.net/repository/ias-release/</url></repository></repositories><dependencies><dependency><…...

LabVIEW超宽带紧凑场测量系统
采用 LabVIEW 开发超宽带紧凑场测量系统,实现天线方向图、目标雷达散射截面(RCS)及天线增益的自动化测量。通过品牌硬件设备,优化系统架构,解决传统测量系统在兼容性、数据处理效率及操作便捷性等方面的问题࿰…...

编译rustdesk,使用flutter、hwcodec硬件编解码、支持Windows 7系统
目录 安装相应的环境安装visual studio安装vpkg安装rust开发环境安装llvm和clang编译源码下载源码使用Sciter作为UI的(已弃用)使用flutter作为UI的(主流)下载flutter sdk桥接静默安装支持Windows 7系统最近某desk免费的限制越来越多,实在没办法,平时远程控制用的比较多,…...

ROS机器人和NPU的往事和新知-250602
往事: 回顾一篇五年前的博客: ROS2机器人笔记20-12-04_ros2 移植到vxworks-CSDN博客 里面提及专用的机器人处理器,那时候只有那么1-2款专用机器人处理器。 无关: 01: 每代人的智商和注意力差异是如何出现的-250602-…...

【从零开始学习QT】信号和槽
目录 一、信号和槽概述 信号的本质 槽的本质 二、信号和槽的使用 2.1 连接信号和槽 2.2 查看内置信号和槽 2.3 通过 Qt Creator 生成信号槽代码 自定义槽函数 自定义信号 自定义信号和槽 2.4 带参数的信号和槽 三、信号与槽的连接方式 3.1 一对一 (1&…...

MCP调研
什么是 MCP MCP(Model Context Protocol,模型上下文协议),是由 Anthropic 在 2024 年 11 月底推出的开放标准协议,旨在统一大型语言模型(LLM)与外部数据源、工具的通信方式。MCP 的主要目的在于…...

TDengine 运维——巡检工具(定期检查)
背景 TDengine 在运行一段时间后需要针对运行环境和 TDengine 本身的运行状态进行定期巡检,本文档旨在说明如何使用巡检工具对 TDengine 的运行环境进行自动化检查。 安装工具使用方法 工具支持通过 help 参数查看支持的语法 Usage: taosinspect [OPTIONS]Check…...
8.7 基于EAP-AKA的订阅转移
8.7 基于EAP-AKA的订阅转移 以下场景描述如下情况: • 主ODSA设备应用程序被允许用于该类型主设备,且已获得服务提供商(SP)授权。 • 终端用户在存有活跃订阅的旧主设备上发起订阅转移请求,且可访问eSIM数据。 • 由于…...

qwen 2.5 并行计算机制:依靠 PyTorch 和 Transformers 库的分布式能力
qwen 2.5 并行计算机制:依靠 PyTorch 和 Transformers 库的分布式能力 完整可运行代码: import torch import torch.nn.functional as F from transformers...