OpenCV 图形API(23)图像和通道合成

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

1.算法描述

在OpenCV的G-API模块中,图像和通道合成(composition)函数允许用户对图像进行复杂的操作,如合并多个单通道图像为一个多通道图像,或者从一个多通道图像中提取特定的通道。这些功能是通过G-API的Graph API实现的,旨在高效处理图像数据流。

2.相关函数

2.1水平方向上拼接两个图像函数concatHor

对给定的矩阵应用水平拼接。
该函数将两个具有相同行数的 GMat 矩阵进行水平拼接。

GMat A = { 1, 4,2, 5,3, 6 };
GMat B = { 7, 10,8, 11,9, 12 };
GMat C = gapi::concatHor(A, B);
//C:
//[1, 4, 7, 10;
// 2, 5, 8, 11;
// 3, 6, 9, 12]

输出矩阵必须与 src1 和 src2 具有相同的行数和深度,并且列数是 src1 和 src2 列数之和。支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:
函数的文字ID是 “org.opencv.imgproc.transform.concatHor”

2.1.1函数原型
GMat cv::gapi::concatHor 
(const GMat &  	src1,const GMat &  	src2 
) 	
2.1.2参数:
  • 参数 src1:第一个输入矩阵,用于水平拼接。
  • 参数 src2:第二个输入矩阵,用于水平拼接。
2.1.3 代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像cv::Mat src1 = (cv::Mat_<uchar>(3, 3) << 1, 2, 3,4, 5, 6,7, 8, 9);cv::Mat src2 = (cv::Mat_<uchar>(3, 2) << 10, 11,12, 13,14, 15);// 定义G-API计算图cv::GComputation concatComp( []() {cv::GMat in1, in2;auto out = cv::gapi::concatHor( in1, in2 );  // 水平拼接两张图像return cv::GComputation( cv::GIn( in1, in2 ), cv::GOut( out ) );} );try{// 执行计算图并获取结果cv::Mat dst;concatComp.apply( cv::gin( src1, src2 ), cv::gout( dst ) );// 打印结果std::cout << "Concatenated image: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.1.4运行结果
Concatenated image: 
[  1,   2,   3,  10,  11;4,   5,   6,  12,  13;7,   8,   9,  14,  15]

2.2 垂直方向上拼接两个图像(矩阵)函数concatVert()

对给定的矩阵应用垂直拼接。
该函数将两个具有相同列数(宽度)的 GMat 矩阵进行垂直拼接。

GMat A = { 1, 7,2, 8,3, 9 };
GMat B = { 4, 10,5, 11,6, 12 };
GMat C = gapi::concatVert(A, B);
//C:
//[1, 7;
// 2, 8;
// 3, 9;
// 4, 10;
// 5, 11;
// 6, 12]

输出矩阵必须与 src1 和 src2 具有相同的列数和深度,并且行数是 src1 和 src2 行数之和。支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:
函数的文字ID是 “org.opencv.imgproc.transform.concatVert”

2.2.1函数原型
GMat cv::gapi::concatVert 	
(const GMat &  	src1,const GMat &  	src2 
) 		
2.2.2 参数:
  • 参数 src1:第一个输入矩阵,用于垂直拼接。
  • 参数 src2:第二个输入矩阵,用于垂直拼接。
2.2.3 代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像cv::Mat src1 = (cv::Mat_<uchar>(3, 3) << 1, 2, 3,4, 5, 6,7, 8, 9);cv::Mat src2 = (cv::Mat_<uchar>(2, 3) << 10, 11, 12,13, 14, 15);// 定义G-API计算图cv::GComputation concatComp( []() {cv::GMat in1, in2;auto out = cv::gapi::concatVert( in1, in2 );  // 垂直拼接两张图像return cv::GComputation( cv::GIn( in1, in2 ), cv::GOut( out ) );} );try{// 执行计算图并获取结果cv::Mat dst;concatComp.apply( cv::gin( src1, src2 ), cv::gout( dst ) );// 打印结果std::cout << "Concatenated image: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.2.4运行结果
Concatenated image: 
[  1,   2,   3;4,   5,   6;7,   8,   9;10,  11,  12;13,  14,  15]

2.3将输入矩阵 src 转换为指定的数据深度函数convertTo()

将一个矩阵转换为另一种数据深度,并可选择进行缩放。
该方法将源像素值转换为目标数据深度。最终应用 saturate_cast<> 以避免可能出现的溢出:
m ( x , y ) = s a t u r a t e _ c a s t < r T y p e > ( α ( ∗ t h i s ) ( x , y ) + β ) m(x,y) = saturate \_ cast<rType>( \alpha (*this)(x,y) + \beta ) m(x,y)=saturate_cast<rType>(α(this)(x,y)+β)
输出矩阵必须与输入矩阵具有相同的大小。

注意:
函数的文字ID是 “org.opencv.core.transform.convertTo”

2.3.1函数原型
GMat cv::gapi::convertTo 	
(const GMat &  	src,int  	rdepth,double  	alpha = 1,double  	beta = 0 
) 		
2.3.2参数
  • 参数src:要从中转换的输入矩阵。
  • 参数rdepth:期望的输出矩阵深度,或者更确切地说是深度,因为通道数与输入相同;如果 rdepth 为负值,则输出矩阵将具有与输入相同的深度。
  • 参数alpha:可选的比例因子。
  • 参数beta:可选的加到缩放值上的增量。
