掌握imgproc组件:opencv-直方图与匹配

news2024/12/27 13:31:45

直方图与匹配

  • 1. 图像直方图概述
  • 2.直方图的计算与绘制
    • 2.1 计算直方图:calcHist()函数
    • 2.2 找寻最值:minMAxLoc()函数
    • 2.3 示例程序:绘制H-S直方图
  • 3.直方图对比
    • 3.1 对比直方图:compareHist()函数
    • 3.2 示例程序:直方图对比
  • 4.反射投影
    • 4.1 什么是反向投影
    • 4. 2 反向投影是如何工作的
    • 4.3 反向投影的作用
    • 4.4 计算反向投影:calcBackProject()函数
    • 4.5 复制通道:mixChannels()函数
    • 4.6 综合程序:反向投影
  • 5. 模板匹配
    • 5.1 模板匹配工作原理
    • 5.2 实现模板匹配:matchTemplate()函数

1. 图像直方图概述

直方图广泛运用于很多计算机视觉运用当中,通过标记帧与帧之间显著的边缘和颜色的统计变化,来检测视频中场景中场景的变化。在每个兴趣点设置一个有相近特征的直方图所构成"标签",用以确定图像中的兴趣点。边缘、色彩、角度等方图构成了可以被传递给目标识别分类器的一个通用特征类型。色彩和边缘的直方图序列还可以用来识别网络视频是否被复制。

其实,简单点说,直方图就是对数据进行统计的一种方法,并且将统计值组织到一系列事先定义好的bin当中。其中,bin为直方图中经常用到的一个概念,可翻译为“直条”或“组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。且无论如何,直方图获得的是数据分布的统计图。通常直方图的维数要低于原始数据。总而言之,直方图是计算机视觉中最经典的工具之一。

其实,简单点说,直方图就是对数据进行统计的一种方法,并且将统计值组织到一系列事先定义好的bin当中。其中,bin为直方图中经常用到的一个概念,可翻译为“直条”或“组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。且无论如何,直方图获得的是数据分布的统计图。通常直方图的维数要低于原始数据。总而言之,直方图是计算机视觉中最经典的工具之一。

在统计学中,直方图(Histogram)是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量。

我们在图像变换的那一章中讲过直方图的均衡化,它是通过拉伸像素强度分布范围来增强图像对比度的一种方法。大家在自己的心目中应该已经对直方图有一定的理解和认知。下面就来看一看对图像直方图比较书面化的解释。

图像直方图(Image Histogram)是用以表示数字图像中亮度分布的直方图,标绘了图像中每个亮度值的像素数。可以借助观察该直方图了解需要如何调整亮度分布。这种直方图中,横坐标的左侧为纯黑、较暗的区域,而右侧为较亮、纯白的区域。因此,一张较暗图片的图像直方图中的数据多集中于左侧和中间部分,而整体明亮、只有少量阴影的图像则相反。计算机视觉领域常借助图像直方图来实现图像的二值化。

直方图的意义如下。

  • 直方图是图像中像素强度分布的图形表达方式。
  • 它统计了每一个强度值所具有的像素个数。
    上面已经讲到,直方图是对数据的统计集合,并将统计结果分布于一系列预定的bins中。这里的数据不仅仅指的是灰度值,且统计数据可能是任何能有效

描述图像的特征。下面看一个例子,假设有一个矩阵包含一张图像的信息(灰度值0-255),让我们按照某种方式来统计这些数字。既然已知数字的范围包含256个值,于是可以将这个范围分割成子区域(也就是上面讲到bins),如:
[0,255]=[0,15]U[16,31]U…U[240,255]
range = bin1U bin2U…Ubinn=15

