OpenCV基础(1)

1.图像读写与窗口显示

1.1.imread读取图像文件

Mat cv::imread(const string &filename,int flags = IMREAD_COLOR);

  • filename:要读取的图像文件名
  • flags:读取模式,可以从枚举cv::ImreadModes中取值,默认取值是IMREAD_COLOR,表示始终将图像转换为三通道RGB彩色图像

如果从指定文件加载图像成功就返回Mat矩阵,否则就返回空矩阵

1.2.imwrite保存图片

bool cv::imwrite(const string &filename,InputArray img,const std::vector<int> &params=std::vector<int>());

  • filename:需要写入的文件名,必须加上后缀
  • img:Mat类型数据,要保存到文件当中的源图像数据
  • params:特定格式保存的参数编码,一般不用写

1.3.新建窗口并显示

void nameWindow(const string &winname,int flags);

  • winname:新建的窗口的名称
  • flags:窗口的标识,一般默认为WINDOW_AUTOSIZE
    • WINDOW_AUTOSIZE:窗口自适应图片大小,并且不可手动更改
    • WINDOW_NORMAL:用户可以改变这个窗口的大小
    • WINDOW_OPENGL:窗口创建的时候支持OpenGL

void imshow(const string &winname,InputArray img);

  • winname:显示的窗口名,可以使用nameWindow函数创建窗口,如不创建,imshow将自动创建
  • img:窗口中需要显示的图像

根据图像的深度,imshow会自动对其进行缩放,规则如下:

  • 如果图像数据类型是8U,就直接显示
  • 如果图像数据类型是16U或32S,imshow函数就会自动将每个像素值除以256并显示,即将原图像素值的范围由[0~255*256]映射到[0~255]
  • 如果图像数据类型是32F或64F,imshow函数就会自动将每个像素值除以255并显示,即将原图像素值的范围由[0~1]映射到[0~255](注意:原图像素值必须归一化)

1.4.销毁窗口

//销毁一个指定名称的窗口

void destoryWindow(const string &winnanme);

//销毁全部窗口

void destoryAllWindows();

1.5.调整窗口大小

void resizeWindow(const string &winname,int width,int height);

  • winname:要调整尺寸的窗口名称
  • width:调整后的窗口宽度
  • height:调整后的窗口高度

2.OpenCV中的事件

2.1.鼠标事件

void setMousecallback(const string &winname,MouseCallback onMouse,void *userdata=0);

  • winname:窗口的名字
  • onMouse:鼠标事件响应的回调函数指针
  • userdata:传给回调函数的参数

鼠标事件回调函数类型MouseCallback定义如下:

typedef void(* cv::MouseCallback)(int event,int x,inty,int flags,void *userdata);

event:鼠标事件

enum{
    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 //中键双击
}

x:鼠标事件的x坐标

y:鼠标事件的y坐标

flags:鼠标事件的标志

enum{
    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    
}

userdata:可选的参数

2.2.键盘事件

int waitKey(int delay=0);

delay:延时的时间,单位是毫秒,默认是0,表示永久等待。该函数在至少创建了一个窗口并该窗口处于活动状态才有效;如果有多个窗口,则其中任何一个都可以处于活动状态。在小于等于0时表示等待时间无限长,为正整数n时,至少等待n毫秒才结束。在等待期间,按任意按键函数结束,返回按键的键值(ASCII码),等待时间结束仍未按下按键则返回-1。

2.3.滑动条事件

//创建滑动条
int cv::createTrackbar(const string &trackbarname,const string &winname,int *value,int count,TrackCallback onChange=0,void *userdata=0);

//回调函数类型TrackbarCallback的定义
typedef void(* cv::TrackbarCallback)(int pos,void *userdata);

//获取滑动块的位置
int cv::getTrackbarpos(const string &trackName,const string &winname);

//设置滑动块的位置
void cv::setTrackbarPos(const string &trackName,const string &winname,int pos);

3.矩阵操作

3.1.构造矩阵

Mat::Mat()
Mat::Mat(int rows,int cols,int type)
Mat::Mat(Size size,int type)
Mat::Mat(int rows,int cols,int type,const Scalar &s)
Mat::Mat(Size size,int type,const Scalar &s)
Mat::Mat(const Mat &m)
Mat::Mat(int rows,int cols,int type,void *data,size_t step=AUTO_STEP)
Mat::Mat(Size size,int type,void *data,size_t step=AUTO_STEP)
Mat::Mat(const Mat &m,const Range &rowRange,const Range &colRange)
Mat::Mat(const Mat &m,const Rect &roi)
Mat::Mat(int ndims,const int *sizes,int type,const Scalar &s)
void create(int rows,int cols,int type)

3.2.构造特殊矩阵

//定义全0矩阵
static MatExpr zeros(int rows,int cols,int type)
static MatExpr zeros(Size size,int type)
static MatExpr zeros(int ndims,const int *sz,int type)

