Opencv C++图像处理:矩阵Mat + 随机数RNG + 计算耗时 + 鼠标事件

本文介绍了C++中的数据类型及其字节数和取值范围,详细讲解了OpenCV中的Mat对象,包括如何创建和访问二维矩阵,以及像素获取方法。此外,还讨论了随机数生成和图像计算过程中的颜色溢出处理。最后,提到了鼠标和轨迹条操作在OpenCV中的应用。
摘要由CSDN通过智能技术生成

1、C++的数据类型+字节数+取值范围

数据类型字节数取值范围
bool型(布尔型)1[0 or 1]
BOOL型(int型)4[TRUE or FALSE]
sbyte型(有符号8位整数)1[128 ~ 127]
bytet型(无符号8位整数)8U2[0 ~ 255]
short型(有符号16位整数)16S2[-32,768 ~ 32,767]
ushort型(无符号16位整数)16U2[0 ~ 65,535]
int型(有符号32位整数)32S4[-2,147,483 ~ 2,147,483,647]
uint型(无符号32位整数)4[0 ~ 4,294,967,295]
long型(64位有符号整数)8[9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807]
ulong型(64位无符号整数)8[0 ~ 18,446,744,073,709,551,615]
float型(32位单精度实数)32F4[3.4E+10的负38次方 ~ 3.4E+10的38次方]
double型(64位双精度实数)64F8[1.7E+10的负308次方 ~ 1.7E+10的正308次方]
指针4

注意:int,float,double占多少个字节是由编译器决定的,不同的编译器,规定也不一样。ANSI标准定义int是占2个字节。

2、Mat对象:n 维单/多通道的密集矩阵

Mat(n-dimensional dense array class): 用于存储数值、向量、矩阵、灰度或彩色图像、体素体积、向量场、点云、张量、直方图。
Mat类:创建并访问二维、三维、四维、五维矩阵
Mat类:矩阵相乘——点乘、dot、mul运算详解

OpenCV C++使用 Mat 来存储图像数据,每个像素点的数据格式由存储格式和通道数组成。

> 表达式:CV_{depth}C{channels}
> 		depth表示每个像素点的存储格式
> 		channels表示每个像素点的通道数。
> 即CV_{8U, 16S, 16U, 32S, 32F, 64F}C{1, 2, 3, 4}。

	(1)存储格式类型:8U, 16S, 16U, 32S, 32F, 64F
				8U(unsigned char), 
				16S(short int), 16U(unsigned short int), 
				32S(signed int), 32F(float), 
				64F(double), 
				
		备注:	8U取值范围 =[0, 255],
		 		16U取值范围=[0, 65535], 
		 		32f取值范围=[3.4E+10的负38次方 ~ 3.4E+1038次方].2)通道数类型:C{1, 2, 3, 4}
				C1(单通道图像)。如:gray灰度图
				C3(3 通道图像)。如:RGB 彩色图
				C4(4 通道图像)。如:带有透明度通道的RGB图像

常规RGB图像的存储格式CV_8UC3:表示8位无符号整型3通道矩阵.
		
		假设矩阵Mat = (100, 100, 3)
		11、像素点个数:100 x 100 x 3 = 30000
		22、存储格式:8U。表示每个像素点的值是8位无符号整数,即占用1个字节空间。
		33、通道数:C3。表示每个像素点有3个通道,即存放3个像素值。

图像计算时,需要将读取图像格式CV_8UC3(Vec3b)转换为CV_32F(Vec3F),计算之后再转回CV_8UC3(Vec3b)

  • (1)图像处理:直接处理,无需转换。
  • (2)图像计算:为了保持高精度,避免信息损失,需要转换。
    • CV_8UC1(uchar):8位无符号整型,单通道矩阵
    • CV_8UC3(Vec3b):8位无符号整型,三通道矩阵
    • CV_32FC3(Vec3F):32位浮点型,三通道矩阵

2.1、创建 Mat 矩阵

函数说明:cv::Mat M_temp(row, column, data_type, cv::Scalar(0, 0, 255))
输入参数:		
				row					矩阵的行
				column				矩阵的列
				data_type			图像的数据格式
				Scalar(0, 0, 255)	初始化RGB的像素值。
									(0, 0, 255)表示R/G全为0,B全为255
				
//
cv::Mat img1(480, 640, CV_8UC3);		//新建矩阵
cv::Mat img2(img1);						//复制矩阵