然后再统计每一个bini的像素数目。采用这一方法来统计上面的数字矩阵。
在这里插入图片描述
以上就是一个说明直方图的用途的简单示例。其实,直方图并不局限于统计颜色灰度,而是可以统计任何图像特征,如梯度、方向等。
让我们具体讲讲直方图的一些术语和细节。

  • dims:需要统计的特征的数目。在上例中,dims = 1因为我们仅仅统计了灰度值(灰度图像)。
  • bins:每个特征空间子区段的数目,可翻译为“直条”或“组距”。在上例中,bins = 16。
  • range:每个特征空间的取值范围。在上例中,range = [0,255]。

2.直方图的计算与绘制

2.1 计算直方图:calcHist()函数

void calcHish(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float ** ranges,bool uniform=true, bool accumulate=false)

  • 第一个参数:const Mat*类型的images,输入的数组(或数组集),他们需为相同的深度和相同的尺寸。
  • 第二个参数:int类型的nimages,输入数组的个数,也就是第一个参数中存放了多少张图像。
  • 第三个参数:const int*类型的channels,用于计算直方图的dims通道的列表。第一个数组通道从0到images[0].channels()-1,第二个数组通道从images[0].channels()到images[0].channels() + images[1].channels()-1,以此类推。
  • 第四个参数:InputArray类型的mask,可选地操作掩码。如果此掩码不为空,那么它必须为8位,并且与images[i]有相同大小的尺寸。这里的非零掩码元素用于标记出统计直方图的数组元素数据。
  • 第五个参数:OutputArray类型的hist,输出的目标直方图,一个二维数组。
  • 第六个参数:int类型的dims,需要计算的直方图的维度,必须是正数,且不大于CV_MAX_DIMS
  • 第七个参数:const int*类型的histSize,存放每个维度的直方图尺寸的数组。
  • 第八个参数:const float**类型range,每一维度数组(第六个参数dims)的每一维的边界阵列,可以理解为每一维数值的取值范围。
  • 第九个参数:表示直方图是否均匀的标志。
  • 第十个参数:积累标志。如果它被设置,直方图在开始分配时就不会被清除。这个特性使你能够从几组数组中计算出一个单一的直方图,或者及时更新直方图。

2.2 找寻最值:minMAxLoc()函数

void minMaxLoc(InputArray src, double* minVal, double* maxVal=0,Point* minLoc=0,Point* maxLoc=0,InputArray mask=noArray())

  • 第一个参数:输入图像
  • 第二个参数:返回最小值的指针;如果不需要,则使用NULL。
  • 第三个参数:返回最大值的指针;如果不需要,则使用NULL。
  • 第四个参数:返回最小位置的指针;如果不需要,则使用NULL。
  • 第五个参数:返回最大位置的指针;如果不需要,则使用NULL。
  • 第六个参数:可选的掩码,用于选择一个子阵列。

2.3 示例程序:绘制H-S直方图

注意:色调(Hue)、饱和度(Saturation)。所以H-S直方图就是色调——饱和度直方图。

#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main() {
	Mat srcImage, hsvImage;
	srcImage = imread("../../image/1.tif");
	cvtColor(srcImage, hsvImage, COLOR_BGR2HSV);

	
	//参数准备
	//将色调量化为30个等级,将饱和度量化为32个等级
	int hueBinNum = 30;  //色调的直方图直条数量
	int saturationBinNum = 32; //饱和度的直方图直条数量

	int histSize[] = { hueBinNum, saturationBinNum };
	
	//定义色调的范围为0-179
	float hueRnages[] = { 0,180 };

	//定义饱和度的变化范围为0-255
	float saturationRanges[] = { 0,256 };
	const float* ranges[] = { hueRnages,saturationRanges };
	MatND dstHist;
	
	//参数准备,calHist函数中将计算第0通道和第1通道的直方图
	int channels[] = { 0,1 };
	calcHist(&hsvImage,//输入的数组
		1,//数组个数为1
		channels,
		Mat(),//不适掩膜
		dstHist,
		2,//需要计算的直方图的维度为2
		histSize,//存放每个维度的直方图尺寸的数组
		ranges,//每一维数值的取值范围数组
		true,//指示直方图是否均匀的标识符
		false//累计标识符
	);

	double maxValue = 0;
	minMaxLoc(dstHist, 0, &maxValue, 0, 0);
	int scale = 10;

	Mat histImage = Mat::zeros(saturationBinNum * scale, hueBinNum * scale, CV_8UC3);

	//进行直方图绘制
	for (int hue = 0; hue < hueBinNum; hue++) {
		for (int saturation = 0; saturation < saturationBinNum; saturation++) {
			float binValue = dstHist.at<float>(hue, saturation);//直方图的值
			int intensity = cvRound(binValue * 255 / maxValue); //轻度
			
			//正式绘制
			rectangle(histImage, Point(hue * scale, saturation * scale),
				Point((hue+1)*scale-1,(saturation+1)*scale-1),Scalar::all(intensity),FILLED);
		}
	}
	imshow("素材图", srcImage);
	imshow("H-s直方图", histImage);
	waitKey();
}

