1.计算机视觉是什么
一个模拟人眼识别的结果
让计算机去认知,也就是人工智能
2.计算机视觉的用处
智能汽车、体感游戏、监控追踪、人脸识别、AR/VR、三维重建、测距等等
3.对图像的认识
图像是一种随时间推移的波形图,傅里叶公式将图像从时域中转换到频域中,如下图所示:
4,配置opencv
大致步骤如下:
(1)首先在官网下载opencv,VS2015版本需要适配3.1.0,VS2015之前的版本适配3.0.0即可
(2)下载安装之后,配置环境变量:选择此电脑,右键属性->高级系统设置->环境变量->系统变量->Path->在变量值中添加相应路径,比如我配置的VS2015的路径为D:\Opencv3.1.0\opencv\build\x64\vc14\bin
注意:根据VS的版本和编译器位数选择路径,VS2015只能配置64位;如果VS2013选择VC12文件夹
(3)打开VS,新建一个Visual C++新建Win32控制台项目,注意选择空项目,新建源文件,打开属性管理器,找到Debug|x64(或Wn32)文件夹,找到Microsoft.Cpp.x64.user(或Microsoft.Cpp.win32.user)文件,右键属性,选择通用属性下的VC++目录,在包含目录下添加三条路径D:\Opencv3.1.0\opencv\build\include D:\Opencv3.1.0\opencv\build\include\opencv D:\Opencv3.1.0\opencv\build\include\opencv2,然后在库目录下添加一条路径:D:\Opencv3.1.0\opencv\build\x64\vc14\lib
(4)再点击链接器,选择输入,在附加依赖项处添加文件:opencv_world310d.lib
(5)最后保存属性表,即可永久配置
PS:以上为DEBUG模式下的配置,如果要配置Release模式,步骤均相同,只要第(4)步添加文件时,把d去掉即可
首先输入头文件
#include
using namespace std;
#include
using namespace cv;
包括C++编译所需要的和使用opencv所需要的
1.读取摄像机和视频
代码如下:
VideoCapture cap(0);
while (true)
{
Mat frame;//Mat即矩阵Matrix的缩写,opencv最基本的数据结构,初始化一个框架
cap >> frame;//读取了一帧图像保存在frame
namedWindow("123",0 );//新建一个窗口
imshow("123", frame);//显示窗口
waitKey(30);//在imshow之后如果没有waitKey语句则不会正常显示图像,30即延迟30ms,具体数字根据帧率来定
}
2.读取图片与其中的像素值
代码如下:
Mat imggray=imread("123.jpg",1);//初始化并读取一个图片,注意图片存储文件位置
//参数0表示灰度图 参数1表示三通道彩图
//CV_8UC1单通道灰度图 CV_8UC3三通道彩图
cvtColor(imggray, imggray, CV_RGB2GRAY);//彩图转换为灰度图
imshow("123", imggray);
waitKey(0);
cout <<(int)imggray.at<uchar>(1, 1)<//第二行第二列元素转化成整型输出,读取像素值
3.创建图像和一些常用方法(Mat对象的一些操作)
代码如下:
Mat image = Mat::eye(5, 5, CV_64FC1);//zeros全初始化为0 ones全为1 eye单位矩阵
cout << image<< endl;
Mat imgone = Mat::ones(5, 5, CV_64FC1);//矩阵加减法 行数列数和类型必须完全一样
Mat sum = image + imgone;//也可换成- *等其他运算符
cout << sum << endl;
image.copyTo();//copyTo拷贝 t转置 inv逆矩阵
4.对一个图像在x方向上的求导的非卷积操作
以对一个5×5的图像在x方向上的求导为例,由求导公式D(x)=f(x+1,y)-f(x-1,y)可知,图像边界处的元素无法求导,则应对5×3的元素求导。
代码如下:
VideoCapture cap(0);
while (true)
{
Mat frame;
cap >> frame;
cvtColor(frame, frame, CV_RGB2GRAY);//转换为灰度图
cout << "row" << frame.rows << "col" << frame.cols << endl;
Mat dimg = Mat(frame.rows, frame.cols - 2, CV_8UC1);//定义一个5×3的灰度图
for (int i = 0; i < frame.rows; i++)//5行不变
{
for (int j = 1; j < frame.cols - 1; j++)
//边界的元素无法求导,所以是3列,从第2列的元素开始
{
dimg.at<uchar>(i, j - 1) = frame.at<uchar>(i, j - 1) - frame.at<uchar>(i, j + 1);
//对5行5列求导,5行3列,从第一行第二列的元素开始
}
}
imshow("123", dimg);
waitKey(10);
}
5.图像卷积(求导的卷积操作)(滤镜)
卷积就是加权求和,卷积模板就是权值。
可根据图片理解,如下图:
以用一个1×3的卷积模板对图像卷积为例
代码如下:
VideoCapture cap(0);
while (true)
{
Mat frame;
cap >> frame;
cvtColor(frame, frame, CV_RGB2GRAY);
cout << "row" << frame.rows << "col" << frame.cols << endl;
Mat dimg = Mat(frame.rows, frame.cols - 2, CV_8UC1);
Mat model = Mat(1, 3, CV_64FC1);
//定义一个1*3的卷积模板
model.at<double>(0, 0) = 1;
model.at<double>(0, 1) = 0;
model.at<double>(0, 2) = -1;
//先用两重循环得到求导后结果
for (int i = 0; i < frame.rows; i++)
{
for (int j = 1; j < frame.cols - 1; j++)
{
//再进行两重循环,用卷积模板对求导结果进行卷积
int half = model.cols / 2;
double sum = 0;
for (int m = 0; m < model.rows; m++)
{
for (int n = -half; n < model.cols - half; n++)
{
sum += frame.at<uchar>(i + m, j + n)*model.at<double>(m, n + half);
}
}
dimg.at<uchar>(i, j - 1) = (uchar)sum;
}
}
imshow("123", dimg);
waitKey(10);
}
6.高斯模糊的核创建与卷积操作
正态分布的密度函数公式如下:
代码如下:
Mat gauss(5, 5, CV_64FC1);//创建高斯图
double sigma = 50;//定义并初始化模糊度
for (int i = -2; i < 3; i++)
{
for (int j = -2; j < 3; j++)
{
gauss.at<double>(i + 2, j + 2)=exp(-(i*i + j*j) / (2 * sigma*sigma));//直接用exp()套用公式
}
}
double gssum=sum(gauss).val[0];
for (int i = -2; i < 3; i++)
{
for (int j = -2; j < 3; j++)
{
gauss.at<double>(i + 2, j + 2) /= gssum; //归一化操作
}
}
cout << gauss << endl;//opencv可直接输出图像
//进行卷积操作
VideoCapture cap(0);
while (true)
{
Mat frame;
cap >> frame;
cvtColor(frame, frame, CV_RGB2GRAY);
Mat dimg = Mat(frame.rows - 4, frame.cols - 4, CV_8UC1);
for (int i = 2; i < frame.rows - 2; i++)
{
for (int j = 2; j < frame.cols - 2; j++)
{
//与上面不同的是,没有定义half,本质相同,分别加权求和进行卷积
double sum = 0;
for (int m = 0; m < gauss.rows; m++)
{
for (int n = 0; n < gauss.cols; n++)
{
sum += (double)(frame.at(i + m - 2, j + n - 2))*gauss.at<double>(m, n);//原图强制类型转换为double
}
}
dimg.at(i - 2, j - 2) = (uchar)sum;
}
}
//显示原图与模糊后的图进行对比
imshow("a", frame);
imshow("gauss", dimg);
waitKey(10);
}
7.调用API进行高斯模糊、边缘检测
代码如下:
VideoCapture cap(0);
while (true)
{
Mat frame;
cap >> frame;
cvtColor(frame, frame, CV_RGB2GRAY);
//调用时需要的参数会在VS中显示
GaussianBlur(frame,frame,cvSize(5,5),10,10);
//利用GaussianBlur()输入参数直接进行高斯模糊
Canny(frame, frame, 100, 100);
//利用Canny算子进行边缘检测
Sobel(frame, frame, 0, 1, 1);
//利用Sobel算子进行边缘检测,可与Canny算子对比,更加明显
imshow("a", frame);
waitKey(10);
}