2.3.3代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像cv::Mat src = (cv::Mat_<uchar>(3, 3) << 10, 20, 30,40, 50, 60,70, 80, 90);int rdepth = CV_32F; // 将数据类型转换为32位浮点数double alpha = 1.0;  // 缩放因子double beta = 0.0;   // 偏移量// 定义G-API计算图cv::GComputation convertComp( [ = ]() {  // 使用 [=] 捕获所有外部变量cv::GMat in;auto out = cv::gapi::convertTo( in, rdepth, alpha, beta );  // 转换数据类型return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );}() );try{// 执行计算图并获取结果cv::Mat dst;convertComp.apply( cv::gin( src ), cv::gout( dst ) );// 打印结果std::cout << "Converted image: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.3.4运行结果
Converted image: 
[10, 20, 30;40, 50, 60;70, 80, 90]

2.4创建一个输入矩阵 in 的副本函数copy()

制作输入图像的副本。请注意,这个副本可能不是实际的(没有实际复制数据)。使用此函数以维持图的约定,例如当图的输入需要直接传递到输出时,就像在流模式下一样。

注意:
函数的文字ID是 “org.opencv.streaming.copy”

2.4.1函数原型
GMat cv::gapi::copy 	
(const GMat &  	in
) 	
2.4.2参数
  • 参数 in:输入图像
2.4.3代码示例
include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像cv::Mat src = (cv::Mat_<uchar>(3, 3) << 10, 20, 30,40, 50, 60,70, 80, 90);// 定义G-API计算图cv::GComputation copyComp([](){cv::GMat in;auto out = cv::gapi::copy(in); // 复制输入矩阵return cv::GComputation(cv::GIn(in), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;copyComp.apply(cv::gin(src), cv::gout(dst));// 打印结果std::cout << "Copied image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.4.4运行结果
Copied image: 
[ 10,  20,  30;40,  50,  60;70,  80,  90]

2.5从输入矩阵 src 中裁剪出一个指定的矩形区域函数 crop()

裁剪一个二维矩阵。

该函数根据给定的 cv::Rect 裁剪矩阵。

输出矩阵必须与输入矩阵具有相同的深度,大小由给定的矩形大小指定。

注意:
函数的文字ID是 “org.opencv.core.transform.crop”

2.5.1函数原型
GMat cv::gapi::crop 	
(const GMat &  	src,const Rect &  	rect 
) 	
2.5.2参数
  • 参数src:输入矩阵。
  • 参数rect:用于裁剪矩阵的矩形区域。
2.5.3代码示例
include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像cv::Mat src = (cv::Mat_<uchar>(5, 5) << 1, 2, 3, 4, 5,6, 7, 8, 9, 10,11, 12, 13, 14, 15,16, 17, 18, 19, 20,21, 22, 23, 24, 25);// 定义要裁剪的矩形区域cv::Rect rect(1, 1, 3, 3); // x=1, y=1, width=3, height=3// 定义G-API计算图cv::GComputation cropComp([](){cv::GMat in;cv::GMat out = cv::gapi::crop(in, cv::Rect(1, 1, 3, 3)); // 裁剪输入矩阵return cv::GComputation(cv::GIn(in), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;cropComp.apply(cv::gin(src), cv::gout(dst));// 打印结果std::cout << "Cropped image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.5.4运行结果
Cropped image: 
[  7,   8,   9;12,  13,  14;17,  18,  19]

2.6根据指定的翻转代码 flipCode 翻转输入矩阵 src函数flip()

