学习OpenCV3——OpenCV初探

你需要将图片 1.jpgcup.mp4 放置在电脑的D盘

1. 显示图片

在这里插入图片描述

// Example2_2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
using namespace cv;

int main()
{
	//图像将会在生命周期结束的时候自动释放
	Mat img = imread("D:\1.jpg",-1);
	if (img.empty()) 
	{
		return -1;
	}

	int switch_on = 1;
	switch (switch_on)
	{
	case 1:
		//用户可以调整窗口大小(没有约束)/也用来切换全屏窗口到正常大小。
		namedWindow("Example2_2", WINDOW_NORMAL);
		break;
	case 2:
		//用户不能调整窗口的大小,大小受所显示图像的限制。
		namedWindow("Example2_2", WINDOW_AUTOSIZE);
		break;
	case 3:
		//窗口由opengl支持。
		namedWindow("Example2_2", WINDOW_OPENGL);
		break;
	case 4:
		//将窗口更改为全屏。
		namedWindow("Example2_2", WINDOW_FULLSCREEN);
		break;
	case 5:
		//图像尽可能扩展(没有比例限制)。
		namedWindow("Example2_2", WINDOW_FREERATIO);
		break;
	case 6:
		//图像的扩展受到比例限制。
		namedWindow("Example2_2", WINDOW_KEEPRATIO);
		break;
	case 7:
		//状态栏和工具栏
		namedWindow("Example2_2", WINDOW_GUI_EXPANDED);
		break;
	case 8:
		//老旧的方法
		namedWindow("Example2_2", WINDOW_GUI_NORMAL);
		break;
	default:
		break;
	}

	//如果窗口不存在,imshow会自动创建一个WINDOW_AUTOSIZE窗口
	imshow("Example2_2", img);
	waitKey(0);


	//虽然我们可以让窗口自行销毁,但是在更复杂的代码中,程序员应该在窗口的生命周期自然结束之前自主销毁窗口以防止内存泄漏
	destroyWindow("Example2_2");

    return 0;
}

2. 视频播放

在这里插入图片描述

// Example2_3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
using namespace cv;

int main()
{
	namedWindow("Example2_3", WINDOW_AUTOSIZE);
	VideoCapture cap; //包含视频文件所有的可以读取的属性,包括状态信息。
	cap.open("D:\cup.mp4"); //打开视频文件,cap在此处被初始化
	Mat frame; //保存视频帧,起始就是图像

	for (;;) //无线循环
	{
		cap >> frame; //视频文件会按照帧从视频流中被读取

		//检查数据是不是真的从视频中读取出来,如果没有,程序将会退出
		if (frame.empty())
			break;
		imshow("Example2_3", frame);

		//控制视频的播放速度
		if (waitKey(33) >= 0)
			break;
	}
    return 0;
}

3. 视频跳转

在这里插入图片描述

// Example2_4.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int g_slider_position = 0;		// 滑动条位置
int g_run = 1;					// 在新的跳转触发之后置0,当它为正的时候,指示在停止之前程序要播放多少帧,当它为负时,表示正处于连续播放模式
int g_dontest = 0;				// don't set 避免在调整进度条位置的时候触单步模式
VideoCapture g_cap;

// 回调函数
void onTrackbarSlide(int pos, void *) 
{
	g_cap.set(CAP_PROP_POS_FRAMES, pos);

	if (!g_dontest)
		g_run = 1;
	g_dontest = 0;
}

int main()
{
	namedWindow("Example2_4", WINDOW_AUTOSIZE);
	g_cap.open("D:\cup.mp4");
	int frames = (int)g_cap.get(CAP_PROP_FRAME_COUNT);
	int tmpw = (int)g_cap.get(CAP_PROP_FRAME_WIDTH);
	int tmph = (int)g_cap.get(CAP_PROP_FRAME_HEIGHT);
	cout << "视频帧数:" << frames << endl;
	cout << "帧图像宽度:" << tmpw << endl;
	cout << "帧图像高度:" << tmph << endl;

	createTrackbar("position", "Example2_4", &g_slider_position, frames, onTrackbarSlide);

	 

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

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

			g_run -= 1;
		}

		// 用户的键盘输入
		char c = (char)waitKey(10);
		if (c == 's')
		{
			g_run = 10;
			cout << "Single step,run = " << g_run << endl;
		}
		if (c == 'r')
		{
			g_run = -1;
			cout << "Run mode,run = " << g_run << endl;
		}
		if (c == 27) //ESC键
			break;
	}

	destroyWindow("Example2_4");
    return 0;
}

4. 高斯模糊

在这里插入图片描述

// Example2_5.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
using namespace cv;

// 加载图像并在显示之前平滑处理图像
int main()
{
	namedWindow("in", WINDOW_AUTOSIZE);
	namedWindow("out", WINDOW_AUTOSIZE);

	Mat img = imread("D:\1.jpg",-1);
	imshow("in", img);

	Mat outImg;
	//  GaussianBlur(),blur(),medianBlur(),bilateraFilter()双边滤波器
	GaussianBlur(img, outImg, Size(5, 5), 3, 3);	//卷积核的大小必须是奇数,填入偶数时会报错
	GaussianBlur(outImg, outImg, Size(5, 5), 3, 3); //由于被分配了临时的存储空间,所有outImg可以同时作为输入和输出
	imshow("out", outImg);
	waitKey(0);

	destroyAllWindows(); //销毁所有窗口
    return 0;
}

5. 降采样(图像金字塔)

在这里插入图片描述

// Example2_6.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
using namespace cv;

