c++视频图像处理

server/2024/11/25 22:23:22/

打开视频或摄像头

打开指定视频

	/*VideoCapture(const String &filename, apiPreference);filename:读取的视频或者图像序列的名称apiPreference:读取数据时设置的属性*/
VideoCapture video;  //定义一个空的视频对象
video.open("H:/BaiduNetdiskDownload/01.mp4");
// 判断视频有没有成功打开if (!video.isOpened()) {cout << "视频打开失败";return -1;}

打开摄像头

VideoCapture video(1);   //打开一个摄像头

视频的相关操作

通过get获取视频数据
在这里插入图片描述
将视频流赋值给mat对象

	Mat mat;video >> mat; bool isColor = (mat.type() == CV_8UC3);  //判断视频是否为3通道彩色

输出视频的帧率

cout <<"视频的帧率"<< video.get(CAP_PROP_FPS);

VideoWriter 视频写入

filename:保存视频的地址和文件名,包含视频格式
fourcc:压缩帧的4字符编解码器代码
fps:保存视频的帧率,即视频中每秒图像的张数
framSize:视频帧的尺寸
isColor:保存视频是否为彩色视频

	VideoWriter writer;int codec = VideoWriter::fourcc('M', 'J', 'P', 'G');  //选择MJPG的编码格式double fps = 25.0;  //设置视频的帧率string filename = "file.avi";	// 视频的名和格式writer.open(filename, codec, fps, mat.size(),isColor);   //创建保存文件的视频流if (!writer.isOpened()) {   // 判断视频流是否正常打开cout << "视频打开失败";return -1;}

保存视频中的数据