//定义全1的矩阵
static MatExpr ones(int rows,int cols,int type)
static MatExpr ones(Size size,int type)
static MatExpr ones(int ndims,const int *sz,int type)

//定义对角线为1的矩阵
static MatExpr eye(int rows,int cols,int type)
static MatExpr eye(Size size,int type)

3.3.获取矩阵的属性

Mat类提供了如下公有成员变量:

  • rows:矩阵的行数

  • cols:矩阵的列数

  • dims:矩阵的维数

  • uchar *cv::Mat::data:指向Mat数据部分的首地址

    //获得矩阵通道数
    int channels();

    //判断矩阵是否为空
    bool empty();

    //获取矩阵的总个数
    size_t Mat::total();

3.4.复制矩阵

//深复制
Mat clone();
void copyTo(OutputArray m);
void copyTo(OutputArray m,InputArray mask);

//浅复制(赋值运算符和拷贝构造函数)
Mat dst=src;
Mat dst(src);

4.图像处理基础

4.1.颜色变换

void cvtColor(InputArray src,OutputArray dst,int code,int dstCn=0);

  • src:输入图像
  • dst:输出图像
  • code:转换的代码或标识
  • dstCn:目标图像的通道数,默认取值为0,如果取值为0,就由src和dst决定

4.2.画矩形

void cv::rectangle(InputOutputArray img,Point p1,Point p2,const SCalar &color,int thickness=1,int lineType=LINE_8,int shift=0);

void cv::rectangle(InputOutputArray img,Rect rec,const SCalar &color,int thickness=1,int lineType=LINE_8,int shift=0);

  • img:矩形所在的图像
  • p1:矩形的一个顶点
  • p2:矩形对角线上的另一个顶点
  • color:线条的颜色
  • thickness:线条的粗细程度,取负值(如CV_FILLED)函数绘制填充了色彩的矩形
  • lineType:线条的类型
  • shift:坐标点的小数点位数

4.3.画圆

void cv::circle(InputOutputArray img,Point center,int radius,const SCalar &color,int thickness=1,int lineType=LINE_8,int shift=0);

  • img:圆所在的图像
  • center:圆心的坐标
  • radius:圆的半径
  • color:线条的颜色
  • thickness:线条的粗细程度,取负值(如CV_FILLED)函数绘制填充了色彩的圆形
  • lineType:线条的类型
  • shift:坐标点的小数点位数

4.4.画椭圆

void cv::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);

  • img:椭圆所在的图像
  • center:椭圆圆心的坐标
  • axes:轴的长度
  • angle:偏转的角度
  • startAngle:圆弧起始角的角度
  • endAngle:圆弧终结角的角度
  • color:线条的颜色
  • thickness:线条的粗细程度
  • lineType:线条的类型
  • shift:坐标点的小数点位数

4.5.画线段

void cv::line(InputOutputArray img,Point p1,Point p2,const SCalar &color,int thickness=1,int lineType=LINE_8,int shift=0);

  • img:线段所在的图像
  • p1:线段起始点
  • p2:线段结束点
  • color:线条的颜色
  • thickness:线条的粗细程度
  • lineType:线条的类型
  • shift:坐标点的小数点位数

4.6.多边形填充

void cv::fillPoly(Mat &img,const Point **pts,const int *npts,int ncountours,const Scalar &color,int lineType=LINE_8,int shift=0,Point offset=Point());

  • img:输入图像
  • pts:多边形点集
  • color:多边形颜色
  • lineType:线条的类型
  • shift:坐标点的小数点位数
  • offset:等高线所有点的偏移

4.7.文字绘制

//绘制文字

void cv::putText(cv::Mat &img,const string &text,cv::Point origin,int fontFace,double fontScale,cv::Scalar color,int thickness=1,int lineType=8,bool bottomLeftOrigin=false);

//获取字符串的长度和宽度

Size cv::getTextSize(const string &text,cv::Point origin,int fontFace,double fontScale,int thickness,int *baseLine);

  • img:待绘制的图片
  • text:待绘制的文字
  • origin:文本框的左下角
  • fontFace:字体
  • fontScale:尺寸因子,值越大,字体越大
  • color:线条颜色
  • thickness:线条宽度
  • lineType:线条类型
  • baseLine:文字最底部的y坐标

4.8.随机数

//使用种子产生一个32位随机整数
RNG();
RNG(uint64 state);
RNG rng;     //创建RNG对象,使用默认种子-1
int N1 = rng;//产生32位整数,其实rng既是一个RNG对象,又是一个随机整数

//产生一个均匀分布的随机数(返回一个[a,b)范围的均匀分布的随机数)
int uniform(int a,int b);

//产生一个高斯分布的随机数(返回一个均值为0,标准差为sigma的高斯分布1的随机数)
double gaussian(double sigma);

//返回下一个随机数
unsigned next();

//用随机数填充矩阵
void fill(InputOutputArray mat,int distType,InputArray a,InputArray b,bool saturateRange=false);

4.9.为图像添加边框

