OpenCV 图形API(22)矩阵操作

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

1.算法描述

OpenCV的Graph API提供了一种高效且灵活的方法来处理图像和矩阵。通过G-API,用户可以构建计算图并执行各种矩阵操作,这些操作包括但不限于基本的算术运算、逻辑运算、比较操作以及选择操作等。

2.相关函数

2.1计算两个矩阵(或图像)之间的逐像素绝对差值函数absDiff()

计算两个矩阵之间的逐元素绝对差值。

函数 absDiff 计算两个相同大小和深度的矩阵之间的绝对差值:
dst ( I ) = saturate ( ∣ src1 ( I ) − src2 ( I ) ∣ ) \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|) dst(I)=saturate(∣src1(I)−src2(I)∣)

其中,I 是矩阵元素的多维索引。在处理多通道矩阵时,每个通道独立处理。输出矩阵必须与输入矩阵具有相同的尺寸和深度。

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意

该函数的文本ID是 "org.opencv.core.matrixop.absdiff"

2.1.1 函数原型
cpp 复制代码
GMat cv::gapi::absDiff 
(
 	const GMat &  	src1,
	const GMat &  	src2 
) 	
2.1.2参数:
  • 参数src1: 第一个输入矩阵。
  • 参数src2: 第二个输入矩阵。
2.1.3 代码示例
cpp 复制代码
#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) << 
        15, 15, 15,
        15, 15, 15,
        15, 15, 15);

    // 定义G-API计算图
    cv::GComputation absDiffComp([](){
        cv::GMat in1, in2;
        cv::GMat out = cv::gapi::absDiff(in1, in2); // 计算逐像素绝对差值
        return cv::GComputation(cv::GIn(in1, in2), cv::GOut(out));
    });

    // 输出矩阵
    cv::Mat dst;

    // 执行计算图
    absDiffComp.apply(cv::gin(src1, src2), cv::gout(dst));

    // 打印结果
    std::cout << "Element-wise absolute difference result: \n" << dst << std::endl;

    return 0;
}
2.1.4运行结果
bash 复制代码
Element-wise absolute difference result: 
[  5,   5,  15;
  25,  35,  45;
  55,  65,  75]

2.2计算一个矩阵和一个标量之间的逐元素绝对差值函数absDiffC()

计算矩阵元素与给定标量值之间的绝对差值。

函数 absDiffC 计算输入矩阵 src 中每个元素与给定标量值 c 的绝对差值:
dst ( I ) = saturate ( ∣ src1 ( I ) − matC ( I ) ∣ ) \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{matC}(I)|) dst(I)=saturate(∣src1(I)−matC(I)∣)

其中,matC 是由给定的标量 c 构造的矩阵,并且具有与输入矩阵 src 相同的尺寸和深度。这意味着输出矩阵 dst 中的每个元素都是 src 中相应位置元素与标量 c 之差的绝对值。这里使用 saturate 表示结果会被限制在其数据类型的范围内(例如,对于 CV_8U 类型,结果将被限制在 [0, 255] 范围内)。

输出矩阵必须与 src 具有相同的尺寸和深度。

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

该函数的文本ID是 "org.opencv.core.matrixop.absdiffC"

2.2.1函数原型
cpp 复制代码
GMat cv::gapi::absDiffC 
(
 	const GMat &  	src,
	const GScalar &  	c 
) 	
2.2.2参数
  • 参数src: 输入矩阵。
  • 参数 c: 要减去的标量值。
2.2.3代码示例
cpp 复制代码
#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);

    // 定义标量
    cv::Scalar c(25); // 假设是灰度图像,所以只用一个值

    // 定义G-API计算图
    cv::GComputation absDiffCComp([](){
        cv::GMat in;
        cv::GScalar scalar_c;
        cv::GMat out = cv::gapi::absDiffC(in, scalar_c); // 计算逐像素绝对差值
        return cv::GComputation(cv::GIn(in, scalar_c), cv::GOut(out));
    });

    // 输出矩阵
    cv::Mat dst;

    // 执行计算图
    absDiffCComp.apply(cv::gin(src, c), cv::gout(dst));

    // 打印结果
    std::cout << "Element-wise absolute difference with scalar result: \n" << dst << std::endl;

    return 0;
}
2.2.4运行结果
bash 复制代码
Element-wise absolute difference with scalar result: 
[ 15,   5,   5;
  15,  25,  35;
  45,  55,  65]