// 使用高斯模糊来对一张图像实现单边缩小2倍的降采样。
// 如果我们对图像进行多次降采样,就要建立一个尺度空间,也称图像金字塔,
// 这一方法是计算机视觉用于处理传感器和目标尺度变化的常用手段。
// 对信号(图像)降采样等效于和一系列脉冲函数进行卷积。这样的采样会把高频分量引入输出信号(图像)。
// 为了避免这样的事情发生,我们希望首先通过一个高通滤波器来限制信号带宽,使其能够在采样频率之内。
// 高斯模糊以及降采样通过 pyrDown()函数来实现。 pyramid——金字塔

int main()
{
	namedWindow("1", WINDOW_AUTOSIZE);
	namedWindow("2", WINDOW_AUTOSIZE);

	Mat img1 = imread("D:\1.jpg", -1);
	Mat img2;
	pyrDown(img1, img2);//高斯模糊以及降采样
	imshow("1", img1);
	imshow("2", img2);

	waitKey(0);
	return 0;
}

6. 边缘检测

在这里插入图片描述

// Example2_7.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
using namespace cv;


// Canny边缘检测器
// cvtColor()生成一个和原图一样大小但只有一个通道的图像(灰度图)

int main()
{
	Mat img_rgb, img_gray, img_cny;

	namedWindow("gray", WINDOW_AUTOSIZE);
	namedWindow("canny", WINDOW_AUTOSIZE);

	img_rgb = imread("D:\1.jpg", -1);
	cvtColor(img_rgb, img_gray, COLOR_BGR2GRAY); //彩色图像转灰度图像
	imshow("gray", img_gray);

	Canny(img_gray, img_cny, 10, 100, 3, true); //边缘检测
	imshow("canny", img_cny);

	waitKey(0);

    return 0;
}

7. 像素读写

在这里插入图片描述

// Example2_8-9.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


// 收缩两次图像
// 寻找边缘
// 读写像素值

int main()
{
	Mat img_rgb, img_gray, img_cny;

	namedWindow("gray", WINDOW_AUTOSIZE);
	namedWindow("canny", WINDOW_AUTOSIZE);

	img_rgb = imread("D:\1.jpg", -1);
	cvtColor(img_rgb, img_gray, COLOR_BGR2GRAY); //彩色图像转灰度图像
	imshow("gray", img_gray);

	Mat img_pyr, img_canny;
	pyrDown(img_gray, img_pyr); //降采样
	pyrDown(img_pyr, img_pyr);  //降采样
	Canny(img_pyr, img_cny, 10, 100, 3, true); //边缘检测

	imshow("canny", img_cny);


	//==========读写像素值==========
	// 输出(x,y)点的B ,G ,R值
	Vec3b intensity = img_rgb.at<Vec3b>(16, 32);
	uchar blue = intensity[0];
	uchar green = intensity[1];
	uchar red = intensity[2];
	
	cout << "(blue,green,red)=(" <<
		(unsigned int)blue << "," << (unsigned int)green << "," << (unsigned int)red << ")" << endl;

	cout << "Pyramid pixel there is:" << (unsigned int)img_pyr.at<uchar>(16, 32) << endl;

	// 写像素值
	for (size_t i = 0; i < 100; i++)
	{
		for (size_t j = 0; j < 50; j++)
		{
			img_cny.at<uchar>(i, j) = 128;
		}		
	}
	
	namedWindow("3", WINDOW_AUTOSIZE);
	imshow("3", img_cny);

	waitKey(0);
	return 0;
}

8. 从摄像头中读取

  • 敲了一遍书上的代码,确实有图像进来,但没显示出来,不知道原因。相机开发还是老老实实用SDK吧。

在这里插入图片描述

// Example2_10.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	namedWindow("Camera", WINDOW_NORMAL);

	VideoCapture cap;	
	cap.open(0); //打开第一个摄像头

	if (!cap.isOpened())
	{
		cerr << "Couldn't Open Camera" << endl;
	}

	Mat frame;
	for (;;)
	{
		cap >> frame;
		if (frame.empty())
			break;
		imshow("Camera", frame);//此处有图像,但是没有显示出来
	}

    return 0;
}

9. 写视频文件(对数极坐标图像)

在这里插入图片描述

// Example2_11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

/*==================================================================================
	该程序会打开一个视频文件,读取它的内容后将其转换为对数极坐标(log-polar)形式,
类似于人眼真正捕捉到的图像的形式,然后将对数极坐标图像写入一个新的视频文件。
===================================================================================*/

int main()
{
	namedWindow("Src", WINDOW_NORMAL);
	namedWindow("LogPolar", WINDOW_NORMAL);
	
	VideoCapture cap("D:\cup.mp4");
	
	double fps = cap.get(CAP_PROP_FPS);
	Size size((int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT));

	VideoWriter writer;
	writer.open("D:\cup2.mp4", CAP_OPENCV_MJPEG, fps, size);

	Mat logpolar_frame, bgr_frame;
	for (;;)
	{
		cap >> bgr_frame;
		if (bgr_frame.empty())
			break;
		imshow("Src", bgr_frame);

		logPolar(bgr_frame, logpolar_frame, Point2f(bgr_frame.cols / 2, bgr_frame.rows / 2), 40, WARP_FILL_OUTLIERS);
		imshow("LogPolar", logpolar_frame);
		writer << logpolar_frame;

		char c = waitKey(10);
		if (c == 27) //ESC
			break;
	}
	cap.release();
    return 0;
}

10. 资源下载

代码、图片和视频下载地址:
https://mp.csdn.net/mp_download/manage/download/UpDetailed

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>