【学习OpenCV 3】学习记录-第2章:OpenCV初探


本文仅作学习记录,不作他用!


头文件

#include "opencv2/core/core.hpp"
//新式C++风格的结构以及数学运算
#include "openCv2/flann/mini刊ann.hpp"
//最邻近搜索匹配函数
#include "openCV2/imgproc/imgproc.hpp"
//新式C++风格图像处理函数
#include "openCV2/video/photo.hpp"
//操作和恢复照片相关算法
#include "openCv2/video/video.hpp"
//视觉追踪以及背景分割
#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"
  • 使用头文件opencv.hpp来包含所有可能在OpenCV 函数中用到的头文件,会使得编译速度较慢,根据需求选择需要的函数的头文件将降低编译时间。
  • 头文件在…lmodules/…/include文件夹
  • 函数对应的源文件也存在于对应的src文件夹中 …lmodules/…/include/src

网络资源:
OpenCV库概述
OpenCV3 概述

第一个程序:显示图片

#include <opencv2/opencv.hpp> //Include ftle for every supported OpenCV function
int main(int argc, char** argv ) {
	cv::Mat img = cv::imread(argv[1], -1);
	if (img.empty()) return -1;
	cv::namedWindow("Example1", cv::WINDOW_AUTOSIZE);
	cv::imshow("Example1", img);
	cv::waitKey(0);
	cv::destroyWindow("Example1");
	return 0;
}

函数前加上c v: : ,向编译器说明你所调用的函数处于cv命名空间。若想简化使用use namespace cv
但是,若不想发生于其他库同名函数发生冲突,建议使用cv::,并一起为标准,使代码风格统一。

第二个程序:视频

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
#include "string"	
using namespace std;
using namespace cv;