围绕垂直轴、水平轴或两个轴翻转一个二维矩阵。
该函数以三种不同的方式之一翻转矩阵(行和列的索引是从0开始的):
dst i j = { src src.rows − i − 1 , j i f flipCode = 0 src i , src.cols − j − 1 i f flipCode > 0 src src.rows − i − 1 , src.cols − j − 1 i f flipCode < 0 \texttt{dst} _{ij} = \left\{ \begin{array}{l l} \texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ \texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ \texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ \end{array} \right. dstij= srcsrc.rowsi1,jsrci,src.colsj1srcsrc.rowsi1,src.colsj1ifflipCode=0ifflipCode>0ifflipCode<0
使用此函数的一些示例场景包括:图像的垂直翻转(flipCode == 0),以在左上角和左下角图像原点之间切换。这是在Microsoft Windows*操作系统上进行视频处理时的典型操作。接着进行水平位移并计算绝对差值以检查垂直轴对称性的图像水平翻转(flipCode > 0)。接着进行位移并计算绝对差值以检查中心对称性的同时水平和垂直翻转图像(flipCode < 0)。反转点数组的顺序(flipCode > 0 或 flipCode == 0)。输出图像必须与输入图像具有相同的深度,尺寸应根据给定的 flipCode 正确设置。

注意:
函数的文字ID是 “org.opencv.core.transform.flip”

2.6.1函数原型
GMat cv::gapi::flip 	
(const GMat &  	src,int  	flipCode 
) 	
2.6.2参数
  • 参数 src:输入矩阵。
  • 参数 flipCode:指定如何翻转数组的一个标志;0表示绕x轴翻转,正值(例如1)表示绕y轴翻转。负值(例如-1)表示同时绕两个轴翻转。
2.6.3代码示例
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>int main()
{// 创建示例输入图像cv::Mat src = ( cv::Mat_< uchar >( 3, 3 ) << 1, 2, 3, 4, 5, 6, 7, 8, 9 );// 定义翻转代码:这里选择水平翻转int flipCode = 1;  // 水平翻转// 定义G-API计算图cv::GComputation flipComp( [ flipCode ]() {cv::GMat in;auto out = cv::gapi::flip( in, flipCode );  // 根据flipCode翻转输入矩阵return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );} );try{// 执行计算图并获取结果cv::Mat dst;flipComp.apply( cv::gin( src ), cv::gout( dst ) );// 打印结果std::cout << "Flipped image: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.6.4运行结果
Flipped image: 
[  3,   2,   1;6,   5,   4;9,   8,   7]

2.7对输入矩阵 src 应用查找表(Look-Up Table, LUT)函数LUT()

对一个矩阵执行查找表变换。
LUT 函数使用查找表中的值填充输出矩阵。查找表的索引取自输入矩阵。也就是说,该函数处理 src 的每个元素的方式如下:
支持的矩阵数据类型是 CV_8UC1。输出矩阵与 src 具有相同的大小和通道数,并且与 lut 具有相同的深度。

注意:
函数的文字ID是 “org.opencv.core.transform.LUT”

2.7.1函数原型
GMat cv::gapi::LUT 	
(const GMat &  	src,const Mat &  	lut 
) 		
2.7.2参数
  • 参数 src: 输入矩阵,元素为8位。
  • 参数 lut: 查找表,包含256个元素;在多通道输入数组的情况下,查找表应该要么只有一个通道(在这种情况下,所有通道使用相同的查找表)或者与输入矩阵具有相同数量的通道。
2.7.3代码示例
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>int main()
{// 创建示例输入图像cv::Mat src = ( cv::Mat_< uchar >( 3, 3 ) << 0, 50, 100, 150, 200, 250, 255, 128, 64 );// 创建查找表cv::Mat lut( 1, 256, CV_8U );uchar* p = lut.ptr< uchar >();for ( int i = 0; i < 256; ++i ){p[ i ] = static_cast< uchar >( 255 - i );  // 反转查找表}// 定义G-API计算图cv::GComputation lutComp( [ = ]() {cv::GMat in;cv::GMat out = cv::gapi::LUT( in, lut );  // 正确地应用查找表return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );} );try{// 执行计算图并获取结果cv::Mat dst;lutComp.apply( cv::gin( src ), cv::gout( dst ) );// 打印结果std::cout << "Image after LUT: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.7.4运行结果
Image after LUT: 
[255, 205, 155;105,  55,   5;0, 127, 191]

2.8 将三个单通道的 GMat 图像合并成一个多通道(三通道)的图像函数merge3()

从3个单通道矩阵创建一个3通道矩阵。

该函数将多个矩阵合并为一个多通道矩阵。也就是说,输出矩阵的每个元素将是输入矩阵元素的串联,其中第 i 个输入矩阵的元素被视为 mv[i].channels() 元素向量。输出矩阵必须是 CV_8UC3 类型。

函数 split3 执行相反的操作。

注意:
函数的文字ID是 “org.opencv.core.transform.merge3”

2.8.1函数原型
GMat cv::gapi::merge3 	
(const GMat &  	src1,const GMat &  	src2,const GMat &  	src3 
) 	
2.8.2参数
  • 参数src1: 首个需要合并的输入 CV_8UC1 矩阵。
  • 参数 src2: 第二个需要合并的输入 CV_8UC1 矩阵。
  • 参数 src3: 第三个需要合并的输入 CV_8UC1 矩阵。
2.8.3代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像(单通道)cv::Mat src1 = (cv::Mat_<uchar>(3, 3) << 10, 20, 30,40, 50, 60,70, 80, 90);cv::Mat src2 = (cv::Mat_<uchar>(3, 3) << 100, 110, 120,130, 140, 150,160, 170, 180);cv::Mat src3 = (cv::Mat_<uchar>(3, 3) << 190, 200, 210,220, 230, 240,250, 260, 270);// 定义G-API计算图cv::GComputation mergeComp([](){cv::GMat in1, in2, in3;auto out = cv::gapi::merge3(in1, in2, in3); // 合并三个单通道图像return cv::GComputation(cv::GIn(in1, in2, in3), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;mergeComp.apply(cv::gin(src1, src2, src3), cv::gout(dst));// 打印结果std::cout << "Merged image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.8.4运行结果
Merged image: 
[ 10, 100, 190,  20, 110, 200,  30, 120, 210;40, 130, 220,  50, 140, 230,  60, 150, 240;70, 160, 250,  80, 170,   4,  90, 180,  14]

2.9将四个单通道的 GMat 图像合并成一个多通道(四通道)的图像函数merge4()

从4个单通道矩阵创建一个4通道矩阵。
该函数将多个矩阵合并为一个多通道矩阵。也就是说,输出矩阵的每个元素将是输入矩阵元素的串联,其中第 i 个输入矩阵的元素被视为 mv[i].channels() 元素向量。输出矩阵必须是 CV_8UC4 类型。

函数 split4 执行相反的操作。

注意:
函数的文字ID是 “org.opencv.core.transform.merge4”

2.9.1函数原型
GMat cv::gapi::merge4 	
(const GMat &  	src1,const GMat &  	src2,const GMat &  	src3,const GMat &  	src4 
) 		
2.9.2参数
  • 参数src1: 首个需要合并的输入 CV_8UC1 矩阵。
  • 参数src2: 第二个需要合并的输入 CV_8UC1 矩阵。
  • 参数src3: 第三个需要合并的输入 CV_8UC1 矩阵。
  • 参数src4: 第四个需要合并的输入 CV_8UC1 矩阵
2.9.3代码示例
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>int main()
{// 创建示例输入图像(单通道)cv::Mat src1 = ( cv::Mat_< uchar >( 2, 2 ) << 10, 20, 30, 40 );cv::Mat src2 = ( cv::Mat_< uchar >( 2, 2 ) << 50, 60, 70, 80 );cv::Mat src3 = ( cv::Mat_< uchar >( 2, 2 ) << 90, 100, 110, 120 );cv::Mat src4 = ( cv::Mat_< uchar >( 2, 2 ) << 130, 140, 150, 160 );// 定义G-API计算图cv::GComputation mergeComp( []() {cv::GMat in1, in2, in3, in4;auto out = cv::gapi::merge4( in1, in2, in3, in4 );  // 合并四个单通道图像return cv::GComputation( cv::GIn( in1, in2, in3, in4 ), cv::GOut( out ) );} );try{// 执行计算图并获取结果cv::Mat dst;mergeComp.apply( cv::gin( src1, src2, src3, src4 ), cv::gout( dst ) );// 打印结果std::cout << "Merged image: \n" << dst << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.9.4运行结果
Merged image: 
[ 10,  50,  90, 130,  20,  60, 100, 140;30,  70, 110, 150,  40,  80, 120, 160]

2.10对输入矩阵 src 进行归一化操作函数normalize()

归一化数组的范数或值范围。

该函数通过缩放和移位输入数组元素来实现归一化,使得
∥ dst ∥ L p = alpha \| \texttt{dst} \| _{L_p}= \texttt{alpha} dstLp=alpha
其中 p=Inf, 1 或 2)当 normType 分别为 NORM_INF, NORM_L1 或 NORM_L2 时;或者使得
min ⁡ I dst ( I ) = alpha , max ⁡ I dst ( I ) = beta \min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta} Imindst(I)=alpha,Imaxdst(I)=beta
当 normType 为 NORM_MINMAX 时(仅适用于密集数组)。

注意:
函数的文字ID是 “org.opencv.core.normalize”

2.10.1函数原型
GMat cv::gapi::normalize 	
(const GMat &  	src,double  	alpha,double  	beta,int  	norm_type,int  	ddepth = -1 
) 		
2.10.2参数
  • 参数src: 输入数组。
  • 参数 alpha: 归一化的目标范数值,或者在范围归一化时的下界。
  • 参数 beta: 在范围归一化时的上界;在范数归一化时不使用。
  • 参数 norm_type: 归一化类型(参见 cv::NormTypes)。
  • 参数 ddepth: 当为负值时,输出数组与 src 类型相同;否则,它具有与 src 相同的通道数且深度为 ddepth。
2.10.3 代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像(单通道)cv::Mat src = (cv::Mat_<float>(3, 3) << 1.0f, 2.0f, 3.0f,4.0f, 5.0f, 6.0f,7.0f, 8.0f, 9.0f);// 定义归一化参数double alpha = 0.0;double beta = 1.0;int norm_type = cv::NORM_MINMAX;int ddepth = -1; // 使用与输入相同的深度// 定义G-API计算图cv::GComputation normalizeComp([=]() {cv::GMat in;auto out = cv::gapi::normalize(in, alpha, beta, norm_type, ddepth); // 归一化操作return cv::GComputation(cv::GIn(in), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;normalizeComp.apply(cv::gin(src), cv::gout(dst));// 打印结果std::cout << "Normalized image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.10.4运行结果
Normalized image: 
[0, 0.125, 0.25;0.375, 0.5, 0.625;0.75, 0.875, 1]

2.11对输入图像 src 进行重映射(remapping)函数remap()

应用一个通用的几何变换到图像上。
该函数使用指定的映射对源图像进行变换:
dst ( x , y ) = src ( m a p x ( x , y ) , m a p y ( x , y ) ) \texttt{dst} (x,y) = \texttt{src} (map_x(x,y),map_y(x,y)) dst(x,y)=src(mapx(x,y),mapy(x,y))
其中,具有非整数坐标的像素值将使用一种可用的插值方法计算。mapx 和 mapy 可以分别编码为 map1 和 map2 中的独立浮点映射,或者在 map1 中交错存储的 (x,y) 浮点映射,或者通过使用 convertMaps 创建的定点映射。你可能希望从浮点表示转换到定点表示的原因是它们可以显著加快(高达2倍)重映射操作。在转换后的情况下,map1 包含 (cvFloor(x), cvFloor(y)) 对,而 map2 包含插值系数表中的索引。输出图像必须与输入图像具有相同的大小和深度。

注意:
函数的文字ID是 “org.opencv.core.transform.remap”
由于当前实现的限制,输入和输出图像的尺寸应小于 32767x32767。

2.11.1函数原型
GMat cv::gapi::remap 	
(const GMat &  	src,const Mat &  	map1,const Mat &  	map2,int  	interpolation,int  	borderMode = BORDER_CONSTANT,const Scalar &  	borderValue = Scalar() 
) 		
2.11.2参数
  • 参数src: 源图像。
  • 参数 map1: 第一个映射,包含 (x,y) 点或仅 x 值,类型为 CV_16SC2, CV_32FC1 或 CV_32FC2。
  • 参数 map2: 第二个映射,包含 y 值,类型为 CV_16UC1, CV_32FC1,或者如果 map1 是 (x,y) 点则为空。
  • 参数 interpolation: 插值方法(参见 cv::InterpolationFlags)。此函数不支持 INTER_AREA 和 INTER_LINEAR_EXACT 方法。
  • 参数 borderMode: 像素外推方法(参见 cv::BorderTypes)。当 borderMode=BORDER_TRANSPARENT 时,这意味着目标图像中对应于源图像“异常值”的像素不会被函数修改。
  • 参数 borderValue: 在使用常量边界模式时使用的值,默认为 0。
2.11.3代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像(单通道)cv::Mat src = (cv::Mat_<uchar>(3, 3) << 1, 2, 3,4, 5, 6,7, 8, 9);// 创建映射表cv::Mat map1 = (cv::Mat_<float>(3, 3) << 0.0f, 1.0f, 2.0f,0.0f, 1.0f, 2.0f,0.0f, 1.0f, 2.0f);cv::Mat map2 = (cv::Mat_<float>(3, 3) << 0.0f, 0.0f, 0.0f,1.0f, 1.0f, 1.0f,2.0f, 2.0f, 2.0f);// 定义插值方法和边界模式int interpolation = cv::INTER_LINEAR;int borderMode = cv::BORDER_CONSTANT;cv::Scalar borderValue(0); // 默认值// 定义G-API计算图cv::GComputation remapComp([=]() {cv::GMat in;auto out = cv::gapi::remap(in, map1, map2, interpolation, borderMode, borderValue); // 重映射操作return cv::GComputation(cv::GIn(in), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;remapComp.apply(cv::gin(src), cv::gout(dst));// 打印结果std::cout << "Remapped image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;
**加粗样式**        return -1;}return 0;
}
2.11.4运行结果
Remapped image: 
[  1,   2,   3;4,   5,   6;7,   8,   9]

2.12 调整输入图像 src 的大小函数resize()

调整图像大小。
该函数将图像 src 调整到指定大小,可以是缩小或放大。
输出图像的大小将会是 dsize(当 dsize 非零时)或者根据 src.size()、fx 和 fy 计算得出;输出图像的深度与 src 相同。
如果你想调整 src 的大小以适合预先创建的 dst,你可以这样调用函数:

// explicitly specify dsize=dst.size(); fx and fy will be computed from that.
resize(src, dst, dst.size(), 0, 0, interpolation);

如果你想在每个方向上按比例缩小图像因子为 2,你可以这样调用函数:

// specify fx and fy and let the function compute the destination image size.
resize(src, dst, Size(), 0.5, 0.5, interpolation);

为了缩小图像,通常使用 cv::INTER_AREA 插值方法效果最佳;而要放大图像,通常使用 cv::INTER_CUBIC(较慢)或 cv::INTER_LINEAR(较快但仍看起来不错)插值方法效果最佳。

注意:

函数的文字ID是 “org.opencv.imgproc.transform.resize”

2.12.1函数原型
GMat cv::gapi::resize 	
(const GMat &  	src,const Size &  	dsize,double  	fx = 0,double  	fy = 0,int  	interpolation = INTER_LINEAR 
) 		
2.12.2参数
  • 参数 src: 输入图像。
  • 参数 dsize: 输出图像大小;如果其等于零,则根据以下公式计算:
2.12.3示例代码
#include <opencv2/opencv.hpp>
#include <opencv2/gapi/core.hpp> // 包含G-API核心功能
#include <opencv2/gapi.hpp>int main() {// 创建示例输入图像(单通道)cv::Mat src = (cv::Mat_<uchar>(2, 2) << 1, 2,3, 4);// 定义目标尺寸cv::Size dsize(4, 4); // 将原图放大到4x4// 定义缩放因子(不使用时设为0)double fx = 0;double fy = 0;// 定义插值方法int interpolation = cv::INTER_LINEAR;// 定义G-API计算图cv::GComputation resizeComp([=]() {cv::GMat in;auto out = cv::gapi::resize(in, dsize, fx, fy, interpolation); // 调整大小操作return cv::GComputation(cv::GIn(in), cv::GOut(out));});try {// 执行计算图并获取结果cv::Mat dst;resizeComp.apply(cv::gin(src), cv::gout(dst));// 打印结果std::cout << "Resized image: \n" << dst << std::endl;} catch (const std::exception &e) {std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.12.4运行结果
Resized image: 
[  1,   1,   2,   2;2,   2,   2,   3;3,   3,   3,   4;3,   3,   4,   4]

2.13 调整打包像素格式(Planar, GMatP)图像大小的函数resizeP()

该函数将图像 src 调整到指定大小,可以是缩小或放大。打包图像的内存布局是三个平面在内存中连续排列,因此图像的高度应该是 plane_height * plane_number,图像类型为 CV_8UC1。

输出图像的大小将会是 dsize,输出图像的深度与 src 相同。

注意:

函数的文字ID是 “org.opencv.imgproc.transform.resizeP”

2.13.1函数原型
GMatP cv::gapi::resizeP 	
(const GMatP &  	src,const Size &  	dsize,int  	interpolation = cv::INTER_LINEAR 
) 	
2.13.2参数
  • 参数src: 输入图像,必须是 CV_8UC1 类型;
  • 参数 dsize: 输出图像大小;
  • 参数 interpolation: 插值方法,目前仅支持 cv::INTER_LINEAR。
2.13.3示例代码

没有写出正确的代码,后续加上。。。。。

2.14将一个多通道的 GMat 拆分为三个单通道的 GMat函数split3()

将一个3通道矩阵拆分为3个单通道矩阵。
该函数将一个3通道矩阵拆分为3个单通道矩阵:

mv [ c ] ( I ) = src ( I ) c \texttt{mv} [c](I) = \texttt{src} (I)_c mv[c](I)=src(I)c

所有输出矩阵必须是 CV_8UC1 类型。

函数 merge3 执行相反的操作。

注意

函数的文本标识符是 “org.opencv.core.transform.split3”

2.14.1函数原型
std::tuple<GMat, GMat, GMat> cv::gapi::split3
(const GMat &  	src
) 	
2.14.2参数
  • 参数src 输入的 CV_8UC3 矩阵。
2.14.3代码示例
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>     // 包含G-API核心功能
#include <opencv2/gapi/imgproc.hpp>  // 包含其他可能需要的G-API模块
#include <opencv2/opencv.hpp>int main()
{// 创建或加载示例输入图像(假设是三通道BGR图像)cv::Mat src = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png" );  // 加载实际图像if ( src.empty() ){std::cerr << "Error: Image cannot be loaded!" << std::endl;return -1;}// 定义G-API计算图来拆分图像cv::GComputation comp( []() {cv::GMat in;                                // 输入:多通道GMatauto [ b, g, r ] = cv::gapi::split3( in );  // 使用split3函数拆分图像return cv::GComputation( cv::GIn( in ), cv::GOut( b, g, r ) );} );// 输出结果cv::Mat b, g, r;try{// 执行计算图并传入实际的cv::Mat数据comp.apply( cv::gin( src ), cv::gout( b, g, r ) );// 打印每个通道的信息std::cout << "Blue channel:\n" << b << "\nGreen channel:\n" << g << "\nRed channel:\n" << r << std::endl;}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.14.4运行结果

输出太占屏幕,不展示了

2.15将一个四通道的 GMat 拆分为四个单通道的 GMat函数split4()

将一个4通道矩阵拆分为4个单通道矩阵。
该函数将一个4通道矩阵拆分为4个单通道矩阵:
mv [ c ] ( I ) = src ( I ) c \texttt{mv} [c](I) = \texttt{src} (I)_c mv[c](I)=src(I)c
所有输出矩阵必须是 CV_8UC1 类型。

函数 merge4 执行相反的操作。

注意

函数的文本标识符是 “org.opencv.core.transform.split4”

2.15.1函数原型
std::tuple<GMat, GMat, GMat,GMat> cv::gapi::split4
(const GMat &  	src
) 	
2.15.2参数
  • 参数 src 输入的 CV_8UC4 矩阵。
2.15.3示例代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>int main()
{// 创建或加载示例输入图像(假设是四通道RGBA图像)cv::Mat src = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png", cv::IMREAD_UNCHANGED );  // 加载实际图像,确保包含alpha通道if ( src.empty() ){std::cerr << "Error: Image cannot be loaded!" << std::endl;return -1;}if (src.channels() == 3) { // 如果图像是三通道std::vector<cv::Mat> channels;cv::split(src, channels); // 分离BGR通道cv::Mat alpha(src.size(), CV_8UC1, cv::Scalar(255)); // 创建一个全透明的Alpha通道channels.push_back(alpha); // 添加Alpha通道cv::merge(channels, src); // 合并通道回到四通道图像}// 确保输入是CV_8UC4类型if ( src.type() != CV_8UC4 ){std::cerr << "Error: Input image must be of type CV_8UC4!" << std::endl;return -1;}// 定义G-API计算图来拆分图像cv::GComputation comp( []() {cv::GMat in;                                   // 输入:多通道GMatauto [ b, g, r, a ] = cv::gapi::split4( in );  // 使用split4函数拆分图像return cv::GComputation( cv::GIn( in ), cv::GOut( b, g, r, a ) );} );// 输出结果cv::Mat b, g, r, a;try{// 执行计算图并传入实际的cv::Mat数据comp.apply( cv::gin( src ), cv::gout( b, g, r, a ) );// 确保输出是CV_8UC1类型if ( b.type() != CV_8UC1 || g.type() != CV_8UC1 || r.type() != CV_8UC1 || a.type() != CV_8UC1 ){std::cerr << "Error: Output images must be of type CV_8UC1!" << std::endl;return -1;}// 可视化结果(可选)cv::imshow( "Blue Channel", b );cv::imshow( "Green Channel", g );cv::imshow( "Red Channel", r );cv::imshow( "Alpha Channel", a );cv::waitKey( 0 );  // 等待按键事件}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.15.4运行结果

在这里插入图片描述

2.16仿射变换函数warpAffine()

应用仿射变换到图像。
函数 warpAffine 使用指定的矩阵对源图像进行变换:
dst ( x , y ) = src ( M 11 x + M 12 y + M 13 , M 21 x + M 22 y + M 23 ) \texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23}) dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)
当设置了标志 WARP_INVERSE_MAP 时。否则,首先使用 invertAffineTransform 反转变换,然后将其放入上述公式中代替 MM。该函数不能就地操作(即输入图像和输出图像不能是同一个对象)。