2.3执行两个矩阵(或图像)的加权和操作函数addWeighted()

计算两个矩阵的加权和。

函数 addWeighted 计算两个矩阵的加权和,公式如下:
dst ( I ) = saturate ( src1 ( I ) ∗ alpha + src2 ( I ) ∗ beta + gamma ) \texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} ) dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma)

其中,I 是数组元素的多维索引。在处理多通道矩阵时,每个通道独立处理。

该函数可以用矩阵表达式替换为:
dst ( I ) = alpha ∗ src1 ( I ) − beta ∗ src2 ( I ) + gamma \texttt{dst}(I) = \texttt{alpha} * \texttt{src1}(I) - \texttt{beta} * \texttt{src2}(I) + \texttt{gamma} dst(I)=alpha∗src1(I)−beta∗src2(I)+gamma

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

该函数的文本ID是 "org.opencv.core.matrixop.addweighted"

2.3.1函数原型
cpp 复制代码
GMat cv::gapi::addWeighted 
(
 	const GMat &  	src1,
	double  	alpha,
	const GMat &  	src2,
	double  	beta,
	double  	gamma,
	int  	ddepth = -1 
) 		
2.3.2参数
  • 参数 src1: 第一个输入矩阵。
  • 参数 alpha: 第一个矩阵元素的权重。
  • 参数 src2: 第二个输入矩阵,其大小和通道数与 src1 相同。
  • 参数 beta: 第二个矩阵元素的权重。
  • 参数 gamma: 添加到每个和的标量。
  • 参数 ddepth: 输出矩阵的可选深度(位数)。如果为 -1,则输出矩阵的深度将与 src1 和 src2 相同。
2.3.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.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 ) << 90, 80, 70, 60, 50, 40, 30, 20, 10 );

    // 定义权重和偏移值
    double alpha = 0.5;
    double beta  = 0.5;
    double gamma = 10;

    // 定义G-API计算图
    cv::GComputation addWeightedComp( []() {
        cv::GMat in1, in2;
        double alpha = 0.5, beta = 0.5, gamma = 10;
        cv::GMat out = cv::gapi::addWeighted( in1, alpha, in2, beta, gamma );  // 计算加权和
        return cv::GComputation( cv::GIn( in1, in2 ), cv::GOut( out ) );
    } );

    // 输出矩阵
    cv::Mat dst;

    // 执行计算图
    addWeightedComp.apply( cv::gin( src1, src2 ), cv::gout( dst ) );

    // 打印结果
    std::cout << "Weighted sum with offset result: \n" << dst << std::endl;

    return 0;
}
2.3.4运行结果
cpp 复制代码
Weighted sum with offset result: 
[ 60,  60,  60;
  60,  60,  60;
  60,  60,  60]

2.4计算矩阵中非零元素的数量函数countNonZero()

计算非零数组元素的数量。

函数返回输入矩阵 src 中非零元素的数量:
∑ I :    src ( I ) ≠ 0 1 \sum _{I: \; \texttt{src} (I) \ne0 } 1 I:src(I)=0∑1

这意味着对于 src 中每个满足 src(I) ≠ 0 的元素,计数加一。

支持的矩阵数据类型包括:CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

该函数的文本ID是 "org.opencv.core.matrixop.countNonZero"

2.4.1函数原型
cpp 复制代码
GOpaque<int> cv::gapi::countNonZero 
(
 	const GMat &  	src
) 	
2.4.2参数
  • 参数 src: 输入的单通道矩阵。
代码示例
cpp 复制代码
#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, 1, 0, 1, 0, 1, 0, 1, 0 );

    // 定义G-API计算图
    cv::GComputation countNonZeroComp( []() {
        cv::GMat in;
        cv::GOpaque< int > out = cv::gapi::countNonZero( in );  // 计算非零元素数量
        return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );
    } );

    // 输出结果
    int nonZeroCount;

    // 执行计算图
    countNonZeroComp.apply( cv::gin( src ), cv::gout( nonZeroCount ) );

    // 打印结果
    std::cout << "Number of non-zero elements: " << nonZeroCount << std::endl;

    return 0;
}
运行结果
bash 复制代码
number of non-zero elements: 4