cv::Mat img7 = cv::Mat::zeros(rows, cols, CV_8UC3); 		//值全0矩阵。
cv::Mat img8 = cv::Mat::ones(rows, cols, CV_64FC1); 		//值全1矩阵。
cv::Mat img9 = cv::Mat::eye(rows, cols, CV_16SC2); 			//单位矩阵。		

2.2、获取像素1:img.at(y,x)

cv::Mat img = cv::Mat::ones(240, 320, CV_8UC1);				//创建单通道Mat矩阵
cv::Mat img1 = cv::Mat::ones(480, 640, CV_8UC3);			//创建多通道Mat矩阵

float elem = img.at<uchar>(10, 10);							//获取(单通道)像素点的像素值:img.at<uchar>(y,x)
cv::Vec3b elem = img1.at<cv::Vec3b>(10, 10);				//获取(多通道)像素点的像素值:img.at<cv::Vec3b>(y,x)
elem_B = elem[0]; 			//蓝色通道数值(全255)
elem_G = elem[1]; 			//绿色通道数值(全255)
elem_R = elem[2]; 			//红色通道数值(全0)

2.3、获取像素2(防止颜色溢出):saturate_cast(y,x)

避免边界溢出(截断):

  • 若像素值大于255,则赋值255;
  • 若像素值小于0,则赋值0。
//原理如下
if (data_value < 0) 
	data_value = 0; 
else if (data_value > 255) 
	data_value = 255;
#include <opencv2/opencv.hpp>
//using namespace cv;
//using namespace std;

int main(int argc, const char* argv[]) 
{
    //(1)读取图像
    std::string img_path = "test.jpg";
    cv::Mat src = cv::imread(img_path, 1);

    //(2)判断图像是否读取成功
    if (!src.data)
    {
        std::cout << "can't read image!" << std::endl;
        return -1;
    }
    
    //(3)获取元素
    cv::Mat dst1, dst2;
	dst1 = cv::Mat::zeros(src.size(), src.type());	
	dst2 = cv::Mat::zeros(src.size(), src.type());

	//三个for循环:dst(i,j) =a * src(i,j) + b
	for (int y = 0; y < src.rows; y++)
	{
		for (int x = 0; x < src.cols; x++)
		{
			for (int c = 0; c < 3; c++)		//三个通道
			{
				dst1.at<cv::Vec3b>(y, x)[c] = src.at<cv::Vec3b>(y, x)[c] * 2;								//不饱和滤除
				dst2.at<cv::Vec3b>(y, x)[c] = cv::saturate_cast<uchar>(src.at<cv::Vec3b>(y, x)[c] * 2);		//饱和滤除
			}
		}
	}
	
	//(4)显示图像
	cv::imshow("src", src);
	cv::imshow("dst1", dst1);
	cv::imshow("dst2", dst2);

	cv::waitKey(0);
	return 0;
}

2.4、Mat矩阵常用属性

cv::Mat img(320, 320, CV_8UC3, cv::Scalar(255, 255, 0));		//创建320×320的3通道彩色图像。

Mat.rows 				获取矩阵:行数
Mat.cols 				获取矩阵:列数
Mat.dims 				获取矩阵:维数(单通道是二维,多通道是三维)
Mat.channels() 			获取矩阵:通道数
Mat.size();				获取矩阵:大小
Mat.total() 			获取矩阵:面积=[行数*列数](与通道数无关)
Mat.depth()				获取矩阵:存储格式(返回0~6):enum{CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6}  

Mat.row(0) 				获取矩阵:第一行元素组成的数组。
Mat.col(0) 				获取矩阵:第一列元素组成的数组。
Mat.rowRange(0, 10)		获取矩阵:第0-10行元素组成的数组。
Mat.colRange(0, 10)		获取矩阵:第0-10列元素组成的数组。

Mat.empty();			判断矩阵是否为空,若为空,则返回true。
Mat.clone()				复制矩阵并赋值给新矩阵。

Mat.setTo(0);						将矩阵全部设置为指定值(0)。如:src.setTo(0, src<10);当src中的某个像素值小于10,就将该值设置成0。
MatA.copyTo(MatB)					将矩阵A复制到矩阵B中。
Mat.convertTo(img, CV_32F)			将img的数据格式转换为CV_32F。
Mat.push_back()						将一个或多个元素添加到矩阵底部。其类型和列数必须与Mat矩阵中的相同。