2.16.1函数原型
GMat cv::gapi::warpAffine 	
(const GMat &  	src,const Mat &  	M,const Size &  	dsize,int  	flags = cv::INTER_LINEAR,int  	borderMode = cv::BORDER_CONSTANT,const Scalar &  	borderValue = Scalar() 
) 	
2.16.2参数
  • 参数 src: 输入图像。
  • 参数 M: 2×3 的变换矩阵。
  • 参数 dsize: 输出图像的尺寸。
  • 参数 flags: 插值方法的组合(参见 InterpolationFlags)以及可选的标志 WARP_INVERSE_MAP,表示 MM 是逆变换(从 dst 到 src)。
  • 参数 borderMode: 像素外推方法(参见 BorderTypes);不支持 BORDER_TRANSPARENT。
  • 参数 borderValue: 在使用常量边界模式时使用的值;默认为 0。
2.16.3代码示例
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>     // 包含G-API核心功能
#include <opencv2/gapi/imgproc.hpp>  // 包含imgproc模块,可能需要的其他G-API模块
#include <opencv2/opencv.hpp>int main()
{// 加载输入图像cv::Mat src = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png" );if ( src.empty() ){std::cerr << "Error: Image cannot be loaded!" << std::endl;return -1;}// 定义仿射变换矩阵 Mdouble angle = 45.0;double scale = 1.0;cv::Point2f center( src.cols / 2.0, src.rows / 2.0 );cv::Mat M = cv::getRotationMatrix2D( center, angle, scale );// 定义输出尺寸cv::Size dsize = src.size();// 定义G-API计算图来应用仿射变换cv::GComputation comp( [ dsize, &M ]() {           // 捕获 dsize 和 Mcv::GMat in;                                   // 输入:源图像int flags              = cv::INTER_LINEAR;     // 插值方法int borderMode         = cv::BORDER_CONSTANT;  // 边界模式cv::Scalar borderValue = cv::Scalar();         // 边界填充颜色,默认为黑色cv::GMat out = cv::gapi::warpAffine( in, M, dsize, flags, borderMode, borderValue );return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );} );// 输出结果cv::Mat dst;try{// 执行计算图并传入实际的cv::Mat数据comp.apply( cv::gin( src ), cv::gout( dst ) );// 显示结果cv::imshow( "Original Image", src );cv::imshow( "Transformed Image", dst );cv::waitKey( 0 );  // 等待按键事件}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.16.4 运行结果

在这里插入图片描述

2.17透视变换函数warpPerspective()

应用透视变换到图像。
函数 warpPerspective 使用指定的矩阵对源图像进行变换:
dst ( x , y ) = src ( M 11 x + M 12 y + M 13 M 31 x + M 32 y + M 33 , M 21 x + M 22 y + M 23 M 31 x + M 32 y + M 33 ) \texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} , \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right ) dst(x,y)=src(M31x+M32y+M33M11x+M12y+M13,M31x+M32y+M33M21x+M22y+M23)
当设置了标志 WARP_INVERSE_MAP 时。否则,首先使用 invert 反转变换,然后将其放入上述公式中代替 MM。该函数不能就地操作(即输入图像和输出图像不能是同一个对象)。