在这里插入图片描述

3.直方图对比

3.1 对比直方图:compareHist()函数

compareHist()函数用于对两幅直方图进行比较。与两个版本的C++原型。
double compareHist(InputArray H1, InputArray H2, int method)
double compareHist(const SparseMat &H1, const SparseMat &H2)

  • 第一个参数:第一个比较直方图。
  • 第二个参数:第二个比较直方图,大小与H1相同
  • 第三个参数:比较方法
    在这里插入图片描述

3.2 示例程序:直方图对比

#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main() {
	Mat srcImage_base, hsvImage_base;
	Mat srcImage_test1, hsvImage_test1;
	Mat srcImage_test2, hsvImage_test2;
	Mat hsvImage_halfDown;

	//载入基准图像和两张测试图像
	srcImage_base = imread("1.jpg", 1);
	srcImage_test1 = imread("2.jpg", 1);
	srcImage_test2 = imread("3.jpg", 1);
	
	//显示载入的3张图像
	imshow("基准 图像", srcImage_base);
	imshow("测试图像1", srcImage_test1);
	imshow("测试图像2", srcImage_test2);

	//将图像有BGR色彩空间转换到HSV色彩空间
	cvtColor(srcImage_base, hsvImage_base, COLOR_BGR2HSV);
	cvtColor(srcImage_test1, hsvImage_test1, COLOR_BGR2HSV);
	cvtColor(srcImage_test2, hsvImage_test2, COLOR_BGR2HSV);

	//创建包含基准图像下半部的半身图像
	hsvImage_halfDown = hsvImage_base(Range(hsvImage_base.rows / 2,
		hsvImage_base.rows - 1), Range(0, hsvImage_base.cols - 1));
	//初始化计算直方图需要的实参
	int h_bins = 50;
	int s_bins = 60;
	int histSize[] = { h_bins,s_bins };
	float h_range[] = { 0,256 };
	float s_range[] = { 0,180 };
	const float* range[] = { h_range,s_range };
	int channels[] = { 0,1 };

	//创建存储直方图的MatND类的实例
	MatND baseHist;
	MatND halfDownHist;
	MatND testHist1;
	MatND testHist2;

	//计算基准图像,两张测试图像,半身基准图像的HSV直方图
	calcHist(&hsvImage_base, 1, channels, Mat(), baseHist, 2, histSize,
		range, true, false);
	normalize(baseHist, baseHist, 0, 1, NORM_MINMAX, -1);

	calcHist(&hsvImage_halfDown, 1, channels, Mat(), halfDownHist, 2, histSize,
		range, true, false);
	normalize(halfDownHist, halfDownHist, 0, 1, NORM_MINMAX, -1);

	calcHist(&hsvImage_test1, 1, channels, Mat(), testHist1, 2, histSize,
		range, true, false);
	normalize(testHist1, testHist1, 0, 1, NORM_MINMAX, -1);


	calcHist(&hsvImage_test2, 1, channels, Mat(), testHist2, 2, histSize,
		range, true, false);
	normalize(testHist2, testHist2, 0, 1, NORM_MINMAX, -1);

	//按顺序使用四种对比标准图像的直方图与其余各直方图进行对比
	for (int i = 0; i < 4; i++) {
		int compare_method = i;
		double base_base = compareHist(baseHist, baseHist, compare_method);
		double base_half = compareHist(baseHist, halfDownHist, compare_method);
		double base_test1 = compareHist(baseHist, testHist1, compare_method);
		double base_test2 = compareHist(baseHist, testHist2, compare_method);
		
		//输出结果
		cout << "\n方法" << i+1 << "匹配结果如下";
		cout << "\n【基准图-基准图】" << base_base << "  ";
		cout << "\n【基准图-半身图】" << base_half << "  ";
		cout << "\n【基准图-测试图1】" << base_test1 << "  ";
		cout << "\n【基准图-测试图2】" << base_test2 << "  ";
	}

	waitKey();
	return 0;
}