3、基本数据类型

3.1、Point类:cv::Point()

cv::Point类由两个部分组成:cv::Point{2, 3}{b, s, i, f, d}。
		(1)维度			23代表维度(分别代表2个点、3个点)
		(2)存储类型		b: 表示无符号字符
							s: 表示短整型
							i: 表示32位整型
							f: 表示32位浮点数
							d: 表示64位浮点数
							
Point类支持的操作:
		默认构造函数:		cv::Point2i p;	
							cv::Point3i p;
		复制构造函数:		cv::Point3f p2(p1);
		值构造函数:			cv::Point2i(x0,x1);
							cv::Point3d p(x0,x1,x2);
		构造固定向量类:		cv::Vec3f p;
		成员访问:			p.x, p.y;
		点乘:				float x = p1.dot(p2);
		双精度点乘:			double x =p1.ddot(p2);
		叉乘:				p1.cross(p2)

3.2、Scalar类:cv::Scalar()

cv::Scalar本质上是一个四维向量,其可以产生任意四元素的向量,一般是double类型。

Scalar类支持的操作:
		默认构造函数:				cv::Scalar s;
		复制构造函数:				cv::Scalar s2(s1);
		值构造函数:					cv::Scalar s(x0);
									cv::Scalar s(x0, x1, x2, x3);
		返回所有元素都为标量k:		cv::Scalar::all(k)		
		
		元素相乘:					s1.mul(s2);
		(四元数)共轭:				s.conj();		//return cv::Scalar(s0,-s1,-s2,-s2)
		(四元数)真值测试:			s.isReal();		//return ture, if s1==s2==s3==0.

3.3、Size类:cv::Size()

Size类支持的操作:
		默认构造函数:		cv::Size sz; 
							cv::Size2i sz;
							cv::Size2f sz;
		复制构造函数:		cv::Size sz2(sz1);
		值构造函数:			cv::Size2f sz(w,h);
		成员访问:			sz.width, sz.height;
		计算面积:			sz.area();

3.4、Rect类:cv::Rect()

Rect类包含:		
			(1)Point类的成员(x, y)。				矩形左上角
			(2)Size类的成员(width, height)。		代表矩形的大小

4.1 Rect类支持的操作:
		默认构造函数:			cv::Rect r;
		复制构造函数:			cv::Rect r2(r1);
		值构造函数:				cv::Rect(x, y, w, h);
		由起始点和大小构造:		cv::Rect(p, sz);
		由两个对角构造:			cv::Rect(p1, p2);
		成员访问:				r.x, r.y, r.width, r.height;
		计算面积:				r.area();
		提取左上角和右下角:		r.tl(), r.br();
		判断p点是否在矩形r内:	r.contains(p);

4.2 Rect类的覆写操作:
		矩形r1和矩形r2的交集:			cv::Rect r3 = r1&r2; r1 &= r2;
		矩形r1和矩形r2的并集:			cv::Rect r3 = r1|r2; r1 |= r2;
		平移矩形r x个数量:				cv::Rect rx = r+x; r += x;
		扩大矩形r s大小:				cv::Rect rs = r+s; r += s;
		比较矩形r1和矩形r2是否相等:		bool eq = (r1 == r2);
		比较矩形r1和矩形r2是否不相等:	bool ne = (r1 != r2);

3.5、Matx类:cv::Matx()

固定矩阵类(Matx类):
		是为了使编译时就已知矩阵的维度而设计,其内部所有数据都是在堆栈上分配的。
		其是Opencv的c++接口基本类型的核心。
		其继承于固定矩阵类。而其他的类:要么继承于固定向量类,要么转换成固定向量类。
		其是一个模板cv::Matx<>,但独立的矩阵通常通过别名分配。别名的基础格式为cv::Matx{1,2,3,4,5,6}{1,2,3,4,5,6}{f,d}5.1 Matx类支持的操作:
		默认构造函数:		cv::Matx33f m22f;
							cv::Matx43d m43d;
		复制构造函数:		cv::Matx22d m22d(n22d);
		值构造函数:			cv::Matx21f m(x0,x1);
		含相同元素的矩阵:	m33f = cv::Matx33f::all(x);
		全零矩阵:			m23d = cv::Matx23d::zeros();
		元素全是1的矩阵:	m16f = cv::Matx16f::ones();
		单位矩阵:			m33f = cv::Matx33f::eye();
		均匀分布矩阵:		m33f = cv::Matx33f::randu(min,max);
		正态分布矩阵:		m33f = cv::Matx33f::nrandu(mean,variance);
		成员访问:			m(i,j), m(i);