2.17.1函数原型
GMat cv::gapi::warpPerspective 
(const GMat &  	src,const Mat &  	M,const Size &  	dsize,int  	flags = cv::INTER_LINEAR,int  	borderMode = cv::BORDER_CONSTANT,const Scalar &  	borderValue = Scalar() 
) 		
2.17.2参数
  • 参数 src: 输入图像。
  • 参数 M: 3×3 的变换矩阵。
  • 参数 dsize: 输出图像的尺寸。
  • 参数 flags: 插值方法的组合(INTER_LINEAR 或 INTER_NEAREST)以及可选的标志 WARP_INVERSE_MAP,设置 MM 作为逆变换(从 dst 到 src)。
  • 参数 borderMode: 像素外推方法(BORDER_CONSTANT 或 BORDER_REPLICATE)。
  • 参数 borderValue: 在使用常量边界模式时使用的值;默认等于 0。
2.17.3示例代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>     // 包含G-API核心功能
#include <opencv2/gapi/imgproc.hpp>  // 包含imgproc模块,可能需要的其他G-API模块
#include <opencv2/opencv.hpp>int main()
{// 加载输入图像cv::Mat src = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png" );if ( src.empty() ){std::cerr << "Error: Image cannot be loaded!" << std::endl;return -1;}// 定义透视变换矩阵 M// 这里以简单变换为例,你可以根据需要修改此矩阵cv::Point2f srcPoints[] = { { 50, 50 }, { 200, 50 }, { 50, 200 }, { 200, 200 } };cv::Point2f dstPoints[] = { { 30, 30 }, { 180, 20 }, { 60, 180 }, { 220, 180 } };cv::Mat M               = cv::getPerspectiveTransform( srcPoints, dstPoints );// 定义输出尺寸cv::Size dsize = src.size();// 定义G-API计算图来应用透视变换cv::GComputation comp( [ dsize, &M ]() {           // 捕获 dsize 和 Mcv::GMat in;                                   // 输入:源图像int flags              = cv::INTER_LINEAR;     // 插值方法int borderMode         = cv::BORDER_CONSTANT;  // 边界模式cv::Scalar borderValue = cv::Scalar();         // 边界填充颜色,默认为黑色cv::GMat out = cv::gapi::warpPerspective( in, M, dsize, flags, borderMode, borderValue );return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );} );// 输出结果cv::Mat dst;try{// 执行计算图并传入实际的cv::Mat数据comp.apply( cv::gin( src ), cv::gout( dst ) );// 显示结果cv::imshow( "Original Image", src );cv::imshow( "Transformed Image", dst );cv::waitKey( 0 );  // 等待按键事件}catch ( const std::exception& e ){std::cerr << "Exception: " << e.what() << std::endl;return -1;}return 0;
}
2.17.4运行结果