2.5用于检测输入矩阵 src 中哪些元素位于指定的上下界范围内(包括边界值)函数inRange()

对每个矩阵元素应用范围阈值。

函数对单通道或多通道矩阵应用范围级别的阈值。如果输入矩阵的相应像素值位于指定范围内,则设置输出像素值为0xFF(即255),否则设置为0。

输入和输出矩阵必须是 CV_8UC1 类型。

注意:

该函数的文本ID是 "org.opencv.core.matrixop.inRange"

2.5.1函数原型
cpp 复制代码
GMat cv::gapi::inRange 
(
 	const GMat &  	src,
	const GScalar &  	threshLow,
	const GScalar &  	threshUp 
) 	
2.5.2参数
  • 参数src: 输入矩阵(类型为 CV_8UC1)。
  • 参数threshLow: 下界阈值。
  • 参数threshUp: 上界阈值。
2.5.3代码示例
cpp 复制代码
#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 ) << 50, 100, 150, 200, 250, 30, 70, 80, 90 );

    // 定义阈值
    cv::Scalar threshLow( 30 );  // 下界阈值
    cv::Scalar threshUp( 100 );  // 上界阈值

    // 定义G-API计算图
    cv::GComputation inRangeComp( []() {
        cv::GMat in;
        cv::GScalar low, up;
        cv::GMat out = cv::gapi::inRange( in, low, up );  // 检测范围内的元素
        return cv::GComputation( cv::GIn( in, low, up ), cv::GOut( out ) );
    } );

    // 输出矩阵
    cv::Mat dst;

    // 执行计算图
    inRangeComp.apply( cv::gin( src, threshLow, threshUp ), cv::gout( dst ) );

    // 打印结果
    std::cout << "Elements within range result: \n" << dst << std::endl;

    return 0;
}
2.5.4运行结果

Elements within range result:

255, 255, 0; 0, 0, 255; 255, 255, 255

2.6计算输入图像的积分图函数 integral()

计算图像的积分图。

函数为源图像计算一个或多个积分图,具体如下:
sum ( X , Y ) = ∑ x < X , y < Y image ( x , y ) \texttt{sum} (X,Y) = \sum _{x<X,y<Y} \texttt{image} (x,y) sum(X,Y)=x<X,y<Y∑image(x,y)
sqsum ( X , Y ) = ∑ x < X , y < Y image ( x , y ) 2 \texttt{sqsum} (X,Y) = \sum _{x<X,y<Y} \texttt{image} (x,y)^2 sqsum(X,Y)=x<X,y<Y∑image(x,y)2

函数返回一个尺寸为 (W+1)×(H+1) 的积分图,数据类型可以是32位整数或浮点数(32f 或 64f),以及一个用于平方像素值的积分图;该平方积分图是一个尺寸为 (W+1)×(H+1) 的双精度浮点数(64f)数组。

注意:

该函数的文本ID是 "org.opencv.core.matrixop.integral"

2.6.1函数原型
cpp 复制代码
std::tuple<GMat, GMat> cv::gapi::integral 
(
 	const GMat &  	src,
	int  	sdepth = -1,
	int  	sqdepth = -1 
) 	
2.6.2参数
  • 参数 src: 输入图像。
  • 参数 sdepth: 积分图和倾斜积分图的期望深度,可以是 CV_32S, CV_32F 或 CV_64F。
  • 参数 sqdepth: 平方像素值积分图的期望深度,可以是 CV_32F 或 CV_64F。
2.6.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>
#include <opencv2/opencv.hpp>
#include <tuple>