void cv::copyMakeBorder(InputArray src,OutputArray ddst,int top,int bottom,int left,int right,int borderType,const Scalar &value=Scalar());

  • src:输入图像
  • dst:输出图像
  • top、bottom、left、right:表示源图像在4个方向上扩充多少像素
  • borderType:边界类型
    • BORDER_REPLICATE:复制法,复制最边缘的像素扩充边界
    • BORDER_REFLECT_101:对称法,以最边缘的像素为轴,对称填充
    • BORDER_CONSTANT:常量法,以一个常量像素值填充扩充的边界
    • BORDER_REFLECT:和对称法原理一致,不过连最边缘的像素也要对称过去
    • BORDER_WRAP:用另一侧的元素来填充这一侧的扩充边界

4.10.在图像当中查找轮廓

//查找轮廓
void cv::findContours(InputArray image,OutPutArrayOfArrays contours,OutPutArray hierarchy,int mode,int method,Point offset=Point());

//绘制轮廓
void cv::drawContours(InputOutputArray image,OutPutArrayOfArrays contours,int contourIdx,const Scalar &color,int thickness=1,int lineType=LINE_8,InputArray hierarchy=noArray(),int maxLevel=INT_MAX,Point offset=Point());

5.视频处理

5.1.播放视频文件

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
 
void processiamge(Mat &frame)
{
    circle(frame, Point(cvRound(frame.cols / 2), cvRound(frame.rows / 2)), 150, Scalar(0, 0, 255), 2, 8);
}
 
int main()
{
    string filename = "1.avi";//打开的视频文件
    VideoCapture capture;
    capture.open(filename);
 
    double rate = capture.get(CV_CAP_PROP_FPS);//获取视频文件的帧率
    int delay = cvRound(1000.000 / rate);
 
    if (!capture.isOpened())//判断是否打开视频文件
    {
        return -1;
    }
    else
    {
        while (true)
        {
            Mat frame;
            //capture.read(frame);
            capture >> frame;//读出每一帧的图像
            if (frame.empty()) break;
            imshow("处理前视频", frame);
            processiamge(frame);
            imshow("处理后视频", frame);
            waitKey(delay);
        }
    }
    return 0;
}

5.2.设置和获取视频属性

//获取属性 double get(int propId);

//设置属性 bool set(int propId,double value);

5.3.播放摄像头视频

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
 
void processiamge(Mat &frame)
{
    circle(frame, Point(cvRound(frame.cols / 2), cvRound(frame.rows / 2)), 150, Scalar(0, 0, 255), 2, 8);
}
 
int main()
{
    VideoCapture capture;
    capture.open(0);//0表示摄像头的索引号
 
    double rate = capture.get(CV_CAP_PROP_FPS);//获取视频文件的帧率
    int delay = cvRound(1000.000 / rate);
 
    if (!capture.isOpened())//判断是否打开视频文件
    {
        return -1;
    }
    else
    {
        while (true)
        {
            Mat frame;
            //capture.read(frame);
            capture >> frame;//读出每一帧的图像
            if (frame.empty()) break;
            imshow("处理前视频", frame);
            processiamge(frame);
            imshow("处理后视频", frame);
            waitKey(delay);
        }
    }
    return 0;
}

5.4.录制视频

#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
using namespace cv;
 
void main()
{
    VideoCapture capture(0);//如果是笔记本,0打开的是自带的摄像头,1 打开外接的相机
    double rate = 25.0;//视频的帧率
    Size videoSize(1280,960);
    VideoWriter writer("VideoTest.avi", CV_FOURCC('M', 'J', 'P', 'G'), rate, videoSize);
    Mat frame;
 
    while (capture.isOpened())
    {
        capture >> frame;
        writer << frame;
        imshow("video", frame);
        if (waitKey(20) == 27)//27是键盘摁下esc时,计算机接收到的ascii码值
        {
            break;
        }
    }
}
相关推荐
古希腊掌管学习的神1 小时前
[机器学习]XGBoost(3)——确定树的结构
人工智能·机器学习
ZHOU_WUYI1 小时前
4.metagpt中的软件公司智能体 (ProjectManager 角色)
人工智能·metagpt
靴子学长2 小时前
基于字节大模型的论文翻译(含免费源码)
人工智能·深度学习·nlp
AI_NEW_COME3 小时前
知识库管理系统可扩展性深度测评
人工智能
海棠AI实验室3 小时前
AI的进阶之路:从机器学习到深度学习的演变(一)
人工智能·深度学习·机器学习
hunteritself3 小时前
AI Weekly『12月16-22日』:OpenAI公布o3,谷歌发布首个推理模型,GitHub Copilot免费版上线!
人工智能·gpt·chatgpt·github·openai·copilot
IT古董4 小时前
【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
人工智能·机器学习·分类
centurysee4 小时前
【最佳实践】Anthropic:Agentic系统实践案例
人工智能
mahuifa4 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai
四口鲸鱼爱吃盐4 小时前
Pytorch | 从零构建GoogleNet对CIFAR10进行分类
人工智能·pytorch·分类