在这里插入图片描述
在这里插入图片描述

4.反射投影

4.1 什么是反向投影

反向投影是一种记录给定图像的像素与直方图模型中的像素分布的吻合程度的方法。
说得简单些:对于Back Projection,你计算一个特征的直方图模型,然后用它来寻找图像中的这个特征。
应用实例:如果你有一个肉色的直方图(例如,色相-饱和度直方图),那么你可以用它来寻找图像中的肉色区域。

4. 2 反向投影是如何工作的

我们用皮肤的例子来解释这个问题:
假设你已经根据下面的图片得到了一个皮肤直方图(色相-饱和度)。这个直方图除了将是我们的模型直方图(我们知道它代表了皮肤色调的一个样本)。你应用了一些遮罩,只捕捉皮肤区域的直方图:在这里插入图片描述
现在,让我们想象一下,你得到另一个像下面这样的手部图像(测试图像):(连同其各自的直方图)
在这里插入图片描述
我们要做的是使用我们的模型直方图(我们知道它代表皮肤色调)来检测测试图像中的皮肤区域。以下是具体步骤

  1. 在测试图像的每个像素(即p(i,j))中,收集数据并找到该像素对应的bin位置(即(hi,j,si,j))。
  2. 在对应的bin - (hi,j,si,j)中查询模型直方图,并读取bin值。
  3. 将这个bin值存储在一个新的图像中(BackProjection)。另外,你可以考虑先将模型直方图归一化,这样测试图像的输出就可以为你所见。
  4. 应用上述步骤,我们得到以下测试图像的BackProjection图像:在这里插入图片描述
  5. 在统计学方面,根据我们使用的模型直方图,BackProjection中存储的值代表了测试图像中一个像素属于皮肤区域的概率。例如,在我们的测试图像中,较亮的区域更有可能是皮肤区域(因为它们实际上是),而较暗的区域的概率较小(注意这些 "暗 "的区域属于有一些阴影的表面,这反过来影响了检测)。

4.3 反向投影的作用

反向投影用于在输入图像中找与特定图像最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。

4.4 计算反向投影:calcBackProject()函数

void calcBackProject(const Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true)

  • 第一个参数:源数组。它们都应该有相同的深度,CV_8U、CV_16U或CV_32F,而且大小相同。它们中的每一个都可以有任意数量的通道。
  • 第二个参数:源图像的数量。
  • 第三个参数:用来计算反向投影的通道列表。通道的数量必须与直方图的维度一致。第一个数组通道从0到images[0].channels()-1,第二个数组通道从images[0].channels()到images[0].channels() + images[1].channels()-1,以此类推。
  • 第四个参数:输入直方图,可以是密集的或稀疏的。
  • 第五个参数:目标反向投影阵列,其须为单通道,并且和image[0]有相同的大小和深度。
  • 第六个参数:const float**类型的ranges,表示每一维度数组的每一维的边界阵列,可以理解为每一维数值的取值范围。
  • 第七个参数:输出的方向投影可选地缩放因子
  • 第八个参数:指示直方图是否均匀的标识符