矩阵能正常的进行加减乘除:
		点积:						float x = m1.dot(m2);
		双精度点积:					double x = m1.ddot(m2);
		变换操作符:					m44f = (Matx44f) m44d;
		提取(i, j)处的2*2子矩阵:	m44f.get_minor<2,2>(i, j);
		提取第i行或者j列:			m14f = m44f.row(i),m41f = m44f.col(j);
		提取矩阵的对角线:			m41f = m44f.diag();
		计算矩阵转置:				n44f = m44f.t();
		计算矩阵的逆:				n44f = m44f.inv(method);
		每个元素的乘法:				m1.mul(m2);

3.6、Vec类:cv::Vec()

6.1 Vec类支持的操作:
		默认构造函数:		cv::Vec2s v2s;
		复制构造函数:		cv::Vec3f u3f(v3f);
		值构造函数:			cv::Vec2f v2f(x0,x1);
		成员访问:			v4f[i]; v3w(j);		//[] 和()都是可以的
		向量叉乘:			v3f, cross(u3f);

3.7、Range类:cv::Range()

cv::Range类:用于确定一个连续的整数序列。

函数说明:cv::Range(int start,int end)
输入参数:
		start		起始点
		end			终止点
		
备注:左闭右开,与Python的range()类似。
举例:cv::Range rng(0, 4)		包含[0,1,2,3],但是不包含4

4、随机数:cv::RNG

(1)cv::RNG rng(int seed);使用随机数种子seed产生一个64位的随机整数,默认-1

  • 计算机产生的随机数都是伪随机数,是根据种子点seed和特定算法计算出来的。
  • 只要种子数一定,算法一定,则每次产生的随机数也是一定的。
  • 用系统时间做种子点

(2)cv::RNG rng((unsigned)time(NULL)); 用系统时间作为种子点,需添加头文件#include <time.h>

4.1、生成一个随机数:cv::RNG::uniform() + cv::RNG::gaussian()

基于随机数的3种生成方法:

(1)cv::RNG rng(int seed) 			使用随机数种子seed产生一个64位随机整数,默认-1。

(2)cv::RNG::uniform(a, b):		返回一个[a,b)范围的均匀分布的随机数。a, b的数据类型要一致,而且必须是intfloatdouble中的一种,默认是int。
(3)cv::RNG::gaussian(σ):			返回一个均值为0,标准差为σ的随机数。若要产生均值为λ,标准差为σ的随机数:λ+RNG::gaussian(σ)
#include<opencv2\opencv.hpp>
#include <string>
//using namespace cv;
//using namespace std;

int main(int argc,char* argv[])
{
	cv::RNG rng(-1);
	int randomNumber1 = rng;
	double randomNumber2 = rng.uniform(0,99);  		
	double randomNumber3 = rng.gaussian(2);			
	
	std::cout << "randomNumber1=" << randomNumber1 << std::endl;		//randomNumber=130063606
	std::cout << "randomNumber2=" << randomNumber2 << std::endl;		//randomNumber=14
	std::cout << "randomNumber3=" << randomNumber3 << std::endl;		//randomNumber=-1.40186
	return 0;
}

4.2、获取下一个随机数:next + operator

1)	cv::RNG:: next 			返回下一个64位随机整数。
(2)	cv::RNG:: operator 		返回下一个指定类型的随机数。
#include<opencv2\opencv.hpp>
#include <string>
//using namespace cv;
//using namespace std;

