OpenCV的简单使用教程与基本函数(C++版本)

article/2025/9/28 3:51:19

OpenCV的简单使用教程(C++)

    • OpenCV简介
    • OpenCV的使用基础
    • 打开、显示和保存图像
    • 图像存储变量 Mat类
    • 图像元素的存储
    • 读入图像文件
    • 创建Mat类
    • 复制Mat类
    • 图像元素的访问
    • OpenCV画图
    • 命令行交互界面

OpenCV简介

OpenCV是一个开源发行的跨平台计算机视觉和机器学习软件库,提供了图像处理和计算机视觉方面的很多通用算法。接下来,我简要介绍一些OpenCV基础且常用的函数(C++接口)。

OpenCV的使用基础

在这里,我就不讲OpenCV的配置问题了。在使用OpenCV接口时,记得在代码开头的预处理命令部分加入

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp>   

为了方便和编写可读性高、简洁的代码,墙裂建议使用命名空间

using namespace cv;// 省去函数前面加cv::的必要性

当然,也可以不使用命名空间,但是在使用时需自己写cv,例如:

cv::Mat img;

打开、显示和保存图像

打开图像:imread 显示图像:imshow 保存图像:imwrite 例如:

int main()
{char imageName[] = "/test.jpg";   Mat M=imread(imageName,IMREAD_COLOR);   // 读入图片 if(M.empty())     // 判断文件是否正常打开  {fprintf(stderr, "Can not load image %s\n", imageName);waitKey(6000);  // 等待6000 ms后窗口自动关闭   return -1;}imshow("image",M);  // 显示图片 waitKey();imwrite("pic.bmp",M); // 存为bmp格式图片return 0;
}

图像存储变量 Mat类

Mat类包括两个数据部分
(1)矩阵头:大小恒定,包括矩阵大小、存储方法、矩阵存储地址等信息
(2)矩阵指针:大小不定,指向包含了像素值的矩阵(可选择存储方法,采用任何维度存储数据)

// Mat的相关参数
int depth = M.depth();	//元素数据类型,枚举型,0为CV_8U
int channels = M.channels();  	//色彩通道数
int nRows = M.rows; 	//行数,图像高度
int nCols = M.cols;  		//列数,图像宽度
uchar * data = M.data;	//图像地址
int nDims = M.dims;		//图像维度
int nElSize = M.elemSize();	//每个像素字节数
int nElSize1 = M.elemSize1();	//每个像素单通道的字节数
int type = M.type();		//元素数据类型及通道数,枚举型

Type:枚举类型
type的命名格式为CV_(位数)+(数据类型)+(通道数)
Mat type说明

图像元素的存储

1.单通道灰度图 (像素通常为< uchar >类型)
单通道灰度图
2.RGB三通道彩色图 (像素通常为< Vec3b >类型)
rgb图
注意事项:①行号、列号都是从“0”开始;②RGB彩色图的通道顺序反过来了,在OpenCV中是BGR

读入图像文件

读入图像使用imread函数,用法如下:

Mat M;  //只构造了Mat类的矩阵头
M = imread(argv[1], IMREAD_COLOR);  // 开辟矩阵空间,并将文件的内容写入函数声明
Mat imread(const string& filename, int flags);
IMREAD_UNCHANGED  	-1
IMREAD_GRAYSCALE  	0
IMREAD_COLOR      		1
IMREAD_ANYDEPTH   	2
IMREAD_ANYCOLOR   	4
缺省值为1

创建Mat类

使用Mat函数可以创建图像矩阵,并可指定大小

// 利用成员函数 create() 创建图像矩阵
Mat M;
M.create(4,4, CV_8UC2);  //4行4列,开辟内存,但未指定像素的初值
cout << "M = "<< endl << " " << M << endl << endl;// 利用Mat类的构造函数创建图像矩阵
//2维图像—平面图像
Mat M(2,2, CV_8UC3, Scalar(0,0,255));  //2行2列,给定全体像素的值 
cout << "M = " << endl << " " << M << endl << endl;
system(" pause "); 	//用于让命令窗口停留显示//3维图像—立体图像
(构造3维矩阵时,需先定义一个数组,说明每个维度的尺寸)
int sz[3] = {3,3,3};	    //每个维度尺寸都是3
Mat M(3,sz,CV_8UC1,Scalar::all(0));  //高维无法直接用cout显示//构造指定内容的特殊矩阵
// 用类似matlab的特殊矩阵为第一个通道的矩阵赋值
Mat M = Mat::eye(4, 4, CV_64FC2);
Mat M = Mat::ones(2, 2, CV_32F);
Mat M = Mat::zeros(3,3, CV_8UC1);//指定每个像素
Mat M = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
Mat_<double> 对应	CV_64F; 	Mat_<uchar>对应	CV_8U
Mat_<char>对应	CV_8S;	Mat_<int>对应	CV_32S
Mat_<float>对应	CV_32F;	Mat_<double>对应	CV_64F//利用随机数给矩阵赋值
Mat M = Mat(3, 2, CV_8UC3);
cv::randu(M, Scalar::all(0), Scalar::all(255)); //上限255,下限0//利用外部数据指针赋值
Mat M(height, width, CV_8UC3, pixels);  
//char * pixels; 