4.5 复制通道:mixChannels()函数

将输入阵列中的指定通道复制到输出阵列的指定通道。
在这里插入图片描述

4.6 综合程序:反向投影

#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

#define WINDOW_NAME1 "原始图"

Mat g_srcImage, g_hsvImage, g_hueImage;
int g_bins = 30; 

//回调函数
void on_BinChange(int, void*) {
	MatND hist;
	int histSize = MAX(g_bins, 2);
	float hue_range[] = { 0,180 };
	const float* ranges = { hue_range };

	calcHist(&g_hueImage,1,0,Mat(),hist,1,&histSize,&ranges,true,false);
	normalize(hist, hist, 0, 255, NORM_MINMAX, -1);

	//计算反向投影
	MatND backproj;
	calcBackProject(&g_hueImage, 1, 0, hist, backproj, &ranges, 1, true);

	imshow("反向投影图", backproj);
	
	//绘制直方图的参数准备
	int w = 400, h = 400;
	int bin_w = cvRound((double)w / histSize);
	Mat histImg = Mat::zeros(w, h, CV_8UC3);

	//绘制直方图
	for (int i = 0; i < g_bins; i++) {
		rectangle(histImg,
			Point(i * bin_w, h),
			Point((i + 1) * bin_w, h - cvRound(hist.at<float>(i) * h / 255.0)),
			Scalar(100, 123, 255),1);
	}
	imshow("直方图", histImg);

}

int main() {
	g_srcImage = imread("../../image/1.tif");
	cvtColor(g_srcImage, g_hsvImage, COLOR_BGR2HSV);

	g_hueImage.create(g_hsvImage.size(), g_hsvImage.depth());
	int ch[] = { 0,0 };
	mixChannels(&g_hsvImage, 1, &g_hueImage, 1, ch, 1);

	namedWindow(WINDOW_NAME1);
	createTrackbar("色调组距", WINDOW_NAME1, &g_bins, 180, on_BinChange);
	on_BinChange(0, 0);
	imshow(WINDOW_NAME1, g_srcImage);

	waitKey();
}

在这里插入图片描述

5. 模板匹配

模板匹配是一种寻找图像中与模板图像(补丁)相匹配(相似)的区域的技术。

虽然补丁必须是一个矩形,但可能并非所有的矩形都是相关的。在这种情况下,可以用一个遮罩来隔离应该用来寻找匹配的那部分补丁。

5.1 模板匹配工作原理

我们需要两个主要组成部分:

  • 源图像(I):我们希望在其中找到与模板图像相匹配的图像
  • 模板图像(T):将与源图像进行比较的补丁图像
    我们的目标是检测最高的匹配区域:
    在这里插入图片描述
    为了识别匹配区域,我们必须通过滑动模板图像与源图像进行比较:
    在这里插入图片描述通过滑动,我们的意思是每次移动一个像素的补丁(从左到右,从上到下)。在每一个位置,都会计算出一个度量,因此它代表了该位置的匹配度有多 "好 "或 “坏”(或者该补丁与源图像的那个特定区域有多相似)。
    对于T在I上的每一个位置,你把度量值存储在结果矩阵R中:
    上面的图片是用TM_CCORR_NORMED指标滑动补丁的结果R。最亮的位置表示最高的匹配。正如你所看到的,红圈标记的位置可能是数值最高的位置,所以这个位置(以该点为角,宽度和高度等于补丁图像所形成的矩形)被认为是匹配的。
    在实践中,我们在R矩阵中定位最高值(或更低,取决于匹配方法的类型),使用函数minMaxLoc()。

5.2 实现模板匹配:matchTemplate()函数

