作为一开始接触opencv的小伙伴们,自然要先搞清楚opencv的框架了,我们就从他的模块框架来了解一下好了。
首先,最总的,就是
incluce <opencv2/opencv.hpp>
这个头文件了,他包含了opencv所有的模块的头文件,理论上我们写opencv程序,就包含一个这个头文件就万事大吉了,但这样会极大的降低我们程序的编译速度,因此我们还是希望可以了解各个模块的头文件,写程序是仅包含用到的头文件。
include <opencv2/core/core.hpp>
core模块包含了新式C++风格的结构和数学运算
include <opencv2/imgproc/imgproc.hpp>
imgproc模块包含了C++风格的图像处理函数
include <opencv2/flann/miniflann.hpp>
此头文件包含了最近邻搜索匹配函数
include <opencv2/video/video.hpp>
video模块包含了视觉追踪以及背景分割
include <opencv2/features2d/features2d.hpp>
用于追踪的二维特征
include <opencv2/objdetect/objdetect.hpp>
级联人脸分类器,latent SVM分类器,HoG特征和平面检测器
include <opencv2/calib3d/calib3d.hpp>
校准以及双目视觉相关
include <opencv2/ml/ml.hpp>
机器学习,聚类,以及模式识别相关
include <opencv2/highgui/highgui.hpp>
新式C++风格的显示,滑动条,鼠标操作以及输入输出相关
include <opencv2/contrib/contrib.hpp>
用户贡献的代码,皮肤检测,模糊Mean-Shift追踪,spin image算法及自相似特征
我们看了上面的介绍,自然知道,显示,读取图片这些操作,自然是在highgui模块中了。下面写程序:
#include "pch.h"
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("1.jpg");
if (img.empty())
{
printf("没有找到照片!");
return -1;
}
namedWindow("example1", WINDOW_AUTOSIZE);
imshow("example1", img);
waitKey();
return 0;
}
我们来逐行分析这个程序,
第一行:
Mat img = imread(“1.jpg”);
定义了一个Mat图像类型img来接收读取的图片,用到函数
imread(const string& filename, int flags = 1);
该函数第一个参数为图片路径名,如果图片在此工程目录下,则只需要写图片名“1.jpg”,
第二个参数为表示符,默认为1,将图像转换为彩色再返回,若为0,则转换为灰度图再返回。
第二行:
if (img.empty())
{
printf("没有找到照片!");
return -1;
}
此代码段为判断读取图片是否存在。
第三行:
namedWindow("example1", WINDOW_AUTOSIZE);
运用namedWindow()函数创建一个名为example1的窗口,用来存储图像。第二个参数为标识符。
- WINDOW_NORMAL 用户可以随意改变窗口大小
- WINDOW_AUTOSIZE 窗口可根据突变大小自行调整,用户不可随意改变
- WINDOW_OPENGL 窗口创建时会支持OpenGL
第四行:
imshow("example1", img);
该代码将图片img显示于窗口example1中。
第五行:
waitKey();
代码可以防止程序运行窗口闪退,waitKey()括号内,如果为0或空,则程序会暂停等待键盘事件,如果大于0,则会等待相同时长的毫秒时间。
运行结果:
#include "pch.h"
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
namedWindow("Example2", WINDOW_AUTOSIZE);
VideoCapture cap;
cap.open("1.mp4");
Mat frame;
while(1) {
cap >> frame;
if (frame.empty()) break;
imshow("Example2", frame);
waitKey(30);
}
return 0;
}
首先,我们使用VideoCapture cap;定义了一个视频对象,使用该对象的成员函数open()来打开工程目录下的一段程序。
Mat frame;定义了一个Mat类型的图像frame来存储每一帧。
if (frame.empty()) break;用来检测读取帧是否为空,若为空,即视频播放完毕。
imshow(“Example2”, frame);用来显示该视频帧
waitKey(30); 用来延时30mm
如果我们想让视频完成跳转,则需要添加一个滑动条,程序中多处用到了cap.set()函数,该函数经常与cap.get()函数配合使用/
#include "pch.h"
#include
#include
#include
//按下S键来执行单步模式,按下R恢复视频连续播放
using namespace std;
using namespace cv;
int g_slider_position = 0; //定义视频位置变量
int g_run = 1, g_dontset = 0; //设置视频模式标志位
VideoCapture cap;
void on_TrackbarSlide(int pos, void*) //滑动条响应函数
{
cap.set(CAP_PROP_POS_FRAMES, pos); //设置帧
if (!g_dontset)
g_run = 1;
g_dontset = 0;
}
首先创建了一些全局变量和回调函数,回调函数内设置了帧的跳转和一些标志位的置换
int main()
{
namedWindow("Example3", WINDOW_AUTOSIZE);
cap.open("1.mp4");
int frames = (int)cap.get(CAP_PROP_FRAME_COUNT); //帧数
int tmpw = (int)cap.get(CAP_PROP_FRAME_WIDTH); //宽
int tmph = (int)cap.get(CAP_PROP_FRAME_HEIGHT); //高
cout << "Video has " << frames << "frames of dimensions( " << tmpw << " ," << tmph << " )." << endl;
然后是主函数,创建了一个窗口来显示视频,定义了帧数,视频宽度,高度。
createTrackbar("Position", "Example3", &g_slider_position, frames, on_TrackbarSlide);
创建了一个滑动条函数,该函数原型和用法如下:
/*
int createTrackbar(
conststring& trackbarname, #轨迹条名称
conststring& winname, #窗口名称
int* value, #指向整型的指针,表示当前滑块的位置
int count, #最大位置
TrackbarCallback onChange = 0, //回调函数,每次滑块改变位置时,这个函数就会回调
void* userdata = 0
);
*/
Mat frame;
while(1) {
if (g_run != 0) { //运行单步模式
cap >> frame;
if(frame.empty()) break;
int current_pos = (int)cap.get(CAP_PROP_POS_FRAMES); //获取的帧索引
g_dontset = 1;
setTrackbarPos("Position", "Example3", current_pos); //使进度条跟着视频运
imshow("Example3", frame);
g_run -= 1;
}
char c = (char)waitKey(10);
if (c == 's'){
g_run = 1; cout << "Single step, run = " << g_run << endl;
}
if (c == 'r'){
g_run = -1; cout << "Run mode ,run = " << g_run << endl;
}
if (c == 27)
break;
}
return 0;
}
最后是视频的显示,其中用到了一个setTrackbarPos()函数,该函数用法如下:
设置trackbar位置
void setTrackbarPos(
const char& trackbar_name, //trackbar 的名字
const char* window_name, //trackbar 父窗口的名字
int pos //新的位置
);
#include "pch.h"
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("1.jpg");
int x = 32, y = 64;
//第一种访问方式
cout << "第一种方法:" << endl;
Vec3b intensity = img.at<Vec3b>(y, x);
uchar blue = intensity[0];
uchar green = intensity[1];
uchar red = intensity[2];
cout << "At (x,y)=(" << x << "," << y << "):(blue,green,red)=(" << (unsigned int)blue << ',' << (unsigned int)green
<< ',' << (unsigned int)red << ")" << endl;
//第二种访问方式
cout << "第二种方法:" << endl;
blue = img.at<Vec3b>(y, x)[0];
green = img.at<Vec3b>(y, x)[1];
red = img.at<Vec3b>(y, x)[2];
cout << "At (x,y)=(" << x << "," << y << "):(blue,green,red)=(" << (unsigned int)blue << ',' << (unsigned int)green
<< ',' << (unsigned int)red << ")" << endl;
waitKey();
return 0;
}