int main()
{
    // 创建示例输入图像
    cv::Mat src = ( cv::Mat_< uchar >( 3, 3 ) << 1, 2, 3, 4, 5, 6, 7, 8, 9 );

    // 定义 G-API 计算图
    cv::GComputation integralComp( []() {
        cv::GMat in;
        auto res = cv::gapi::integral( in );
        return cv::GComputation( cv::GIn( in ), cv::GOut( std::get< 0 >( res ), std::get< 1 >( res ) ) );
    } );

    // 初始化输出矩阵(确保类型和尺寸正确)
    cv::Mat sum, sqsum;
    sum.create( src.rows + 1, src.cols + 1, CV_32SC1 );    // 积分图(32 位整数)
    sqsum.create( src.rows + 1, src.cols + 1, CV_64FC1 );  // 平方积分图(64 位浮点)

    try
    {
        integralComp.apply( cv::gin( src ), cv::gout( sum, sqsum ) );

        // 打印结果
        std::cout << "Integral image:\n" << sum << std::endl;
        std::cout << "Squared integral image:\n" << sqsum << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.6.4运行结果

出现了异常,怀疑是opencv内部错误导致,我改了好几遍还是这个错误,也许是我写错了?

bash 复制代码
Exception: OpenCV kernel output parameter was reallocated. 
Incorrect meta data was provided ?

2.7计算两个输入矩阵逐元素最大值的操作函数max()

计算两个矩阵的逐元素最大值。

max 函数计算两个相同大小、通道数和深度的矩阵的逐元素最大值:
dst ( I ) = max ⁡ ( src1 ( I ) , src2 ( I ) ) \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I)) dst(I)=max(src1(I),src2(I))

这里 I 是矩阵元素的一个多维索引。在处理多通道矩阵时,每个通道会独立处理。输出矩阵必须与 src1 具有相同的大小和深度。

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

函数的文字ID是 "org.opencv.core.matrixop.max"

2.7.1函数原型
cpp 复制代码
GMat cv::gapi::max
(
 	const GMat &  	src1,
	const GMat &  	src2 
) 	
2.7.2参数
  • 参数src1:第一个输入矩阵。
  • 参数src2:第二个输入矩阵,其大小和深度与 src1 相同。
2.7.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>     // 包含G-API核心功能
#include <opencv2/gapi/imgproc.hpp>  // 包含G-API图像处理功能
#include <opencv2/opencv.hpp>

int main()
{
    // 创建示例输入图像
    cv::Mat src1 = ( cv::Mat_< uchar >( 3, 3 ) << 1, 50, 3, 4, 5, 6, 7, 8, 9 );

    cv::Mat src2 = ( cv::Mat_< uchar >( 3, 3 ) << 2, 2, 20, 20, 2, 2, 2, 2, 2 );

    // 定义G-API计算图
    cv::GComputation maxComp( []() {
        cv::GMat in1, in2;
        auto out = cv::gapi::max( in1, in2 );  // 计算逐元素最大值
        return cv::GComputation( cv::GIn( in1, in2 ), cv::GOut( out ) );
    } );

    // 初始化输出矩阵
    cv::Mat dst;

    try
    {
        // 执行计算图
        maxComp.apply( cv::gin( src1, src2 ), cv::gout( dst ) );
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    // 打印结果
    std::cout << "Result image: \n" << dst << std::endl;

    return 0;
}
2.7.4运行结果
bash 复制代码
Result image: 
[  2,  50,  20;
  20,   5,   6;
   7,   8,   9]

2.8计算两个输入矩阵(GMat)的逐元素最小值函数min()

计算两个矩阵的逐元素最小值。

min 函数计算两个相同大小、通道数和深度的矩阵的逐元素最小值:
dst ( I ) = min ⁡ ( src1 ( I ) , src2 ( I ) ) \texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I)) dst(I)=min(src1(I),src2(I))

这里 I 是矩阵元素的一个多维索引。在处理多通道矩阵时,每个通道会独立处理。输出矩阵必须与 src1 具有相同的大小和深度。

支持的输入矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

函数的文字ID是 "org.opencv.core.matrixop.min"

2.8.1函数原型
cpp 复制代码
GMat cv::gapi::min
(
 	const GMat &  	src1,
	const GMat &  	src2 
) 	
2.8.2参数
  • 参数src1:第一个输入矩阵。
  • 参数src2:第二个输入矩阵,其大小和深度与 src1 相同。