在这里插入图片描述

------------------------------完结

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

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

相关文章

帝国cms导航淘客新闻下载多功能网站源码 二次元风格自适应附教程

一、本模板使用帝国cms7.5 utf8版本&#xff0c;二次元导航新闻下载工具淘客自适应响应式帝国cms模板。 1、网站后台有3个系统模型&#xff0c;新闻系统模型&#xff0c;下载系统模型&#xff0c;导航系统模型&#xff0c;商城系统模型&#xff0c;可以根据自己的需求不同&…

本地部署大模型(ollama模式)

分享记录一下本地部署大模型步骤。 大模型应用部署可以选择 ollama 或者 LM Studio。本文介绍ollama本地部署 ollama官网为&#xff1a;https://ollama.com/ 进入官网&#xff0c;下载ollama。 ollama是一个模型管理工具和平台&#xff0c;它提供了很多国内外常见的模型&…

C# virtual 和 abstract 详解

简介 在 C# 中&#xff0c;virtual 和 abstract 关键字都用于面向对象编程中的继承和多态&#xff0c;它们主要用于方法、属性和事件的定义&#xff0c;但在用法上存在一些重要的区别。 virtual 关键字 virtual 表示可重写的方法&#xff0c;但可以提供默认实现&#xff0c;…

自动驾驶的数据集以及yolov8和yolop

