opencv学习笔记四:Opencv初探

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_43667130/article/details/102767137

opencv的基本框架

作为一开始接触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 <iostream>
#include  <opencv2/highgui/highgui.hpp>

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 <iostream>
#include  <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

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 <iostream>
#include  <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
//按下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 <iostream>
#include <opencv2/opencv.hpp>

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;
}

这儿有两种访问像素点的方法,两种方法是等价的,运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43667130/article/details/102767137