2.8.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>     // 包含G-API核心功能
#include <opencv2/gapi/imgproc.hpp>  // 包含G-API图像处理功能
#include <opencv2/opencv.hpp>

int main()
{
    // 创建示例输入图像
    cv::Mat src1 = ( cv::Mat_< uchar >( 3, 3 ) << 10, 50, 30, 40, 5, 60, 70, 8, 9 );

    cv::Mat src2 = ( cv::Mat_< uchar >( 3, 3 ) << 20, 2, 200, 200, 2, 2, 2, 200, 2 );

    // 定义G-API计算图
    cv::GComputation minComp( []() {
        cv::GMat in1, in2;
        auto out = cv::gapi::min( in1, in2 );  // 计算逐元素最小值
        return cv::GComputation( cv::GIn( in1, in2 ), cv::GOut( out ) );
    } );

    // 初始化输出矩阵
    cv::Mat dst;

    try
    {
        // 执行计算图
        minComp.apply( cv::gin( src1, src2 ), cv::gout( dst ) );
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    // 打印结果
    std::cout << "Result image: \n" << dst << std::endl;

    return 0;
}
2.8.4运行结果
bash 复制代码
Result image: 
[ 10,   2,  30;
  40,   2,   2;
   2,   8,   2]

2.9计算输入矩阵 src 的无穷范数函数normInf()

计算矩阵的绝对无穷范数。

此版本的 normInf 计算 src 的绝对无穷范数。

以一个数组的函数为例,考虑函数 r ( x ) = ( x 1 − x ) , x ∈ [ − 1 ; 1 ] r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1] r(x)=(x1−x),x∈[−1;1]。对于样本值 r ( − 1 ) = ( − 1 2 ) r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix} r(−1)=(−12),其 L∞​ 范数计算如下:
∥ r ( − 1 ) ∥ L ∞ = max ⁡ ( ∣ − 1 ∣ , ∣ 2 ∣ ) = 2 \begin{align*} \| r(-1) \|{L\infty} &= \max(|-1|,|2|) = 2 \end{align*} ∥r(−1)∥L∞=max(∣−1∣,∣2∣)=2

对于 r ( 0.5 ) = ( 0.5 0.5 ) r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix} r(0.5)=(0.50.5),计算过程为:
∥ r ( 0.5 ) ∥ L ∞ = max ⁡ ( ∣ 0.5 ∣ , ∣ 0.5 ∣ ) = 0.5. \begin{align*} \| r(0.5) \|{L\infty} &= \max(|0.5|,|0.5|) = 0.5. \end{align*} ∥r(0.5)∥L∞=max(∣0.5∣,∣0.5∣)=0.5.

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

函数的文字ID是 "org.opencv.core.matrixop.norminf"

2.9.1函数原型
cpp 复制代码
GScalar cv::gapi::normInf 	
(
 	const GMat &  	src
) 	
2.9.2参数:
  • 参数 src:输入矩阵。
2.9.3代码示例
cpp 复制代码
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, -50, 3, 4, 5, 6, 7, 8, 9 );

    // 定义G-API计算图
    cv::GComputation normComp( []() {
        cv::GMat in;
        auto out = cv::gapi::normInf( in );  // 计算无穷范数
        return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );
    } );

    try
    {
        // 执行计算图并获取结果
**加粗样式**        cv::Scalar result;
        normComp.apply( cv::gin( src ), cv::gout( result ) );

        // 打印结果
        std::cout << "Infinity norm: " << result[ 0 ] << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.9.4运行结果
bash 复制代码
Infinity norm: 206

2.10 计算输入矩阵 src 的 L1 范数函数 normL1()

计算矩阵的绝对 L1 范数。

此版本的 normL1 计算 src 的绝对 L1 范数。

以一个数组的函数为例,考虑函数 r ( x ) = ( x 1 − x ) , x ∈ [ − 1 ; 1 ] r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1] r(x)=(x1−x),x∈[−1;1]。对于样本值 r ( − 1 ) = ( − 1 2 ) r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix} r(−1)=(−12),其 L1 范数计算如下:
∥ r ( − 1 ) ∥ L 1 = ∣ − 1 ∣ + ∣ 2 ∣ = 3 \begin{align*} \| r(-1) \|_{L_1} &= |-1| + |2| = 3 \\ \end{align*} ∥r(−1)∥L1=∣−1∣+∣2∣=3