复制Mat类

当需要复制图像或者生成一张与原图像大小的新图像时,要用使用复制Mat类

//仅复制矩阵头,不复制数据
//共享全部数据
Mat B(A); // 将A的矩阵头复制给BC = A; // 将A的矩阵头复制给C//共享部分数据
Mat D(A, Rect(0,0,2,3)); 
//D为A中以(0,0)为左上角,宽2,高3的矩形部分
Mat E = A(Range::all(),Range(0,3));
//E包括A的每一行,及其中第0列到第2列//复制矩阵头,且复制一份新数据
//克隆
Mat F = A.clone();//拷贝
Mat G;
A.copyTo(G);

图像元素的访问

因为灰度图像和彩色图像的通道数不一样,所以两者的访问方式不一样,需要注意。下面我主要讲解彩色图像元素的访问(三通道),灰度图像的访问只需要单通道和用Mat.at< uchar >(j,i)访问即可。
访问方式有三种:data指针、Mat.at(i,j)和Mat.ptr行指针

//1. 使用data指针(unsigned char*)加偏移量
unsigned char* ptr=M.data; 
int height = M.rows; //number of rows
int width = M.cols; //number of colums
for (int i=0; i<height; i++) 
{for (int j=0; j<width; j++){ptr[ (i *width +j)*3 +0]=ptr[ (i *width +j)*3 +0]/2;ptr[ (i *width +j)*3 +1]=ptr[ (i *width +j)*3 +1]/2;ptr[ (i *width +j)*3 +2]=ptr[ (i *width +j)*3 +2]/2;}
}
//2. 用Mat.at(i,j)访问坐标(i,j)的图像元素 
int height = M.rows; //number of rows
int width = M.cols; //number of colums
for (int i=0; i<height; i++){for (int j=0; j<width; j++){M.at<Vec3b>(i,j)[0] = M.at<Vec3b>(i,j)[0]*i*j/(height*width);M.at<Vec3b>(i,j)[1] = M.at<Vec3b>(i,j)[1]*i*j/(height*width);M.at<Vec3b>(i,j)[2] = M.at<Vec3b>(i,j)[2]*i*j/(height*width);}
}
int height = M.rows; //number of rowsint width = M.cols; //number of columsVec3b* p;for (int i=0; i<height; i++) {p = M.ptr<Vec3b>(i);for (int j=0; j<width; j++){p[j][0] = p[j][0]*i*j/(height*width);p[j][1] = p[j][1]*i*j/(height*width);p[j][2] = p[j][2]*i*j/(height*width);}}

OpenCV画图

使用OpenCV可以画出很多的基本图形,应有尽有,比如:画圆、画直线、插入文字等。