项目背景 网络全部是分割了没有检测。 自动驾驶的车道线和可行驶区域在数据集中的表示 自动驾驶系统中的车道线和可行驶区域的表示方式主要有以下几种&#xff1a; 基于几何模型&#xff1a;使用几何模型来描述车道线和可行驶区域的形状和位置&#xff0c;例如直线、曲线、多…

Oracle DROP、TRUNCATE 和 DELETE 原理

在 Oracle 11g 中&#xff0c;DROP、TRUNCATE 和 DELETE 是三种不同的数据清理操作&#xff0c;它们的底层原理和适用场景有显著差异 1. DELETE 的原理 类型&#xff1a;DML&#xff08;数据操作语言&#xff09; 功能&#xff1a;逐行删除表中符合条件的数据&#xff0c;保留…

PCIe 5.0光学SSD原型问世!

近日&#xff0c;Kioxia Corporation&#xff08;铠侠&#xff09;、AIO Core Co., Ltd. 和 Kyocera Corporation&#xff08;京瓷&#xff09;联合宣布成功开发了一款支持 PCIe 5.0 接口的光学 SSD 原型。该技术旨在通过光接口替换传统的电接口&#xff0c;从而显著增加计算设…

SQL 查询中涉及的表及其作用说明

SQL 查询中涉及的表及其作用说明&#xff1a; 涉及的数据库表 表名别名/用途关联关系dbo.s_orderSO&#xff08;主表&#xff09;存储订单主信息&#xff08;订单号、日期、客户等&#xff09;dbo.s_orderdetailSoD&#xff08;订单明细&#xff09;通过 billid SO.billid 关…