对于 r ( 0.5 ) = ( 0.5 0.5 ) r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix} r(0.5)=(0.50.5),计算过程为:
∥ r ( 0.5 ) ∥ L 1 = ∣ 0.5 ∣ + ∣ 0.5 ∣ = 1 \begin{align*} \| r(0.5) \|_{L_1} &= |0.5| + |0.5| = 1 \\ \end{align*} ∥r(0.5)∥L1=∣0.5∣+∣0.5∣=1

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意

函数的文字ID是 "org.opencv.core.matrixop.norml1"

2.10.1函数原型
cpp 复制代码
GScalar cv::gapi::normL1 	
(
 	const GMat &  	src
) 	
2.10.2参数
  • 参数 src:输入矩阵。
2.10.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>

int main()
{
    // 创建示例输入图像
    cv::Mat src = ( cv::Mat_< float >( 3, 3 ) << 1.0f, -50.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f );

    // 定义G-API计算图
    cv::GComputation normComp( []() {
        cv::GMat in;
        auto out = cv::gapi::normL1( in );  // 计算L1范数
        return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );
    } );

    try
    {
        // 执行计算图并获取结果
        cv::Scalar result;
        normComp.apply( cv::gin( src ), cv::gout( result ) );

        // 打印结果
        std::cout << "L1 norm: " << result[ 0 ] << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.10.4运行结果
bash 复制代码
L1 norm: 93

2.11计算输入矩阵 src 的 L2 范数函数normL2()

计算矩阵的绝对 L2 范数。

此版本的 normL2 计算 src 的绝对 L2 范数。

以一个数组的函数为例,考虑函数 r ( x ) = ( x 1 − x ) , x ∈ [ − 1 ; 1 ] r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1] r(x)=(x1−x),x∈[−1;1]。对于样本值 r ( − 1 ) = ( − 1 2 ) r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix} r(−1)=(−12),其 L2 范数计算如下:
∥ r ( − 1 ) ∥ L 2 = ( − 1 ) 2 + ( 2 ) 2 = 5 \begin{align*} \| r(-1) \|_{L_2} &= \sqrt{(-1)^{2} + (2)^{2}} = \sqrt{5} \\ \end{align*} ∥r(−1)∥L2=(−1)2+(2)2 =5

对于 r ( 0.5 ) = ( 0.5 0.5 ) r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix} r(0.5)=(0.50.5),计算过程为:
∥ r ( 0.5 ) ∥ L 2 = ( 0.5 ) 2 + ( 0.5 ) 2 = 0.5 \begin{align*} \| r(0.5) \|_{L_2} &= \sqrt{(0.5)^{2} + (0.5)^{2}} = \sqrt{0.5} \\ \end{align*} ∥r(0.5)∥L2=(0.5)2+(0.5)2 =0.5

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

函数的文字ID是 "org.opencv.core.matrixop.norml2"

2.11.1函数原型
cpp 复制代码
GScalar cv::gapi::normL2 
(
 	const GMat &  	src
) 	
2.11.2参数
  • 参数 src:输入矩阵。
2.11.3代码示例
cpp 复制代码
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>  // 包含G-API核心功能
#include <opencv2/opencv.hpp>