// 画圆 
Point center = Point(255,255);//圆心int r = 100; //半径 
circle(M,center,r,Scalar(0,0,0));
//参数为:原图像、圆心、半径、颜色、粗细、线型
imshow(“显示图像",img);  // 画椭圆弧线
Size s=Size(20,10);
ellipse(M,center,s,0,10,180,Scalar(0,0,0));
//参数为:原图像、圆心、长短轴、径向夹角(水平面到长轴的夹角)、起始角度(长轴到起始边沿的夹角)、结束角度(长轴到结束点的夹角)、倾斜的矩形(可选项)、颜色、粗细、线性、偏移  // 画线
Point a = Point(600,600);
line(M,a,center,Scalar(255,0,0));
//参数为:原图像、起始点、结束点、颜色、粗细、线型  // 画矩形   
rectangle(M,a,center,Scalar(255,0,0)); 
//参数为:原图像、顶点、对角点、颜色、粗细、大小// 插入文字  
string words= "good luck";
putText(M,words,Point(M.rows/2,M.cols/4),CV_FONT_HERSHEY_COMPLEX,1,Scalar(255,0,0));
//参数为:承载的图片,插入的文字,文字的位置(文本框左下角),字体,大小,颜色

命令行交互界面

OpenCV提供了相关函数,有助于编写交互程序

带输入参数的可执行命令
//主函数增加两个入口参数
int main(int argc,char*argv[]) 
// argv[0]为命令自身,其后依次为输入参数;argc为数组的元素个数
对于  int _tmain(int argc, _TCHAR* argv[])  //C++版本的main函数
需设值项目属性的generalcharacter setUse Multi-Byte Character Set//调用变量时
Mat img=imread(argv[1],IMREAD_ANYCOLOR); // 调试时
在Solution Explore中右键项目(或选中项目后点project菜单)
Properties --> Configuration Properties -> Debugging
在Command Arguments中,输入入口参数(如C:\news.jpg),参数间以空格隔开//命令窗口调用时
打开项目的debug目录(xxx.exe所在目录)
空白处“Shift+右键”,选择“在此处打开命令窗口”
输入项目名及参数,如 xxx C:\news.jpg执行过程中的命令行输入交互
// 加入命令行输入提示
cout<<"请选择操作 [1] xx; [2] xx\n";// 读入选择
int x;
cin>>x;// 根据选择,提示下一步输入,及执行相应操作
string imagename;
if (x == 1)
{  cout<<"请输入图片文件名“<<endl;cin>>imagename;Mat img=imread(imagename,IMREAD_COLOR);.
}

更多详细的OpenCV函数说明,请移步官方文档:

https://docs.opencv.org/3.4/d6/d00/tutorial_py_root.html


http://chatgpt.dhexx.cn/article/HRHy3juS.shtml

相关文章

OpenMV入门

1. 什么是OpenMV OpenMV 是一个开源&#xff0c;低成本&#xff0c;功能强大的 机器视觉模块。 OpenMV上的机器视觉算法包括 寻找色块、人脸检测、眼球跟踪、边缘检测、标志跟踪 等。 以STM32F427CPU为核心&#xff0c;集成了OV7725摄像头芯片&#xff0c;在小巧的硬件…

OpenMV零基础教程

一、资料导航 “工欲善其事&#xff0c;必先利其器”。在正式学习OpenMV之前&#xff0c;你必须知道一条或几条OpenMV的学习途径。这里推荐星瞳科技的中文官网教程&#xff0c;这个教程里面包括了OpenMV IDE的下载和安装、OpenMV上手教程、OpenMV中文文档、OpenMV详细参数以及O…

C++版本OpenCv教程

C版本OpenCv教程(一)Mat—基本的图像容器 目标 我们有多种方法从现实世界获取数字图像:数码相机、扫描仪、计算机断层扫描和磁共振成像等等。在以上任何情况下&#xff0c;我们(人类)看到的都是图像。然而&#xff0c;当将其转换到我们的数字设备时&#xff0c;我们所记录的是…

VS配置OpenCV教程(超详细)

目录 安装环境说明 下载OpenCV 配置OpenCV开发环境 属性表 测试 可能存在的问题 安装环境说明 操作系统&#xff1a;Windows10 OpenCV版本&#xff1a;OpenCV2和OpenCV3 VS版本&#xff1a;VS2015或者VS2017 下载OpenCV OpenCV下载地址&#xff1a;http://opencv.org…

伺服控制原理 及RT and IRT

什么是伺服系统&#xff1f; 以物体的位置、方向、速度等为控制量&#xff0c;以跟踪输入给定制的任意变化为目的&#xff0c;所构成的自动闭环控制系统。 伺服系统组成&#xff1a; 伺服系统是具有负反馈的闭环自动控制系统&#xff0c;由控制器、伺服驱动器、伺服电机和反…

ERTEC200P-2 PROFINET设备完全开发手册(3-1)

3. 读写周期数据 PROFINET的基本通讯模型如下图&#xff1a; Profinet 是基于标准以太网技术的应用层协议&#xff0c;支持4种类型的数据通道 标准通道&#xff1a;参数化及配置&#xff0c;读诊断数据&#xff0c;设备信息(I&M)&#xff0c;资产信息 (AMR) ;&#xff08…

ERTEC200P-2 PROFINET设备完全开发手册(8-2)

8.2 IRT通讯原理及API PROFINET RT通讯的特点&#xff1a; 典型的PROFINET网络如下图所示。 其中&#xff1a; T1: 采样输入 T2: IO背板周期 T3: Profinet I/O 通讯周期 T4: CPU组织块OB1执行周期 T5: Profinet I/O 通讯周期 T6: IO背板周期 T7: 建立输出 在PRO…

多维IRT模型的EM估计

多维IRT模型的EM估计 MIRT &#xff08;Multidimensional Item Response Theory&#xff09;多维项目反应理论。与一维项目反应理论的区别只是在于对于潜在变量的 θ i \theta_{i} θi​ 的建模&#xff0c;一个是unidimensional latent trait θ i \theta_{i} θi​&#xf…

R语言IRT理论:扩展Rasch模型等级量表模型lltm、 rsm 和 pcm模型分析心理和教育测验数据可视化

最近我们被客户要求撰写关于IRT理论的研究报告&#xff0c;包括一些图形和统计输出。 摘要 我们首先介绍扩展 Rasch 模型的方法论&#xff0c;然后是一般程序描述和应用主题,包括简单的 Rasch 模型、评级量表模型、部分信用模型及其线性扩展。这种线性结构的结合允许对协变量…

ERTEC200P-2 PROFINET设备完全开发手册(8-1)

8.1 IRT通讯实验 这里我们使用APP3 IsoApp&#xff0c;修改源代码usrapp_cfg.h的宏为 #define EXAMPL_DEV_CONFIG_VERSION 3 使能App3&#xff0c;对应的主程序为“usriod_main_isoapp.c” 编译后下载运行。打开4.2建立的TIA项目&#xff0c;添加等时模式组织块&#xff0c…

ERTEC200P-2 PROFINET设备完全开发手册(9-2)

9.2 运行AC1/AC4参考代码 修改源代码usrapp_cfg.h的宏为 #define EXAMPL_DEV_CONFIG_VERSION 44 编译后下载到评估板运行AC4示例程序 在TIA中导入GSDML-V2.35-Siemens-ERTEC200pApp44-20210623.xml。新建项目&#xff0c;添加PLC和Devkit设备。 按照如下图所示配置模块&am…

可解释知识追踪(整理更新)

微观角度的可解释性&#xff0c;一个深度学习模型的可解释性是其内 在的固有性质&#xff0c;指模型的决策在多大程度上可以被人类预测和理解。模型的可解释性越强&#xff0c;代表模 型的行为对人类越透明&#xff0c;模型的不确定性也就越低&#xff1b;反之模型的可解释性越…

IRT模型估计-EM算法

IRT模型中参数估计 IRT(Item Response Theory) 项目反应理论。是教育评估与心理测量理论中的重要模型。主要目的是通过被试(examinees) 的对于一套试题的反应(responses), 对被试 的能力(ability parameters) 参数 θ \theta θ 和题目(item parameters) 作出估计。由于被试的…

技术话题(2)实时通讯RT和同步实时通讯IRT的区别

目前西门子 S7-1200 PLC仅支持RT通讯&#xff0c;与 V90 PN 连接做位置控制和速度控制均是通过PROFINET通讯来实现的。 而 S7-1500 PLC 支持IRT通讯&#xff0c;与 V90 PN 做位置控制和速度控制也是由PROFINET通讯来实现的。 下面我们为大家介绍一下RT通讯的特点&#xff1a;…

IRT模型

IRT模型是用来分析考试成绩或者问卷调查数据的数学模型。这些模型的目标是来确定的潜在心理特征&#xff08;latent trait&#xff09;是否可以通过测试题被反应出来&#xff0c;以及测试题和被测试者之间的互动关系。在IRT模型的理念是一个学生回答一个问题是否正确这个结果是…

浅谈知识追踪(BKT、IRT、DKT)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、知识追踪是什么&#xff1f;二、具体内容1.基于贝叶斯的知识追踪&#xff08;BKT&#xff09;项目反应理论&#xff08;IRT&#xff09;深度知识追踪&#…

IRT

文章目录 CTT(classical test theory)历史定义parallel testCronbachs α \alpha α 项目评估P-valueitem-total correlation 缺点 IRT(Item response theory)对于CTT的改进定义三大假设IRF3PL(three parameter logistic model)IRF形态PL模型分类 逻辑正态模型 模型拟合分析项…

Deep-IRT Make Deep Learning Based Knowledge Tracing Explainable Using Item Response Theory

写在前面&#xff1a; 本文在DKVMN的基础上结合项目IRT&#xff0c;加入了student ability network 和 difficulty network两个网络&#xff0c;增加深度知识追踪的可解释性 1 摘要 基于深度学习的知识追踪模型已被证明在不需要人工设计特征的情况下优于传统的知识追踪模型&…

IRT模型学习小结

文章目录 IRT模型学习小结关于IRT模型 IRT模型原理模型介绍参数估计 应用场景 IRT模型学习小结 关于IRT模型 与IRT模型相对应的经典测量理论CCT。经典测量理论与项目反应理论在测量领域均占有重要地位。经典测量理论形成较早&#xff0c;但是经典测量理论却有一些难以克服的缺…

自适应学习系列(一)IRT简介

2019独角兽企业重金招聘Python工程师标准>>> 自适应学习之IRT简介 一、近端发展区(ZPD) Zone of Proximal Development&#xff08;ZPD&#xff09;是由心理学家Vygotsky提出来的一种学习理论&#xff0c;是目前自适应学习常用的思考模型。他认为&#xff0c;能力高…