while (1) {   // 检查是否执行完毕   if (!video.read(video))  // 判断能否从摄像头或者视频文件中读出一帧图像{cout<<"摄像头或者视频读取完成"<<endl;break;}writer.write(video);  //把图像写入视频流    writer<<matimshow('live', video);  //显示图像 char c = waitKey(50);if (c == 27) {   //俺esc退出break;}}

颜色空间转换

三种存取数据的区间

  • 8U–存储0-255的数据类型
  • 32F–存储0-1(将0-1区间映射为0-255,大于1的部分映射为白色,小于0的部分映射为黑色)
  • 64F–存储0-1
    convertTo

m:输出图像
rtype:转换后数据类型
alpha:缩放系数
beta:平移系数
转换公式:alpha*I(x,y)+ beta

// 将0-255的图像转为0-1mat.convertTo(mat2, CV_32F, 1/255.0, 0);

RGB转灰度图公式:Gray=R0.3+G0.59+B*0.11

图像格式转换cvtColor

src:待转换颜色模型的原始图像
dst:转换颜色模型后的目标图像。
code:颜色空间转换的标志,如由RGB空间到HSV空间。
dstCn:目标图像中的通道数,如果参数为0,则从src和代码中自动导出通道数。

	Mat HSV;// 将RGB转为HSVcvtColor(mat, HSV, COLOR_BGR2HSV);

通道管理

split多通道分离

split(
InputArray m, //可以输入mat型
OutputArrayOfArrays mv
)
m:待分离的多通道图像
mv:分离后的单通道图像,为向量vector形式

merge多通道合并

merge(
InputArrayOfArrays mv,
OutputArray dst )
mv:需要合并的图像向量vector,其中每个图像必须拥有相同的尺寸和数据类型
dst:合并后输出的图像,通道数等于所有输入图像的通道数的总和

合并两个矩阵,取同一位置中较小的值

min(
InputArray src1,
InoytArray sec2,
OutputArray dst )

合并两个矩阵,取同一位置中较大的值

max(
InputArray src1,
InoytArray sec2,
OutputArray dst )

找出矩阵中的最值

minMaxLoc(
InputArray src, //输入单通道矩阵
CV_OUT double* minVal, //指向最小值的指针,如果不需要,则使用NULL
CV_OUT double* maxVal =0, //指向最大值的指针,如果不需要,则使用NULL
CV_OUT Point* minLoc =0, //指向最小值位置的指针,如果不需要,则使用NULL
CV_OUT Point* maxLoc = 0, //指向最大值位置的指针,如果不需要,则使用NULL
InputArray mask =noArray() //掩码矩阵,用于标记寻找上述四个值的范围,参数默认值为noArray,表示寻找范围是矩阵中所有数据
)

与或非运算

bitwise_not(						//非运算InputArray src,					//输入矩阵OutputArray dst,				//输出矩阵InputArray mask = noArray()		//掩码区域
)bitwise_and(					//与运算InputArray src1,			//输入矩阵1InputArray src2,			//输入矩阵2OutputArray dst,			// 输出矩阵InputArray mask = noArray());//掩码矩阵
bitwise_or(						//或运算InputArray src1,			//输入矩阵1InputArray src2,			//输入矩阵2OutputArray dst,			// 输出矩阵InputArray mask = noArray());//掩码矩阵
)

阈值化(二值化)

在这里插入图片描述
threshold( //图像二值化
InputArray src, //待二值化图像,图像只能是CV_8U和CV_32F两种数据类型
OutputArray dst, //二值化后的图像
double thresh, //阈值
double maxval, //二值化过程中的最大值,非必须参数
int type //二值化方式
);

adaptiveThreshold(			//自适应阈值化,只支持灰度图InputArray src,			//待二值化图像OutputArray dst,		//输出图像double maxValue,		//二值化的最大值int adaptiveMethod,		//自适应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_Cint thresholdType,		//选择二值化方法int blockSize,			//自适应确定阈值的像素邻域大小double C);				//从平均值或者加权平均值中减去的常数

LUT查找表
LUT(
InputArray src, //输入图像,类型只能是8U
InputArray lut, //256个像素的查找表,如果为多通道,通道数必须和输入图像通道数相同
OutputArray dst //输出矩阵,数据类型和查找表相同
);

图像尺寸缩放、翻转、拼接

resize(InputArray src,							//输入图像OutputArray dst,						//输出图像Size dsize,								//输出图像的尺寸double fx = 0,							//水平轴的比例因子,变为原来的几倍double fy = 0,							//垂直轴的比例因子int interpolation = INTER_LINEAR		//插值方法,INTER_AREA最近邻插值,INTER_LINEAR双线性插值,INTER_CUBIC三线性插值
);flip(   图像翻转InputArray src,		//输入图像OutputArray dst,	//输出图像int flipCode		//翻转方式标志,数值大于0表示绕y轴翻转,数值等于0表示围绕x轴翻转,数值小于0表示围绕两个轴翻转
);
resize(INTER_AREA,INTER_LINEAR,INTER_CUBIC)hconcat(//横向拼接InputArray src1,		// 输入图像 InputArray src2,		//输入图像,需要两个输入图像高度相同OutputArray dst			//输出图像
)	vconcat(//纵向拼接InputArray src1,		// 输入图像 InputArray src2,		//输入图像,需要两个输入图像高度相同OutputArray dst			//输出图像
)

仿射变换和旋转

// 仿射变换:由平移,缩放,旋转,翻转和错切组合得到,也叫三点变换

在这里插入图片描述

warpAffine(      仿射变换InputArray src,								//输入图像OutputArray dst,							//输出图像InputArray M,								//2*3变换矩阵,仿射变换矩阵Size dsize,									//输出图像尺寸int flags = INTER_LINEAR,					//插值方法标志int borderMode = BORDER_CONSTANT,			//像素边界外推方法的标志const Scalar& borderValue = Scalar());		//填充边界使用的数值,默认情况下为0

像素边界外推方法
BORDER_CONSTANT = 0,用特定值填充//!< iiiiii|abcdefgh|iiiiiii
BORDER_REPLICATE = 1,两端复制填充//!< aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT = 2, 倒叙填充//!< fedcba|abcdefgh|hgfedcb
BORDER_WRAP = 3, 正序填充//!< cdefgh|abcdefgh|abcdefg
BORDER_REFLECT_101 = 4, 不包含边界值倒叙填充//!< gfedcb|abcdefgh|gfedcba
BORDER_TRANSPARENT = 5, //随机填充!< uvwxyz|abcdefgh|ijklmno
BORDER_REFLECT101 = BORDER_REFLECT_101, //!与BORDER_REFLECT_101相同
BORDER_DEFAULT = BORDER_REFLECT_101, //!与BORDER_REFLECT_101相同
BORDER_ISOLATED = 16 //!< 不关心感兴趣区域之外的部分

c++中并没有直接进行图像旋转的函数,需要求取一个旋转变换的仿射矩阵,通过仿射矩阵实现图像的旋转
getRotationMatrix2D( 图像旋转,返回一个2*3的矩阵
Point2f center, 图像旋转的中心位置
double angle, 图像旋转的角度,正值为逆时针旋转
double scale 两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放输入1
);
图像旋转的计算公式
在这里插入图片描述
三点对应方式计算仿射变换矩阵
getAffineTransform(
const Point2f src[], 原图像的三个点坐标
const Point2f dst[] 仿射变换后的三个点坐标
);

透视变换(透视投影,又叫四点变换)

在这里插入图片描述
从一个点出发把一个平面内人形状投影到另一个平面上
计算公式:
在这里插入图片描述
getPerspectiveTransform( 计算透视变换矩阵
const Point2f src[], 原图像中的三个坐标
const Point2f dst[], 目标图像中的三个像素坐标
int solveMethod = DECOMP_LU 计算透视变换矩阵的方法
);

	计算透视变换矩阵的方法DECOMP_LU = 0,			最佳主轴元素的高斯消元法 DECOMP_SVD = 1,			奇异值分解法 DECOMP_EIG = 2,			特征值分解法 DECOMP_CHOLESKY = 3,	Cholesky分解法DECOMP_QR = 4,			QR分解法DECOMP_NORMAL = 16		使用正规方程公式,可以去前面的标志一起使用warpPerspective(							透视变换函数InputArray src,							输入图像OutputArray dst,InputArray M,							3*3的透视变换矩阵Size dsize,								输出图像尺寸int flags = INTER_LINEAR,				插值方式 int borderMode = BORDER_CONSTANT,		像素边界外推方法的标志 const Scalar& borderValue = Scalar()	填充边界使用的数值,默认为0);

绘制图形

绘制直线

line(						InputOutputArray img,		//绘制的图像Point pt1,					//起点坐标Point pt2,					//终点坐标const Scalar& color,		//颜色int thickness = 1,			//宽度int lineType = LINE_8,		//边界类型int shift = 0				//中心坐标的半径数值中的小数点数
);	

边界类型:

	FILLED = -1,   填充型LINE_4 = 4, //!< 4-connected line    四连接LINE_8 = 8, //!< 8-connected line	8连接LINE_AA = 16 //!< antialiased line

绘制圆形

circle(InputOutputArray img,		Point center,		int radius,			半径长度const Scalar& color, int thickness = 1,		线的宽度,-1为绘制实心圆int lineType = LINE_8,int shift = 0
);

绘制椭圆

ellipse(InputOutputArray img, Point center,Size axes,double angle,			//椭圆旋转的角度double startAngle,		起始角度double endAngle,		终止角度const Scalar& color,int thickness = 1,int lineType = LINE_8, int shift = 0);

矩形绘制

	rectangle(InputOutputArray img,Point pt1, Point pt2,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);

绘制多边形

fillPoly(InputOutputArray img, const Point** pts,		所有顶点坐标(可以是多重数组,绘制多个多边形)const int* npts,		定点数int ncontours,			绘制的多边形的个数const Scalar& color, int lineType = LINE_8, int shift = 0,Point offset = Point());

绘制文字

putText(InputOutputArray img, const String& text, Point org,					//文字字符串左下角像素的坐标int fontFace, double fontScale, Scalar color,int thickness = 1, int lineType = LINE_8,bool bottomLeftOrigin = false
);

ROI分割和拷贝

img(Range(int start,	//区间的开始int end;	//区间的结束	),Range(int start,	//区间的开始int end;	//区间的结束	)
)Rect_(_Tp _x,						//左上角x坐标_Tp _y,						//左上角y坐标_Tp _width,					//宽_Tp _height)				//高

矩阵存储图
在这里插入图片描述
浅拷贝:只拷贝矩阵头
mat1=mat2
深拷贝:拷贝所有内容

cv::copyTo
copyTo(InputArray src,OutputArray dst, InputArray mask);Mat::copyToMat mat1;mat.copyTo(OutputArray dst,InputArray mask) const

图像金字塔

高斯图像金字塔:不断下采样
拉普拉斯金字塔:第k层的高斯图像下采样,再上采样,然后上采样和第k层的高斯图像求和得到拉普拉斯金字塔

pyrDown(		//下采样InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT			//填充方式);pyrUp(		上采样InputArray src,OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT);

创建滑动条和鼠标监控

创建滑动条

createTrackbar(const String& trackbarname, const String& winname,			//创建滑动条的窗口的名称int* value,						//反应当前滑块的位置int count,						//最大值TrackbarCallback onChange = 0,	//回调函数void* userdata = 0				//传递给回调函数的参数);

案例代码

Mat img;void callBack(int value, void*) {float a = value / 100;Mat img2 = img * a;imshow("img", img2);
}int main()
{img = imread("H:/1732413934315.png");namedWindow("img");imshow("img", img);int value = 100;createTrackbar("滑动条名称","img",&value,200,callBack,0);waitKey(0);return 0;
}

鼠标监控

setMouseCallback(		鼠标时间响应函数const String& winname, MouseCallback onMouse, void* userdata = 0)MouseCallback(int event,			鼠标响应事件标志,瞬间动作int x, int y, int flags,			鼠标相应标识,长时间的操作void* userdata		传递给回调函数的可选参数)鼠标响应时间标志enum MouseEventTypes {EVENT_MOUSEMOVE = 0, //!< 鼠标指针再窗口上移动EVENT_LBUTTONDOWN = 1, //!<按下鼠标左键EVENT_RBUTTONDOWN = 2, //!< 按下鼠标右键EVENT_MBUTTONDOWN = 3, //!< 按下鼠标中键EVENT_LBUTTONUP = 4, //!< 释放鼠标左键EVENT_RBUTTONUP = 5, //!< 释放鼠标右键EVENT_MBUTTONUP = 6, //!< 释放鼠标中键EVENT_LBUTTONDBLCLK = 7, //!< 双击鼠标左键EVENT_RBUTTONDBLCLK = 8, //!< 双击鼠标右键EVENT_MBUTTONDBLCLK = 9, //!< 双击鼠标中键EVENT_MOUSEWHEEL = 10,//!< 正值表示向前滚动,负值表示向后滚动EVENT_MOUSEHWHEEL = 11 //!< 正值表示向左滚动,负值表示向右滚动鼠标相应标识EVENT_FLAG_LBUTTON = 1, //!< 按住左键拖拽EVENT_FLAG_RBUTTON = 2, //!< 按住右键拖拽EVENT_FLAG_MBUTTON = 4, //!< 按住中键拖拽EVENT_FLAG_CTRLKEY = 8, //!< 按下ctrl键EVENT_FLAG_SHIFTKEY = 16,//!< 按下SHIFT键EVENT_FLAG_ALTKEY = 32 //!< 按下ALT键normalize(   归一化InputArray src, OutputArray dst, double alpha = 0, double beta = 1, int norm_type = NORM_MINMAX, int dtype = -1, InputArray mask = noArray()
);NORM_MINMAX: 数组的数值被线性变换到alpha和beta之间(通常是0到1)。NORM_L2 : :归一化后的值 = 像素值 / sqrt(所有像素值平方和)NORM_INF : 归一化后的值 = 像素值 / 最大绝对值像素值NORM_L1 : 归一化后的值 = 像素值 / (所有像素值绝对值的和)calcHist(     统计图像像素const Mat* images,int nimages,const int* channels, //需要统计哪些区域InputArray mask,SparseMat& hist, int dims,const int* histSize, const float** ranges,		//每个图像通道中灰度值的取值范围bool uniform = true,		//直方图是否均匀bool accumulate = false		//是否累积统计直方图,是否分别统计每个通道
);equalizeHist(          直方图均衡化InputArray src,		输入图像必须是8UC1OutputArray dst);LUTLUT(图像直方图匹配,将图像分布映射为指定分布InputArray src, InputArray lut,			变换矩阵OutputArray dst
);matchTemplate(InputArray image,				只能为8U或32F格式,两个输入图像类型必须相同InputArray templ,OutputArray result,int method,						匹配方法 InputArray mask = noArray());匹配方法
TM_SQDIFF = 0,        平方差匹配法 TM_SQDIFF_NORMED = 1,	归一化平方差匹配法 TM_CCORR = 2,			相关匹配法TM_CCORR_NORMED = 3,	归一化相关匹配法 TM_CCOEFF = 4,			系数匹配法 TM_CCOEFF_NORMED = 5	归一化相关系数匹配法

http://www.ppmy.cn/server/144908.html

相关文章

ESP8266 STA模式TCP服务器 电脑手机网络调试助手

STA模式TCP服务器和手机电脑网络调试助手多连接

【PHP】 环境以及插件的配置,自学笔记(一)

文章目录 环境的准备安装 XAMPPWindowMacOS 配置开发环境Vscode 关于 PHP 的插件推荐Vscode 配置 php 环境Apache 启动Hello php配置热更新 参考 环境的准备 下载 XAMPP , 可以从 官网下载 https://www.apachefriends.org/download.html 安装 XAMPP XAMPP 是一个跨平台的集成开…

Java、Android引用类型

Java/Android中有四种引用类型&#xff0c;分别是&#xff1a; Strong reference - 强引用 Soft Reference - 软引用 Weak Reference - 弱引用 Phantom Reference - 虚引用 不同的引用类型有着不同的特性&#xff0c;同时也对应着不同的使用场景。 Strong reference - 强引用…

【Python】selenium获取定位元素大小、电脑屏幕的像素、屏幕尺寸信息、以及网页尺寸的方法

我们在使用selenium 进行自动化测试的时候&#xff0c;有时候会使用获取网页的大小做一些计算&#xff0c;例如测试进行滑动验证码时&#xff0c;需要计算滑块在屏幕的相对大小&#xff0c;就要用到以上这些部分的内容。 1.1 获取某个的位置信息&#xff1a; button_ driver…

【Ubuntu24.04】服务部署(虚拟机)

目录 0 背景1 安装虚拟机1.1 下载虚拟机软件1.2 安装虚拟机软件1.2 安装虚拟电脑 2 配置虚拟机2.1 配置虚拟机网络及运行初始化脚本2.2 配置服务运行环境2.2.1 安装并配置JDK172.2.2 安装并配置MySQL8.42.2.3 安装并配置Redis 3 部署服务4 总结 0 背景 你的服务部署在了你的计算…

AI模型---安装cuda与cuDNN

1.安装cuda 先打开cmd 输入nvidia-smi 查看显卡支持cuda对应的版本&#xff1a; 然后去英伟达官网下载cuda&#xff08;外网多刷几次&#xff09; https://developer.nvidia.com/cuda-toolkit-archive 注意对应版本 安装过程中如果显示如下图&#xff1a; 请安装visual Stu…

鸿蒙开发Hvigor插件动态生成代码

Hvigor允许开发者实现自己的插件&#xff0c;开发者可以定义自己的构建逻辑&#xff0c;并与他人共享。Hvigor主要提供了两种方式来实现插件&#xff1a;基于hvigorfile脚本开发插件、基于typescript项目开发。下面以基于hvigorfile脚本开发插件进行介绍。 基于hvigorfile脚本…

网络安全-------防止被抓包

1.Ios应用网络安全之https 安全套接字层 (Secure Socket Layer, SSL) 是用来实现互联网安全通信的最普遍的标准。Web 应用程序使用 HTTPS&#xff08;基于 SSL 的 HTTP&#xff09;&#xff0c;HTTPS 使用数字证书来确保在服务器和客户端之间进行安全、加密的通信。在 SSL 连接…