在这里插入图片描述

  • 第一个参数:正在运行搜索的图像。它必须是8位或32位浮点。
  • 第二个参数:搜索模板,需和源图像有一样的数据类型,且大小不能超过源模板
  • 第三个参数:比较结果的映射图像。它必须是单通道的32位浮点。如果图像是W×H,模板是w×h,那么结果是(W-w+1)×(H-h+1) 。
  • 第四个参数:指定比较方法的参数
    在这里插入图片描述
  • 第五个参数:可选的掩码。它必须具有与templ相同的大小。它必须具有与模板相同的通道数,或者只有一个通道,然后用于所有模板和图像通道。如果数据类型是CV_8U,掩码被解释为二进制掩码,意味着只有掩码为非零的元素被使用,并且保持不变,与实际掩码值无关(权重等于1)。对于数据 tpye CV_32F,掩码值被用作权重。

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

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

相关文章

Dubbo接口级服务发现-数据结构

目录 Dubbo服务治理易用性的原理&#xff1a; URL地址数据划分&#xff1a; Dubbo接口级服务发现---易用性的代价 Proposal&#xff0c;适应云原生、更大规模集群的服务发现类型。 Dubbo3应用级服务发现---基本原理 Dubbo负载均衡机制 常规负载均衡算法 负载均衡策略&am…

leetcode526. 优美的排列(回溯算法-java)

优美的排列 leetcode526. 优美的排列题目描述接替思路代码演示: 动态规划专题 leetcode526. 优美的排列 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/beautiful-arrangement 题目描述 假设有从 1 到 n 的 n 个整数。用…

【Python 随练】判断一个5位数是否为回文数

题目&#xff1a; 一个 5 位数&#xff0c;判断它是不是回文数。即 12321 是回文数 &#xff0c;个位与万位相同&#xff0c;十位与千位相同。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个编程问题&#xff1a;判断一个5位数是否为回文数。回文数是指从左到右…

数字IC前端学习笔记:近期最少使用(LRU)算法

相关文章 数字IC前端学习笔记&#xff1a;LSFR&#xff08;线性反馈移位寄存器&#xff09; 数字IC前端学习笔记&#xff1a;跨时钟域信号同步 数字IC前端学习笔记&#xff1a;信号同步和边沿检测 数字IC前端学习笔记&#xff1a;锁存器Latch的综合 数字IC前端学习笔记&am…

Java新特性-Functon接口

Java新特性-Functon接口 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ Spring专栏&#x1f449;https://blog.csdn.net/weixin_53580595/category_12279588.html Sprin…

使用CRM系统如何让你的企业受益

随着市场的竞争日益加剧&#xff0c;企业需要更好地管理客户关系和提高销售。为此&#xff0c;很多企业已经开始使用CRM系统。CRM系统是一种管理客户关系的工具&#xff0c;可以帮助企业更好地了解客户需求&#xff0c;提高销售效率&#xff0c;提高客户满意度和忠诚度等。在这…

【ARM AMBA APB 入门 2 -- Debug APB总线介绍】

文章目录 1.1 DEBUG APB 介绍1.1.1 Debug APB interface 1.2 Debug APB 与 APB 的区别 1.1 DEBUG APB 介绍 ARM Debug APB是一种用于调试ARM处理器的总线协议。它是一种简化的、低功耗的调试接口&#xff0c;用于与处理器内部的调试逻辑进行通信。 ARM Debug APB具有以下特点…

使用Py2neo构建知识图谱(概念与实现)

知识图谱是一种用于描述实体之间关系的图形化知识表示方法&#xff0c;它将实体、属性和关系组织成一个大型的、半结构化的知识库。知识图谱的应用非常广泛&#xff0c;包括语义搜索、智能问答、个性化推荐、内容分发等领域。 知识图谱的构建方法有很多种&#xff0c;其中比较…

基于SpringBoot和Vue的医疗设备管理系统的设计与实现(源码+文档+报告)

伴随着网络技术的发展&#xff0c;网络巨头们也在各自的行业中展开了激烈的竞争。网络技术已经渗透到了社会的各个角落&#xff0c;移动支付、远程医疗和健康管理等多种网络技术的普及也日益广泛。同时&#xff0c;网络产业的崛起也极大地影响了传统产业。对医疗设备管理系统的…