int main()
{
    // 创建示例输入图像
    cv::Mat src = ( cv::Mat_< float >( 3, 3 ) << 1.0f, -50.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f );

    // 定义G-API计算图
    cv::GComputation normComp( []() {
        cv::GMat in;
        auto out = cv::gapi::normL2( in );  // 计算L2范数
        return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );
    } );

    try
    {
        // 执行计算图并获取结果
        cv::Scalar result;
        normComp.apply( cv::gin( src ), cv::gout( result ) );

        // 打印结果
        std::cout << "L2 norm: " << result[ 0 ] << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.11.4运行结果
bash 复制代码
L2 norm: 52.7352

2.12计算输入矩阵 src 的所有元素之和函数sum()

计算所有矩阵元素的和。

sum 函数计算矩阵中所有元素的和,每个通道独立计算。

支持的矩阵数据类型包括:CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1。

注意:

函数的文字ID是 "org.opencv.core.matrixop.sum"

2.12.1函数原型
cpp 复制代码
GScalar cv::gapi::sum 	
(
 	const GMat &  	src
) 	
2.12.2参数
  • 参数 src:输入矩阵。
2.12.3代码示例
cpp 复制代码
#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);

    // 定义G-API计算图
    cv::GComputation sumComp( []() {
        cv::GMat in;
        auto out = cv::gapi::sum( in );  // 计算元素之和
        return cv::GComputation( cv::GIn( in ), cv::GOut( out ) );
    } );

    try
    {
        // 执行计算图并获取结果
        cv::Scalar result;
        sumComp.apply( cv::gin( src ), cv::gout( result ) );

        // 打印结果
        std::cout << "Sum of all elements: " << result[ 0 ] << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.12.4运行结果
bash 复制代码
Sum of all elements: 45

2.13对输入矩阵 src 应用阈值操作函数threshold()

对每个矩阵元素应用固定级别的阈值。

该函数对单通道或多通道矩阵应用固定级别的阈值处理。此函数通常用于从灰度图像中生成双层(二进制)图像(也可以使用比较函数达到这一目的),或者用于去除噪声,即过滤掉像素值过小或过大的像素。函数支持几种不同类型的阈值处理,这些类型由 type 参数决定。

此外,特殊值 cv::THRESH_OTSU 或 cv::THRESH_TRIANGLE 可以与上述值之一组合使用。在这种情况下,函数会使用 Otsu 或 Triangle 算法来确定最优的阈值,并用这个值代替指定的 thresh。除了返回阈值处理后的矩阵外,函数还会返回计算得到的阈值。Otsu 和 Triangle 方法仅对 8 位矩阵实现。

在使用 cv::THRESH_OTSU 或 cv::THRESH_TRIANGLE 标志时,输入图像应为单通道。输出矩阵必须与 src 具有相同的大小和深度。

注意:

函数的文字ID是 "org.opencv.core.matrixop.threshold"

2.13.1函数原型
cpp 复制代码
GMat cv::gapi::threshold 
(
 	const GMat &  	src,
	const GScalar &  	thresh,
	const GScalar &  	maxval,
	int  	type 
) 	
2.13.2参数
  • 参数 src:输入矩阵(CV_8UC1, CV_8UC3 或 CV_32FC1)。
  • 参数 thresh:阈值。
  • 参数 maxval:当使用 cv::THRESH_BINARY 和 cv::THRESH_BINARY_INV 阈值类型时的最大值。
  • 参数 type:阈值类型(参见 cv::ThresholdTypes)。
2.13.3代码示例
cpp 复制代码
#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 ) << 50, 120, 180, 40, 160, 200, 30, 140, 220 );

    // 定义阈值和最大值
    cv::Scalar thresh = 100;  // 阈值
    cv::Scalar maxval = 255;  // 最大值

    // 定义G-API计算图
    cv::GComputation thresholdComp( []() {
        cv::GMat in;
        cv::GScalar th, mv;
        auto out = cv::gapi::threshold( in, th, mv, cv::THRESH_BINARY );  // 应用二值化阈值操作
        return cv::GComputation( cv::GIn( in, th, mv ), cv::GOut( out ) );
    } );

    try
    {
        // 执行计算图并获取结果
        cv::Mat dst;
        thresholdComp.apply( cv::gin( src, thresh, maxval ), cv::gout( dst ) );

        // 打印结果
        std::cout << "Thresholded image: \n" << dst << std::endl;
    }
    catch ( const std::exception& e )
    {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
2.13.4运行结果
bash 复制代码
Thresholded image: 
[  0, 255, 255;
   0, 255, 255;
   0, 255, 255]

完结=====

相关推荐
AngelPP20 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年20 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼20 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS20 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区1 天前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈1 天前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang1 天前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx
shengjk11 天前
NanoClaw 深度剖析:一个"AI 原生"架构的个人助手是如何运转的?
人工智能
西门老铁1 天前
🦞OpenClaw 让 MacMini 脱销了,而我拿出了6年陈的安卓机
人工智能