- imshow,imread函数
imshow("xxxx",img);
/*
参数1:显示图片的窗口名称。
参数2:储存图片数据的对象。
*/
Mat img = imread("0001.jpg",1);
/*
上面的Mat我们可以理解为一个存储数据的容器,定义了一个img对象来存图片的数据。
参数1:引号里面的为图片路径,而且程序要左斜杠。
参数2:如果写为1最后输出就显示原图,如果写为0,最后输出就显示灰度图。
*/
- 窗口创建,删除
原型:void nameWindow(const string& winname,int flags = WINDOW_AUTOSIZE) ;
参数1:新建的窗口的名称。自己随便取。
参数2:窗口的标识,一般默认为WINDOW_AUTOSIZE 。
WINDOW_AUTOSIZE 窗口大小自动适应图片大小,并且不可手动更改。(上面图1就是使用的它)
WINDOW_NORMAL 用户可以改变这个窗口大小(上面图2就是使用的它)
WINDOW_OPENGL 窗口创建的时候会支持OpenGL(OpenGL图形界面应用程序)
destroyWindow("EXAMPLE");
参数为窗口名称;
- waitkey函数
waitKey(0)
系统暂停等待键盘事件;
0或负数则无限等待直到有键按下;
正数就是相应时间;
- 关于Mat的函数
Mat就是一个数据的容器,里面有一些相关的操作:
————————————————————————————————————————————————————————————————————
***Mat类型初始化大赏***
Mat A;
Mat m(int cols,int rows,int type);
Mat m(Size(int cols,int rows),int type);
Mat m(int cols,int rows,int type,const Scarlar&S);//最后一个举例:Scarlar(0,0,0)
Mat m =zeros(int rows,int cols,int type)//创建一个全是0的rows*cols
Mat m =eye(int rows,int cols,int type)//创建一个单位矩阵
Mat m =ones(int rows,int cols,int type)//创建一个全是1的矩阵
(...)
————————————————————————————————————————————————————————————————————
***Mat类型的一种初始化,用拷贝形式***
Mat d;
Mat c = Mat ( d.data() , d.type());
这是一个固定模板,目的是实现创造一个c,使得与d的大小,存储的数据类型均相同
————————————————————————————————————————————————————————————————————
***Mat类型的拷贝***
Mat a;
Mat b = a.clone;
实现b对a的深拷贝第一种方法
Mat a2;
Mat b2;
b2.copyto(a2);
实现b对a的深拷贝第二种方法
注意,copyto也可以运用到复制行列上,比如:
Mat A;
Mat D;
A.col(1).copyto(D);
ps1:当然,这个是基于D的空间,如果空间A比D大,则会扩展D的空间
而如果D本来就是一行一列的,则会覆盖D中的数据
ps2:两者均是对Mat容器的深拷贝,而普通的浅拷贝直接是b2 = a2,这种,只是拷贝Mat类型的指针,不复制数据只创建矩阵头,数据共享。下面讲述两种浅拷贝方法:
Mat a2;
Mat b2;
Mat c2(a2) //1
b2 = a2; //2
————————————————————————————————————————————————————————————————————————————————————————
***行指针***
const uchar* ptr=Mat.ptr<uchar>(i);
索引i表示第i行的像素值
指针类型为uchar*
——————————————————————————————————————————————————————————————————————————————————
***像素处理范围函数***
sturate_cast(number)函数 :目的是判断像素处理范围
大致就是number>300的话,返回255
number<-1,返回0
——————————————————————————————————————————————————————————————————————————————————
***像素点读取值***
Mat A;
int b=A.at<Vec3b>(row,col)[0];//BLUE
int g=A.at<Vec3b>(row,col)[1];//GREEN
int r=A.at<Vec3b>(row,col)[2];//RED
opencv是bgr的
灰度图读取:
int v=A.at<uchar>(col,rol);
——————————————————————————————————————————————————————————————————————————————————
OpenCV学习笔记(一)环境配置、图像基本操作、Mat对象_爱吃肉的大高个的博客-CSDN博客
- 关于视频帧的函数:
VideoCapture cap; //创建存储视频文件或者设备的对象
cap.open("xxx"); //打开视频文件或者视频设备
cap.open(0);//打开电脑摄像头,如果是其他外接摄像头,那就是1,2之类的
ps:视频读取后异常处理的固定格式:
/*if (!cap.isOpened())
{
cout << "could not open the VideoCapture !" << endl;
system("pause");
return -1;
}*/
利用流操作运算符将cap读到的视频帧传到frame里面:
cap>>frame;//等价于cap.read(frame);
- 图像算数操作和逻辑操作:
加 add(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
减:subtract(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
乘:multiply(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
除:divide(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
src1与src2要有相同的大小和通道数,当深度不一致时,输出图像要明确指定深度
参数mask都是在计算完成后最后进行计算的,
参数dtype可以自己设置深度,当dtype = -1,表示输出图像的深度与原图相同;
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main()
{
cv::Mat image_1 = cv::imread("0004.png");
cv::Mat image_2 = cv::imread("0005.png");
cv::namedWindow("image - 1", cv::WINDOW_AUTOSIZE);
cv::namedWindow("image - 2", cv::WINDOW_AUTOSIZE);
cv::imshow("image - 1", image_1);
cv::imshow("image - 2", image_2);
cv::waitKey(10);
//001加法运算(合并两张图片,注意图片格式大小要一致)
/*
特点:
输出图像像素的灰度仅取决于两幅或两幅以上的输入图像的对应像素灰度值。算术运算结果和参与运算像素的邻域内像素的灰度值无关
算术运算不会改变像素的空间位置。
*/
cv::Mat Result_1 = cv::Mat(image_1.size(), image_1.type());
add(image_1, image_2,Result_1, cv::Mat(), -1);
cv::namedWindow("**********************加法操作结果**********************",cv::WINDOW_AUTOSIZE);
imshow("**********************加法操作结果 * *********************", Result_1);
cv::waitKey(30);
cv::destroyWindow("**********************加法操作结果**********************");
//002减法运算
/*
* 减法运算:将同一景物在不同时间拍摄的图像或同一景物在不同坡段的图像相减,常称为差影法。
差值图像提供了图像间的差值信息,能用于指导动态监测,运动目标的检测与跟踪,图像背景的消除及目标识别等。
主要应用举例:
差影法(检测同一场景两幅图像之间的变化)
混合图像的分离
*/
cv::Mat Result_2 = cv::Mat(image_1.size(), image_1.type());
subtract(image_1, image_2, Result_2, cv::Mat(), -1);
cv::namedWindow("image output", cv::WINDOW_AUTOSIZE);
imshow("**********************减法操作结果**********************", Result_2);
cv::waitKey(30);
cv::destroyWindow("**********************减法操作结果**********************");
//003 乘法操作
/*
图像的乘法运算就是将两幅图像对应的灰度值或彩色分量进行相乘。
乘运算的主要作用是抑制图像的某些区域,掩膜值置为1,否则置为0。乘运算有时也被用来实现卷积或相关的运算。
主要应用:
1.图像的局部显示
2.改变图像的灰度级
*/
cv::Mat Result_3 = cv::Mat(image_1.size(), image_1.type());
subtract(image_1, image_2, Result_3, cv::Mat(), -1);
cv::namedWindow("*****************乘法操作结果*****************", cv::WINDOW_AUTOSIZE);
imshow("image output", Result_3);
cv::waitKey(2000);
cv::destroyWindow("*****************乘法操作结果*****************");
//004 除操作
cv::Mat bgImg = cv::Mat(image_1.size(), image_1.type());
cv::Mat Result_4 = cv::Mat(image_1.size(), image_1.type());
divide(image_1, bgImg,Result_4, 1.0, -1);
cv::namedWindow("*****************除法操作结果*****************", cv::WINDOW_AUTOSIZE);
imshow("*****************除法操作结果*****************", Result_4);
cv::waitKey(30);
cv::destroyWindow("*****************除法操作结果*****************");
//005 权重操作调节亮度
cv::Mat Result_5 = cv::Mat(image_1.size(), image_1.type());
cv::addWeighted(image_1, 2.5, image_2, 0.5, 0,Result_5, -1);
cv::namedWindow("*****************权重操作结果*****************", cv::WINDOW_AUTOSIZE);
imshow("*****************权重操作结果*****************", Result_5);
cv::waitKey(30);
cv::destroyWindow("*****************权重操作结果*****************");
//006 逻辑运算 之 逻辑非
cv::Mat Result_6 = cv::Mat(image_1.size(), image_1.type());
cv::bitwise_not(image_1, Result_6, cv::Mat());
cv::namedWindow("*****************逻辑非操作结果*****************", cv::WINDOW_AUTOSIZE);
imshow("*****************逻辑非操作结果*****************", Result_6);
cv::waitKey(30);
cv::destroyWindow("*****************逻辑非操作结果*****************");
}
线性加权:
addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
**原理:dst = src1 * alpha + src2 * beta + gamma;**
线性计算:
void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
**原理:dst = alpha * src1 + src2;**
位运算(逻辑操作)
//按位与
void bitwise_and(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//按位或
void bitwise_or(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//按位异或
void bitwise_xor(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//按位非
void bitwise_not(InputArray src,
OutputArray dst,
InputArray mask = noArray());
- LUT查找表:
void cv::LUT(InputArray src,
InputArray lut,
OutputArray dst
)
src:输入图像矩阵,其数据类型只能是CV_8U。
lut:256个像素灰度值的查找表,单通道或者与src通道数相同。
dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同。
LUT查找表两种构造方法:
1,直接构造大数组,循环赋值
2,利用mat分别构建三个矩阵,用向量的方法,将三个连起来(比较烦)
#include<highgui\highgui.hpp>
using namespace cv;
int main()
{
uchar lutData[256 * 3];
int j = 0;
for (int i = 0; i < 256; i++)
{
if (i <= 100)
{
lutData[i * 3] = 255;
lutData[i * 3 + 1] = 50;
lutData[i * 3 + 2] = 50;
}
if (i > 100 && i <= 200)
{
lutData[i * 3] = 100;
lutData[i * 3 + 1] = 10;
lutData[i * 3 + 2] = 200;
}
if (i > 200)
{
lutData[i * 3] = 255;
lutData[i * 3 + 1] = 200;
lutData[i * 3 + 2] = 100;
}
}
Mat lut(1, 256, CV_8UC3, lutData);
Mat a = imread("002.jpg");
Mat b;
namedWindow("anjis", WINDOW_AUTOSIZE);
namedWindow("anjis1", WINDOW_AUTOSIZE);
imshow("anjis", a);
LUT(a, lut, b);
imshow("anjis1", b);
waitKey();
}
//图像查找表 LUT
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
//构建LUT查找表第一层,利用uchar类型的数组存储,后来复制到mat类型的lutone中
uchar lutFirst[256];
for (int i = 0; i < 256; i++)
{
if (i <= 100)
lutFirst[i] = 234;
if (i > 100 && i <= 200)
lutFirst[i] = 255;
if (i > 200)
lutFirst[i] = 255;
}
Mat lutOne(1, 256, CV_8UC1, lutFirst); //Unsigned 8bits 一个通道 赋值类型
//LUT查找表第二层
uchar lutSecond[256];
for (int i = 0; i < 256; i++)
{
if (i <= 100)
lutSecond[i] = 255;
if (i > 100 && i <= 150)
lutSecond[i] = 105;
if (i > 150 && i <= 200)
lutSecond[i] = 25;
if (i > 200)
lutSecond[i] = 255;
}
Mat lutTwo(1, 256, CV_8UC1, lutSecond);
//LUT查找表第三层
uchar lutThird[256];
for (int i = 0; i < 256; i++)
{
if (i <= 100)
lutThird[i] = 100;
if (i > 100 && i <= 200)
lutThird[i] = 200;
if (i > 200)
lutThird[i] = 255;
}
Mat lutThree(1, 256, CV_8UC1, lutThird);
//拥有三通道的LUT查找表矩阵
vector<Mat> mergeMats;
mergeMats.push_back(lutOne);
mergeMats.push_back(lutTwo);
mergeMats.push_back(lutThree);
Mat LutTree;
merge(mergeMats, LutTree);
//这一步是合并所有通道,形成LUT表(三个通道)
//计算图像的查找表
Mat img = imread("0001.jpg");
cv::imshow("origin", img);
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat gray, out0, out1, out2;
cvtColor(img, gray, COLOR_BGR2GRAY); //色彩空间转换函数
/*
API详解:void cv::cvtColor(cv::InputArray src, // 输入图
cv::OutputArray dst, // 输出图
int code, // 颜色映射类型,可以查表得到,有很多
int dstCn = 0 // 输出的通道数 (0='automatic'),我们可以使用默认值,什么都不写。
*/
LUT(gray, lutOne, out0); //实现单通道LUT表对黑白图的处理
LUT(img, lutOne, out1); //实现单通道LUT表对彩图的处理
LUT(img, LutTree, out2);// 实现多通道LUT表对彩图的处理
imshow("out0", out0);
imshow("out1", out1);
imshow("out2", out2);
waitKey(0);
return 0;
}
- 关于伪彩变换:
userColor的关键字:COLORMAP_XXX
void cv::applyColorMap(InputArray src,
OutputArray dst,
InputArray userColor
)
参数
src CV_8UC1或CV_8UC3类型的灰度或彩色源图像。
dst 目标图像是彩色映射的源图像。注意:Mat::create是在dst上调用的。
userColor 适用于CV_8UC1或CV_8UC3类型和大小为256的颜色映射
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main()
{
cv::Mat photo = cv::imread("0003.jpg");
cv::Mat output = cv::Mat(photo.size(), photo.type());
cv::cvtColor(photo,output,cv::COLOR_RGB2GRAY);//把图片转化为灰度图(色彩空间转换部分会详细学)
cv::imshow("origin", output);
cv::waitKey(100);
cv::applyColorMap(photo, output, cv::COLORMAP_AUTUMN);
imshow("COLORMAP_AUTUMN", output);
cv::applyColorMap(photo, output, cv::COLORMAP_BONE);
imshow("COLORMAP_BONE", output);
cv::applyColorMap(photo, output, cv::COLORMAP_COOL);
imshow("COLORMAP_COOL", output);
cv::applyColorMap(photo, output, cv::COLORMAP_DEEPGREEN);
imshow("COLORMAP_DEEPGREEN", output);
cv::applyColorMap(photo, output, cv::COLORMAP_OCEAN);
imshow("COLORMAP_OCEAN", output);
cv::waitKey(0);
}
- 图像通道的分离,合并,混合
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main()
{
//图像的分离:
cv::Mat photo = cv::imread("0003.jpg");
cv::Mat output = cv::Mat(photo.size(), photo.type());
std::vector<cv::Mat> mv;
split(photo, mv);
imshow("Blue Channel", mv[0]);
imshow("Green Channel", mv[1]);
imshow("Red Channel", mv[2]);
//图像合并:
cv::Mat photo_alter_1, photo_alter_2, photo_alter_3;
mv[1] = 0;
mv[2] = 0;
cv::merge(mv, photo_alter_1);
imshow("altered_1", photo_alter_1);
split(photo, mv);
mv[1] = 0;
mv[0] = 0;
cv::merge(mv, photo_alter_2);
imshow("altered_2", photo_alter_2);
split(photo, mv);
mv[0] = 0;
mv[2] = 0;
cv::merge(mv, photo_alter_3);
imshow("altered_3", photo_alter_3);
cv::waitKey(0);
}
混合:
C++: void mixChannels(const Mat*src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs)
void mixChannels(
const Mat* src, //输入数组或向量矩阵,所有矩阵的大小和深度必须相同。
size_t nsrcs, //矩阵的数量
Mat* dst, //输出数组或矩阵向量,大小和
深度必须与src[0]相同
size_t ndsts,//矩阵的数量
const int* fromTo,//指定被复制通道与要复制到的位置组成的索引对(字面意思)
size_t npairs //fromTo中索引对的数目
);
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main()
{
//图像的分离:
cv::Mat photo = cv::imread("0002.jpg");
cv::Mat output = cv::Mat(photo.size(), photo.type());
std::vector<cv::Mat> mv;
split(photo, mv);
imshow("Blue Channel", mv[0]);
imshow("Green Channel", mv[1]);
imshow("Red Channel", mv[2]);
//图像合并:
cv::Mat photo_alter_1, photo_alter_2, photo_alter_3;
mv[1] = 0;
mv[2] = 0;
cv::merge(mv, photo_alter_1);
imshow("altered_1", photo_alter_1);
split(photo, mv);
mv[1] = 0;
mv[0] = 0;
cv::merge(mv, photo_alter_2);
imshow("altered_2", photo_alter_2);
split(photo, mv);
mv[0] = 0;
mv[2] = 0;
cv::merge(mv, photo_alter_3);
imshow("altered_3", photo_alter_3);
//图像混合
cv::Mat dst = cv::Mat::zeros(photo.size(), photo.type());
int ft[] = { 0,1,2,0,1,2 };
/*
0变1 2变0 1变2
0,1,2对应各个通道,略
*/
mixChannels(&photo, 1, &dst, 1, ft, 3);
cv::imshow("Mix", dst);
cv::waitKey(0);
}
- 色彩空间变换:
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
相关参数:
InputArray src – 原始图像
OutputArray dst – 转换后图像
int code – 转换编码
int dstCn = 0 – 目标图像通道数,如果取值为0,则由src和code决定
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main()
{
cv::Mat Image_1 = cv::imread("0002.jpg");
cv::Mat Output_1 = cv::Mat(Image_1.size(), Image_1.type());
cv::cvtColor(Image_1, Output_1,cv::COLOR_BGR2HSV);
//注:需要记住cv::COLOR_xxxxx格式,方便查找
imshow("output", Output_1);
cv::waitKey(0);
}