Axure设计之动态柱状图教程(中继器)

中继器作为复杂的元件&#xff0c;通常被用来制作“高保真”的动态原型&#xff0c;以达到良好的视觉效果和交互效果。本文将教大家通过AxureRP9工具如何使用中继器设计动态柱状图表。 一、案例效果 下载地址&#xff1a; https://download.csdn.net/download/u010709330/8797…

多元分类预测 | Matlab鹈鹕算法(POA)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,POA-HKELM分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab鹈鹕算法(POA)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,POA-HKELM分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab…

QT5.12安卓环境的搭建(转载保存留档查看)

1. QT环境搭建 Qt 5.12.6安装的时候 添加 “Android ARM64-v8a”&#xff0c;也可以添加 “Android ARMv7” 。 &#xff08;其它为搭建qgc时需要添加的&#xff09; 2. Android 环境搭建 QT官方的指导&#xff1a; Qt 5.12 Getting Started with Qt for Android Qt 5.15 …

C语言-函数栈帧(每次调用函数,开辟函数的大概流程)

思路&#xff1a; emm&#xff0c;有点懵&#xff0c;这一块&#xff0c;只知道个大概&#xff0c;如果后期我深挖的话&#xff0c;我再回头来补充上图括号的位置&#xff0c;便是每次创建&#xff0c;调用函数的时候&#xff0c;所产生的函数栈帧&#xff0c;也可以理解为每次…

(五)Qt 动态手势识别“左右滑动”以及实现翻页效果

系列文章目录 通过Qt实现手势识别控制软件操作相关系列技术方案 &#xff08;一&#xff09;Qt 将某控件、图案绘制在最前面的方法&#xff0c;通过QGraphicsScene模块实现 &#xff08;二&#xff09;Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方&#xff0c;实现圆…

Spring Boot 中的 SockJS

Spring Boot 中的 SockJS 在 Spring Boot 中&#xff0c;SockJS 是一个用于实现 WebSocket 的兼容性解决方案。本文将介绍 SockJS 的原理、使用方法和示例代码。 什么是 SockJS SockJS 是一种浏览器与服务器之间的通信协议&#xff0c;它可以在浏览器和服务器之间建立一个基于…

python--tornado服务

一、前言 Tornado是一个基于非阻塞I/O的Web框架&#xff0c;具有可以处理大量并发连接&#xff0c;适用于高并发的场景的高性能&#xff0c;轻量级和异步支持的优点。 本篇主要展示了使用 tornado http post 和 get 服务 二、代码 tornado http post 和 get 服务 # -*- codin…

视频拼接融合产品的产品与架构设计(一)

1视频拼接产品概述 将多达8个视频拼接在一起&#xff0c;拼成上帝视角的大图&#xff0c;并且可以共享最终生成的画面。 1.1 三维方案 三维方案是我在晚上思考的时候无意想到&#xff0c;这种方案应该是最接近事实的方案&#xff0c;多个画面应该是在三个维度&#xff0c;x&…

智慧产业园区管理系统主要包含哪些

智能设备管理 本文介绍的是智慧产业园区管理系统中的智能设备管理。智能设备管理是智慧产业园区管理系统中的重要组成部分&#xff0c;它可以为企业提供高效、智能化的设备管理服务。通过智能设备管理系统&#xff0c;企业可以对设备进行实时监控和在线运维&#xff0c;及时发…

JS知识点汇总(五)--执行上下文

1. JavaScript中执行上下文和执行栈是什么&#xff1f; 1、执行上下文 执行上下文是一种对Javascript代码执行环境的抽象概念&#xff0c;也就是说只要有Javascript代码运行&#xff0c;那么它就一定是运行在执行上下文中 执行上下文的类型分为三种&#xff1a; 全局执行上…