C++学习之金融类安全传输平台项目git

目录 1.知识点概述 2.版本控制工具作用 3.git和SVN 4.git介绍 5.git安装 6.工作区 暂存区 版本库概念 7.本地文件添加到暂存区和提交到版本库 8.文件的修改和还原 9.查看提交的历史版本信息 10.版本差异比较 11.删除文件 12.本地版本管理设置忽略目录 13.远程git仓…

【HCIP】GRE VPN实验笔记

一、实验拓扑 二、实验要求 1、按照图示配置IP地址 2、在R1和R3上配置默认路由使公网区域互通 3、在R1和R3上配置GRE VPN&#xff0c;使两端私网能够互相访问&#xff0c;Tunnel口IP地址如图 4、在R1和R3上配置RIPv2或者ospf或者静态&#xff0c;来传递两端私网路由 三、实…

大模型——Llama Stack快速入门 部署构建AI大模型指南

Llama Stack快速入门 部署构建AI大模型指南 介绍 Llama Stack 是一组标准化和有主见的接口,用于如何构建规范的工具链组件(微调、合成数据生成)和代理应用程序。我们希望这些接口能够在整个生态系统中得到采用,这将有助于更轻松地实现互操作性。 Llama Stack 定义并标准化…

ALOPS智能化运维管理平台

AIOps&#xff08;Artificial Intelligence for IT Operations&#xff09;即智能运维&#xff0c;是将人工智能技术应用于 IT 运维管理领域&#xff0c;以实现自动化、智能化的运维决策和管理。以下是关于 AIOps 的详细介绍&#xff1a; 核心能力 数据收集与整合&#xff1a…

C语言超详细指针知识(二)

在上一篇有关指针的博客中&#xff0c;我们介绍了指针的基础知识&#xff0c;如&#xff1a;内存与地址&#xff0c;解引用操作符&#xff0c;野指针等&#xff0c;今天我们将更加深入的学习指针的其他知识。 1.指针的使用和传址调用 1.1strlen的模拟实现 库函数strlen的功能是…

一种替代DOORS在WORD中进行需求管理的方法 (二)

一、前景 参考&#xff1a; 一种替代DOORS在WORD中进行需求管理的方法&#xff08;基于WORD插件的应用&#xff09;_doors aspice-CSDN博客 二、界面和资源 WORD2013/WORD2016 插件 【已使用该工具通过第三方功能安全产品认证】&#xff1a; 1、 核心功能 1、需求编号和跟…

设计模式 Day 6:深入讲透观察者模式(真实场景 + 回调机制 + 高级理解)

观察者模式&#xff08;Observer Pattern&#xff09;是一种设计结构中最实用、最常见的行为模式之一。它的魅力不仅在于简洁的“一对多”事件推送能力&#xff0c;更在于它的解耦能力、模块协作设计、实时响应能力。 本篇作为 Day 6&#xff0c;将带你从理论、底层机制到真实…

文献总结:AAAI2025-UniV2X-End-to-end autonomous driving through V2X cooperation

UniV2X 一、文章基本信息二、文章背景三、UniV2X框架1. 车路协同自动驾驶问题定义2. 稀疏-密集混合形态数据3. 交叉视图数据融合&#xff08;智能体融合&#xff09;4. 交叉视图数据融合&#xff08;车道融合&#xff09;5. 交叉视图数据融合&#xff08;占用融合&#xff09;6…

2025蓝桥杯python A组题解

真捐款去了&#xff0c;好长时间没练了&#xff0c;感觉脑子和手都不转悠了。 B F BF BF 赛时都写假了&#xff0c; G G G 也只写了爆搜。 题解其实队友都写好了&#xff0c;我就粘一下自己的代码&#xff0c;稍微提点个人的理解水一篇题解 队友题解 B 思路&#xff1a; 我…

免费送源码:Java+ssm+MySQL 校园二手书销售平台设计与实现 计算机毕业设计原创定制

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对校园二手书销售平台等问题&#xff0c;对校…

工业科学级天文相机:跨界融合的高精密成像解决方案

随着国内科技的快速发展&#xff0c;工业相机领域正悄然兴起一场"天文级"的技术革命。这类兼具工业设备可靠性与天文观测精度的特殊相机&#xff0c;正在半导体制造、天文观测、空间探测等领域开辟新的应用疆域。其核心技术突破不仅体现在传感器性能的提升&#xff0…

论文阅读笔记——Multi-Token Attention

MTA 论文 在 Transformer 中计算注意力权重时&#xff0c;仅依赖单个 Q 和 K 的相似度&#xff0c;无法有效捕捉多标记组合信息。&#xff08;对于 A、B 两个词&#xff0c;单标记注意力需要分别计算两个词的注意力分数&#xff0c;再通过后处理定位共同出现的位置或通过多层隐…

301.找出3位偶数

2094. 找出 3 位偶数 - 力扣&#xff08;LeetCode&#xff09; class Solution {List<Integer> resnew ArrayList<>();List<Integer> linew ArrayList<>();public int[] findEvenNumbers(int[] digits) {Arrays.sort(digits);boolean[] numsnew boolea…