一、opencv安装
1.opencv下载
官网下载:http://sourceforge.net/projects/opencvlibrary/
2.安装
如果在ubantu内下载的opencv
打开ubantu命令行,输入下列命令
(解压)
unzip opencv-3.4.1.zip
进入解压后的文件中
cd opencv-3.4.12
安装cmake
sudo apt-get install cmake
安装依赖库
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
安装完上列东东后创建编译文件夹
mkdir build
并进入该文件夹
cd build
camke
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
执行命令,时间稍长
sudo make
安装,时间也稍长
sudo make install
配置环境
sudo vi /etc/ld.so.conf.d/opencv.conf
打开该文件后,直接在末尾加
/usr/local/lib
保存文件并退出
执行下列命令让刚才的操作生效
sudo ldconfig
配置bash
sudo vi /etc/bash.bashrc
在末尾添加
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
保存退出,执行下列命令让配置生效
source /etc/bash.bashrc
二、opencv使用
1.图片使用
在安装包文件夹下新建文件夹test
(注意:要将图片放在测试程序所在文件夹下)
mkdir test
建立test.cpp
vi test.cpp
在test.cpp中添加下列代码
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("lena.jpg");
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->height / 2);
for (int i = 0;i<image->height;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx*dx + dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test",1); imshow("test", src);
cvWaitKey();
return 0;
}
保存退出并编译
g++ test.cpp -o test `pkg-config --cflags --libs opencv`
上面的命令中g++命令就不多说了,后面的作用解释下,这里使用了一个工具’pkg-config’,主要功能为:
检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。
获得编译预处理参数,如宏定义,头文件的位置。
获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。
自动加入所依赖的其它库的设置,详细解释:https://blog.csdn.net/catherine627/article/details/53375620
运行
./test
至此完成
2.视频使用
新建文件test1.cpp
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture(0);//从摄像头读取视频
//循环显示每一帧
while(1)
{
Mat frame;//定义一个Mat变量,用于存储每一帧的图像
capture >> frame;//读取当前帧
imshow("read video frame",frame);//显示当前帧
waitKey(30);//延时30ms
}
system("pause");
return 0;
}
如果要读取视频文件,那么要将读取视频文件那行改为(注意要加后缀名)
VideoCapture capture("视频文件名")
接下来就是编译
g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv`
运行
./test1
Mat:Mat本质上是由两个数据部分组成的类: (包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等) 的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。矩阵头部的大小是恒定的。然而,矩阵本身的大小因图像的不同而不同,通常是较大的数量级。因此,当你在您的程序中传递图像并在有些时候创建图像副本您需要花费很大的代价生成图像矩阵本身,而不是图像的头部。OpenCV 是图像处理库,它包含大量的图像处理函数。若要解决的计算挑战,最终大部分时间你会使用库中的多个函数。由于这一原因图像传给库中的函数是一种常见的做法。我们不应忘记我们正在谈论往往是计算量相当大的图像处理算法。我们想要做的最后一件事是通过制作不必要的可能很大的图像的拷贝进一步降低您的程序的速度。
为了解决这一问题 OpenCV 使用引用计数系统。其思想是Mat的每个对象具有其自己的头,但可能他们通过让他们矩阵指针指向同一地址的两个实例之间共享该矩阵。此外,拷贝运算符将只能复制矩阵头部,也还将复制指向矩阵的指针,但不复制矩阵本身。
引用自:OpenCV中Mat的详解
waitKey(int delay):延时函数,显示视频时这个函数是有用的,用于设置在显示完一帧图像后程序等待"delay"ms再显示下一帧视频;如果使用cvWaitKey(0)则只会显示第一帧视频。
如果程序想响应某个按键,可利用if(cvWaitKey(1)==Keyvalue);
test1运行后会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序(甚至只有关闭命令行窗口才能关闭程序),非常不友好。
下面是改进代码
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
void main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return;
}
//获得cap的分辨率
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
}