int main(int argc,char* argv[])
{
	cv::RNG rng(-1);  
	int randomNumber = rng.next();		//返回下一个随机整数,即N1.next();  
	 
	//返回下一个指定类型的随机数  
	int randomNumber1 = rng.operator uchar();         //返回下一个无符号字符数  
	int randomNumber2 = rng.operator schar();         //返回下一个有符号字符数  
	int randomNumber3 = rng.operator ushort();        //返回下一个无符号短型  
	int randomNumber4 = rng.operator short int();     //返回下一个短整型数  
	int randomNumber5 = rng.operator int();           //返回下一个整型数  
	int randomNumber6 = rng.operator unsigned int();  //返回下一个无符号整型数  
	int randomNumber7 = rng.operator float();         //返回下一个浮点数  
	int randomNumber8 = rng.operator double();        //返回下一个double型数  
	int randomNumber9 = rng.operator ()();            //和rng.next( )等价  
	int randomNumber10 = rng.operator ()(100);        //返回[0,100)范围内的随机数  
	
	std::cout << "randomNumber=" << randomNumber << std::endl;		//randomNumber=130063605
	std::cout << "randomNumber1=" << randomNumber1 << std::endl;		//randomNumber=156
	std::cout << "randomNumber2=" << randomNumber2 << std::endl;		//randomNumber=-116
	std::cout << "randomNumber3=" << randomNumber3 << std::endl;		//randomNumber=24389
	std::cout << "randomNumber4=" << randomNumber4 << std::endl;		//randomNumber=31943
	std::cout << "randomNumber5=" << randomNumber5 << std::endl;		//randomNumber=-1348951784
	std::cout << "randomNumber6=" << randomNumber6 << std::endl;		//randomNumber=94037301
	std::cout << "randomNumber7=" << randomNumber7 << std::endl;		//randomNumber=0
	std::cout << "randomNumber8=" << randomNumber8 << std::endl;		//randomNumber=0
	std::cout << "randomNumber9=" << randomNumber9 << std::endl;		//randomNumber=776868985
	std::cout << "randomNumber10=" << randomNumber10 << std::endl;		//randomNumber=94
	return 0;
}

4.3、用随机数填充矩阵:cv::RNG::fill()

函数说明:void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false );
输入参数:
			(1)mat 			输入矩阵。2D或N维矩阵,最多支持4通道,超过4通道先用reshape()改变结构。
			(2)distType 		分布类型。
						cv::RNG::UNIFORM		均匀分布。
						cv::RNG::NORMAL			高斯分布。
			(3)a 				第一分布参数。均匀分布时表示一个下边界(闭区间),正态分布时表示平均值。
			(4)b 				第二分布参数。均匀分布时表示一个上边界(开区间),正态分布时表示标准差。
			(5)saturateRange=false 	只针对均匀分布有效。当为真的时候,会先把产生随机数的范围变换到数据类型的范围,再产生随机数。如果为假,会先产生随机数,再进行截断到数据类型的有效区间。
#include<opencv2\opencv.hpp>
#include <string>
//using namespace cv;
//using namespace std;

int main(int argc,char* argv[])
{
	cv::RNG rng(-1);
	
	cv::Mat_<int>fillM1(3, 3);			//新建3x3矩阵,int类型
	cv::Mat_<double>fillM2(3, 3);		//新建3x3矩阵,double类型

	rng.fill(fillM1, cv::RNG::UNIFORM, 1, 100);		//随机生成[1,100)均匀分布的int数,并填充fillM。
	rng.fill(fillM2, cv::RNG::NORMAL, 1, 3);		//随机生成均值为1,标准差为3的double数,并填fillN。
	
	std::cout << "filM = " << fillM1 << std::endl;  
	std::cout << "filN = " << fillM2 << std::endl;  
	
	return 0;
}

5、计算消费时间函数

5.1、耗时:cv::getTickCount()

函数说明:int64 cv::getTickCount();
函数作用:读取函数调用前后的时间刻度,来计算执行该函数所损耗的时间。

5.2、频率:cv::getTickFrequency()

函数说明:double cv::getTickFrequency();
函数作用:将损耗时间除以该函数(频率)以进行单位转换,返回时间的刻度数单位:秒。

5.3、实战案例

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

int main(int argc, const char* argv[]) 
{
	double count1 = cv::getTickCount();
	
	//处理
	//处理
	//处理
	
	double count2 = cv::getTickCount();
	double time_consume = (count2 - count1) / cv::getTickFrequency();
	std::cout << "耗时:" << time_consume << std::endl;
}

6、鼠标与轨迹条操作

【OpenCV】OpenCV基础教程(11)—— HighGUI图形用户界面

6.1、鼠标事件的回调函数:cv::MouseCallback

采用回调函数来处理鼠标事件

  • 创建一个回调函数
  • 输入参数:触发事件、触发位置
  • 备注:函数还需要被告知用户是否在触发鼠标事件的同时触发了Shift或者Alt等键。