int main(int argc, char** argv) {
	cv::namedWindow("Example3", cv::WINDOW_AUTOSIZE);
	cv::VideoCapture cap;
	cap.open(string(argv[1]));
	cv::Mat frame;
	for (;;) {
		cap >> frame;
		if (frame.empty()) break;
		cv::imshow("Example3", frame);
		if (cv::waitKey(33) >= 0) break;
	}
	return 0;
}
  • cap.open(string(argv[1]));改为“````cap.open(0)```即可调用摄像头

视频跳转

添加一个滑动条,使得用户可以进行视频跳转。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>
using namespace std;
int g_slider_position = 0; //存储滑动条位置
int g_run = 1; //新的跳转触发后会置零。当它为正的时候,指示在停止之前程序要播放多少张图片;当它为负的时候,表示系统处于连续视频播放模式。
int g_dontset = 0; //start out in single step mode
cv::VideoCapture g_cap;

void onTrackbarSlide(int pos, void*) {
	g_cap.set(cv::CAP_PROP_POS_FRAMES, pos);
	if (!g_dontset)
		g_run = 1;
		g_dontset = 0;
}

int main(int arc, char** argv) {
	cv::namedWindow("Example2_4", cv::WINDOW_AUTOSIZE);
	g_cap.open("C:/Users/zhoum/Pictures/视频项目/south_gate.mp4");
	int frames = (int)g_cap.get(cv::CAP_PROP_FRAME_COUNT);
	int tmpw = (int)g_cap.get(cv::CAP_PROP_FRAME_WIDTH);
	int tmph = (int)g_cap.get(cv::CAP_PROP_FRAME_HEIGHT);
	cout << "video has " << frames << " frames of dimensions(" << tmpw << ", " << tmph << ")." << endl;
	cv::createTrackbar("Position", "Example2_4", &g_slider_position, frames, 
		onTrackbarSlide);

	cv::Mat frame;
	for (;;) {
		if (g_run != 0) {
			g_cap >> frame;
			if (frame.empty()) break;
			int current_pos = (int)g_cap.get(cv::CAP_PROP_POS_FRAMES);
			g_dontset = 1;

			cv::setTrackbarPos("Position", "Example2_4", current_pos);
			cv::imshow("Example2_4", frame);

			g_run = 1;
		}
		char c = (char)cv::waitKey(10);
		// single step
		if (c == 's'){
			g_run = 1; cout << "Single step, run = " << g_run << endl;
		}
		// run mode
		if (c == 'r') {
			g_run = -1; cout << "Run mode, run = " << g_run << endl;
		}
		if (c == 27)
			break;
	}
	return 0;
}

简单的变换

加载图像并且在显示之前平滑处理图像。

#include <opencv2/opencv.hpp>
int main() {
	cv::Mat image = cv::imread("C:/Users/.../.../10.png", -1);
	// 创建窗口,显示输入\输出
	cv::namedWindow("Example2_5-in", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("Example2_5-out", cv::WINDOW_AUTOSIZE);

	// 创建窗口,显示输入图片
	cv::imshow("Example2_5-in", image);
	// 创建图片保存平滑后的图片
	cv::Mat out;
	// 开始平滑
	cv::GaussianBlur(image, out, cv::Size(5, 5), 3, 3);
	cv::GaussianBlur(out, out, cv::Size(5, 5), 3, 3);
	cv::imshow("Example2_5-out", out);
	cv::waitKey(0);
	return 0;
}

较复杂的变换

降采样、灰度图、边缘分割

#include <opencv2/opencv.hpp>
int main(int argc, char** argv) {
	cv::Mat img1, img2, img_gry, img_cny;
	img1 = cv::imread("C://Users//zhoum//Desktop//1.jpg", -1);
	cv::namedWindow("Example1", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("Example2", cv::WINDOW_AUTOSIZE);
	cv::imshow("Example1", img1);

	//下采样一半
	cv::pyrDown(img1, img2);
	cv::imshow("Example2", img2);

	//转化灰度图
	cv::cvtColor(img1, img_gry, cv::COLOR_BGR2GRAY);
	cv::namedWindow("Example gray", cv::WINDOW_AUTOSIZE);
	cv::imshow("Example gray", img_gry);

	//canny边缘分割
	cv::Canny(img_gry, img_cny, 50, 150, 3, true);
	cv::namedWindow("Example canny", cv::WINDOW_AUTOSIZE);
	cv::imshow("Example canny", img_cny);

	cv::waitKey(0);
	return 0;
}

写入AVI文件

OpenCV提供的格式是未经过压缩的,目前支持的格式如下:

CV_FOURCC('P', 'I', 'M', '1') = MPEG-1 codec
CV_FOURCC('M', 'J', 'P', 'G') = motion-jpeg codec
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec 
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec 
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec 
CV_FOURCC('U', '2', '6', '3') = H263 codec 
CV_FOURCC('I', '2', '6', '3') = H263I codec 
CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char* argv[]) {
	cv::namedWindow("Example_11", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("Log_Polar", cv::WINDOW_AUTOSIZE);
	//调用摄像头
	cv::VideoCapture capture(0);
	double fps = capture.get(cv::CAP_PROP_FPS);
	cv::Size size(
		(int)capture.get(cv::CAP_PROP_FRAME_WIDTH),
		(int)capture.get(cv::CAP_PROP_FRAME_HEIGHT)
	);
	cv::VideoWriter writer;
	writer.open("output_video.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, size);
	cv::Mat logpolar_frame, bgr_frame;
	for (;;) {
		capture >> bgr_frame;
		if (bgr_frame.empty()) break;
		cv::imshow("Example2_11", bgr_frame);
		cv::logPolar(
			bgr_frame, //输入
			logpolar_frame, //输出
			//logpolar转换的中心点
			cv::Point2f(
				bgr_frame.cols / 2,
				bgr_frame.rows / 2
			),
			40, //幅值(比例参数)
			cv::WARP_FILL_OUTLIERS  // 用0值填满外部
		);
		cv::imshow("Log_Polar", logpolar_frame);
		writer << logpolar_frame;

		char c = cv::waitKey(10);
		if (c == 27) break; //允许用户中断
	}
	capture.release();
}

练习

  • 1.安装编译OpenCv
  • 2.运行lkdemo.cpp
  • 3.读取视频降采样并存储彩色视频
  • 4.给练习3增加显示处理过图像的功能
  • 5.增加滑动条,通过滑动条来调节降采样率,显示处理后结果。存储功能跳过。

个人能力有限,代码可能存在部分问题,请批评指正

根据书本内容大致完成了练习的作业。

运行lkdemo.cpp

初始化
在这里插入图片描述
黑夜模式
在这里插入图片描述

降采样并存储

问题与解决:
Q:按照书里面存储的代码和降采样直接结合,输出的视频无法播放。
A:设置cv::VideoWriter writer;size时,原来代码是读取视频大小获得,如不修改和采样后的视频大小不符合,故需要将尺寸修改为采样后大小,这里由于是2倍降采样,直接将size减半就行。

#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char* argv[]) {
	cv::namedWindow("original_img", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("sampled_img", cv::WINDOW_AUTOSIZE);
	//调用摄像头
	cv::VideoCapture capture(0);
	double fps = capture.get(cv::CAP_PROP_FPS);
	// 降采样后视频尺寸变为原来一半,故除以2
	cv::Size size(
		(int)capture.get(cv::CAP_PROP_FRAME_WIDTH) / 2,
		(int)capture.get(cv::CAP_PROP_FRAME_HEIGHT) / 2
	);
	cv::VideoWriter writer;
	writer.open("sampled_video.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, size);
	cv::Mat original_frame, sampled_frame;
	for (;;) {
		capture >> original_frame;
		if (original_frame.empty()) break;
		cv::imshow("original_img", original_frame);
		cv::pyrDown(original_frame, sampled_frame);
		cv::imshow("sampled_img", sampled_frame);
		writer << sampled_frame;

		char c = cv::waitKey(10);
		if (c == 27) break; //允许用户中断
	}
	capture.release();
}

滑动条调节降采样率

问题与解决:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>
using namespace std;

int slider_position = 0;
int sample_multiple = 0;

void onTrackbarSlide(int pos, void*) {
	if (pos % 2 == 0) sample_multiple = pos;
}

int main(int arc, char** argv) {
	cv::VideoCapture capture(0);
	cv::namedWindow("original_video", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("sampled_video", cv::WINDOW_AUTOSIZE);
	cv::namedWindow("Slide", cv::WINDOW_AUTOSIZE);
	cv::createTrackbar("Position", "Slide", &slider_position, 8,
		onTrackbarSlide);
	cv::Mat original_frame, sampled_frame;

	for (;;) {
		capture >> original_frame;
		// pyrDown() 没只能下降一半,所以这样设置不行。
		//cv::Size sample_size(
		//	(int)((original_frame.cols + 1) / sample_multiple),
		//	(int)((original_frame.rows + 1) / sample_multiple)
		//);
		if (original_frame.empty()) break;
		cv::imshow("original_video", original_frame);
		cout << "video downsample multiple: " << sample_multiple << endl;
		sampled_frame = original_frame;
		for (int i = 1; i < sample_multiple; i++) {
			cv::pyrDown(original_frame, sampled_frame);
			original_frame = sampled_frame;
		}
		cv::imshow("sampled_video", sampled_frame);

		char c = cv::waitKey(10);
		if (c == 27) break; //允许用户中断
	}
	return 0;
}

显示效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值