#include <opencv2/highgui.hpp>
函数说明:typedef void(* cv::MouseCallback) (int event, int x, int y, int flags, void *userdata)
输入参数:
				11、event:鼠标事件
								事件名称						数值		说明
								CV_EVENT_MOUSEMOVE			0			指示鼠标指针已在窗口上移动。
								CV_EVENT_LBUTTONDOWN		1			表示按下了鼠标左键。
								CV_EVENT_RBUTTONDOWN		2			表示按下了鼠标右键。
								CV_EVENT_MBUTTONDOWN		3			表示按下了鼠标中键。
								CV_EVENT_LBUTTONUP			4			表示释放了鼠标左键。
								CV_EVENT_RBUTTONUP			5			表示释放了鼠标右键。
								CV_EVENT_MBUTTONUP			6			表示释放了鼠标中键。
								CV_EVENT_LBUTTONDBLCLK		7			表示双击鼠标左键。
								CV_EVENT_RBUTTONDBLCLK		8			表示双击鼠标右键。
								CV_EVENT_MBUTTONDBLCLK		9			表示双击鼠标中键。
				22、(x, y):触发鼠标事件的坐标位置
				33、flags:鼠标状态
								标志名称						数值		说明
								CV_EVENT_FLAG_LBUTTON		1			表示鼠标左键已按下。
								CV_EVENT_FLAG_RBUTTON		2			表示鼠标右键已按下。
								CV_EVENT_FLAG_MBUTTON		4			表示鼠标中键已按下。
								CV_EVENT_FLAG_CTRLKEY		8			表示按下了Ctrl键(8~15)。
								CV_EVENT_FLAG_SHIFTKEY		16			表示按下了Shift键(16~31)。
								CV_EVENT_FLAG_ALTKEY		32			表示按下了Alt键(32~39)44、param:(可选参数)可以以任何结构方式传递额外的参数信息。

6.2、设置鼠标事件的回调函数:cv::setMouseCallback()

#include <opencv2/highgui.hpp>
函数说明:void cv::setMouseCallback(const String &winname, MouseCallback onMouse, void *userdata = (void *)0)
输入参数:
				winname			窗口的名称。
				onMouse			鼠标事件的回调函数。
				userdata		传递给回调的可选参数(默认0)。

6.3、创建轨迹条,并将其附加到指定的窗口:cv::createTrackbar()

  • 创建一个具有指定名称和范围的轨迹条(滑块或范围控件),分配一个变量值作为与轨迹条同步的位置,并指定在轨迹条位置更改时调用的回调函数onChange。
  • 创建的轨迹条将显示在指定的窗口winname中。
#include <opencv2/highgui.hpp>
函数说明:int cv::createTrackbar( const String &trackbarname, const String &winname, int *value, int count, TrackbarCallback onChange = 0, void *userdata = 0 )	
输入参数:
				trackbarname		创建轨迹条的名称。
				winname				作为轨迹条的父窗口的名称。
				value				指向整数变量的可选指针,该变量的值反映滑块的位置。创建时,滑块位置由该变量定义。
				count				滑块的最大位置。最小位置始终为0。
				onChange			指向每当滑块改变位置时要调用的函数的指针(默认0)。这个函数应该被原型化为void Foo(intvoid*),其中第一个参数是轨迹条位置,第二个参数是用户数据(见下一个参数)。如果回调是NULL指针,则不会调用回调,但只更新值。
				userdata			按原样传递给回调的用户数据(默认0)。它可以在不使用全局变量的情况下用于处理轨迹条事件。

6.4、获取指定轨迹条的当前位置:cv::getTrackbarPos()

#include <opencv2/highgui.hpp>
函数说明:int cv::getTrackbarPos(const String &trackbarname, const String &winname)
输入参数:
				trackbarname		轨迹条的名称。
				winname				作为轨迹条的父窗口的名称。
				
备注:如果轨迹条连接到控制面板,winname可以为空。

6.5、设置指定轨迹条在指定窗口中的位置:cv::setTrackbarPos()

#include <opencv2/highgui.hpp>
函数说明:void cv::setTrackbarPos( const String &trackbarname, const String &winname, int pos )	
输入参数:
				trackbarname		轨迹条的名称。
				winname				作为轨迹条的父窗口的名称。
				pos					新的位置。
				
备注:如果轨迹条连接到控制面板,winname可以为空。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖墩会武术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值