OpenCV课程C++实例代码实现

这篇文章主要是为了保存一下之前学习的opencv代码,其次是希望能帮助到其他人。

B站网课链接贾志刚老师43讲 课程感觉有点没用免费课程干货太少,简单的介绍OpenCV常见函数的用法,并没有深入讲解源码。可能是免费课程的原因,建议看一下源码就行。目前在看C++的OpenCV课程推荐有夏曹俊老师的课程。这个应该是教育机构的推销课程相对其他OpenCV相比还是比较优秀的。

一、什么是OpenCV

       OpenCV的全称是Open Source Computer Vision Library是一个跨平台的计算机视觉处理开源软件库,是由Intel公司俄罗斯团队发起并参与和维护,支持与计算机视觉和机器学习相关的众多算法,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序,该程序库也可以使用英特尔公司的IPP进行加速处理。

二、OpenCV官方下载链接

     Opencv官网地址为官方地址,网站提供了各个版本源码、发行版的下载地址及说明文档,其中Windows的下载包是一个自解压程序,解压之后有两个文件夹,其中sources文件夹里包含源码,build中包含编译好的库文件,以供Windows下编译opencv使用。
     GitHub上的地址为Git地址,该网址下有多个opencv相关的仓库,其中opencv仓库中包含了opencv的源码。

三、Visual Studio配置OpenCV环境

之前写过一篇这方面的配置方法跳转接口

综合比较了几篇CSDN其他大佬的配置环境的文章比较推荐这一篇OpenCV配置

四、代码实现功能目录

     void colorSpace_demo(Mat& image);                     //图像色彩空间转换
     void mat_creation_demo(Mat& image);                  //图像对象的创建与赋值
     void pixel_visit_demo(Mat& image);                       //图像像素的读写操作
     void operators_demo(Mat& image);                        //图像像素的算术操作
     void tracking_bar_demo(Mat& image);                   //滚动条调节图像亮度
     void key_demo(Mat& image);                                 //滚动条参数传递
     void color_style_demo(Mat& image);                      //键盘响应操作
     void bitwise_demo(Mat& image);                            //自带颜色表操作
     void channels_demo(Mat& image);                         //图像像素逻辑操作
     void inrange_demo(Mat& image);                           //通道分离与合并
     void pixel_statistic_demo(Mat& image);                  //图像色彩空间转换
     void drawing_demo(Mat& image);                          //图像几何图形绘制
     void random_drawing_demo(Mat& image);            //随机数与随机颜色
     void polyline_drawing_demo(Mat& image);            //多边形天聪与绘制
     void mouse_drawing_demo(Mat& image);             //鼠标操作与响应
     void norm_demo(Mat& image);                              //图像像素转化
     void resize_demo(Mat& image);                            //图像放缩与插值
     void flip_demo(Mat& image);                                 //图像翻转
     void rotate_demo(Mat& image);                             //图像旋转
     void video_demo(Mat& image);                             //视频文件使用
     void videokeep_demo(Mat& image);                     //视频处理与保存
     void showHistogram_demo(Mat& image);             //图像直方图
     void histogram_2d_demo(Mat& image);                //二维直方图
     void hisogram_eq_demo(Mat& image);                 //直方图均衡化
     void blur_demo(Mat& image);                                //图像卷积操作
     void gaussian_blur_demo(Mat& image);               //高斯模糊
     void bifilter_demo(Mat& image);                            //高斯双边模糊         

五、源代码

quickopencv.h

#pragma once
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

 class QuickDemo {
 public:
	 void colorSpace_demo(Mat& image);                    //图像色彩空间转换
	 void mat_creation_demo(Mat& image);			      //图像对象的创建与赋值
	 void pixel_visit_demo(Mat& image);					  //图像像素的读写操作
	 void operators_demo(Mat& image);					  //图像像素的算术操作
	 void tracking_bar_demo(Mat& image);				  //滚动条调节图像亮度
	 void key_demo(Mat& image);							  //滚动条参数传递
	 void color_style_demo(Mat& image);					  //键盘响应操作
	 void bitwise_demo(Mat& image);						  //自带颜色表操作
	 void channels_demo(Mat& image);					  //图像像素逻辑操作
	 void inrange_demo(Mat& image);						  //通道分离与合并
	 void pixel_statistic_demo(Mat& image);				  //图像色彩空间转换
	 void drawing_demo(Mat& image);						  //图像几何图形绘制
	 void random_drawing_demo(Mat& image);				  //随机数与随机颜色
	 void polyline_drawing_demo(Mat& image);			  //多边形天聪与绘制
	 void mouse_drawing_demo(Mat& image);				  //鼠标操作与响应
	 void norm_demo(Mat& image);						  //图像像素转化
	 void resize_demo(Mat& image);						  //图像放缩与插值
	 void flip_demo(Mat& image);						  //图像翻转
	 void rotate_demo(Mat& image);						  //图像旋转
	 void video_demo(Mat& image);						  //视频文件使用
	 void videokeep_demo(Mat& image);					  //视频处理与保存
	 void showHistogram_demo(Mat& image);				  //图像直方图
	 void histogram_2d_demo(Mat& image);				  //二维直方图
	 void hisogram_eq_demo(Mat& image);					  //直方图均衡化
	 void blur_demo(Mat& image);						  //图像卷积操作
	 void gaussian_blur_demo(Mat& image);				  //高斯模糊
	 void bifilter_demo(Mat& image);                      //高斯双边模糊          

 }; 

quickdemo.cpp

#include "quickopencv.h"

void QuickDemo::colorSpace_demo(Mat& image)
{
	Mat gray, hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	//HSV 三通道  H0~180  S0~255   V0~255   V是亮度
	cvtColor(image, gray, COLOR_BGR2GRAY);
	imshow("HSV", hsv);
	imshow("hh", gray);
	imwrite("D:\\系统默认\\桌面\\OpenCV\\OpenCV_S02\\hsv.jpg",hsv);
	imwrite("D:\\系统默认\\桌面\\OpenCV\\OpenCV_S02\\gray.jpg",gray);
}

void QuickDemo::mat_creation_demo(Mat& image)
{
	Mat m1, m2;
	m1 = image.clone();
	image.copyTo(m2);

	//创建空白图像
	Mat m3 = Mat::ones(Size(8, 8), CV_8UC3); //8位无符号的单通道数据
	cout << "width: " << m3.cols << "height:  " << m3.rows << "channels  " << m3.channels() << endl;
	m3 = Scalar(0, 0,255);

	//Mat m4 = m3;
	//clone 克隆 而直接等于就会改变两个,随便用 “= ”会重构
	Mat m4 = m3.clone();
	m4 = Scalar(0, 255, 255);

	imshow("m3", m3);
	imshow("m4", m4);
}
void QuickDemo::pixel_visit_demo(Mat& image)
{
	int w = image.cols;
	int h = image.rows;
	int dims = image.channels(); //通道
	for (int row = 0; row < h; row++)
	{
		uchar* current_row = image.ptr<uchar>(row);
		for (int col = 0; col < w; col++)
		{
			if (dims == 1)  //灰度图像
			{
				int pv = image.at<uchar>(row, col);
				image.at<uchar>(row, col) = 255 - pv;

			} 
			if (dims == 3)  //彩色图像
			{
				//Vec3b 一次性获取是三个值
				Vec3b bgr = image.at<Vec3b>(row, col);
				image.at<Vec3b>(row, col)[0] = 255 - bgr[0]-34;
				image.at<Vec3b>(row, col)[1] = 255 - bgr[1]-34;
				image.at<Vec3b>(row, col)[2] = 255 - bgr[2]-34;
			}
		}
	}
	imshow("像素读写", image);
}
void QuickDemo::operators_demo(Mat& image)
{
	Mat dst = Mat::zeros(image.size(), image.type());;
	//创建图像全是0
	Mat m = Mat::zeros(image.size(), image.type());
	m=Scalar(50, 50, 50);
	//opencv中两个图像相乘与专有函数multiply
	//dst = image * m;
	//multiply(image, m, dst);
	

	//加法
	//int w = image.cols;
	//int h = image.rows;
	//int dims = image.channels(); //通道
	//for (int row = 0; row < h; row++)
	//{
	//	for (int col = 0; col < w; col++)
	//	{
	//			//Vec3b 一次性获取是三个值
	//			Vec3b p1 = image.at<Vec3b>(row, col);
	//			Vec3b p2 = m.at<Vec3b>(row, col);
	//			//saturate_cast<uchar>()类型数值限定uchar------>0~255
	//			dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0]+p2[0]);
	//			dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1]+p2[1]);
	//			dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2]+p2[2]);
	//	}
	//}
	//imshow("加法操作",dst);
	//add(image, m, dst);
	imshow("减法操作",dst);
	//subtract(image, m, dst);
	imshow("乘法操作",dst);
	//multiply(image, m, dst);
	imshow("除法操作",dst);
	//divide(image, m, dst);
}


static void on_lightness(int b, void* userdata)
{
	Mat image = *((Mat*)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
    Mat m = Mat::zeros(image.size(), image.type());
	m = Scalar(b, b, b);
	//图像融合 1:数组通常为图片,2.第一个数组的权重3.第二的数组图片
	//,4,第二过数组的权重,5一个加到权重总和的标量,6:输出数组,7:可选深度
	addWeighted(image, 1.0, m, 0.0, b, dst);
	imshow("亮度与对比度调节", dst);

}static void on_contrast(int b, void* userdata)
{
	Mat image = *((Mat*)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
    Mat m = Mat::zeros(image.size(), image.type());
	double contrast = b / 100.0;
	//图像融合
	addWeighted(image,contrast,m,0.0,0,dst);
	imshow("亮度与对比度调节", dst);
}

void QuickDemo::tracking_bar_demo(Mat& image)
{
	namedWindow("亮度与对比度调节",WINDOW_AUTOSIZE);
	int lightness = 50;
	int max_value = 100;
	//回调参数错:1:滑动栏名称,2:吸附窗口名称,3.滑动条初始值,指针,4.最大值,5.回调函数,6.void*类型指针 //向回调函数传输数据
	createTrackbar("Value Bar:","亮度与对比度调节", &lightness, max_value, on_lightness,(void*)(&image));
	createTrackbar("Contrast Bar:", "亮度与对比度调节", &max_value, 200, on_contrast, (void*)(&image));
} 

void QuickDemo::key_demo(Mat& image)
{
	Mat dst = Mat::zeros(image.size(), image.type());
	
	while (true)
	{
		
		char c = waitKey(100);
		if (c == 27)
		{
			break;
		}
		if (c == 49)
		{
			cout << "you key #1" << endl;
			cvtColor(image, dst, COLOR_BGR2GRAY);
		}
		if (c == 50)
		{
			cout << "you key #2" << endl;
			cvtColor(image, dst, COLOR_BGR2HSV);
		}
		if (c == 51)
		{
			cvtColor(image, dst, COLOR_BGR2HSV); //不加会卡死
			cout << "you key #3" << endl;
			dst = Scalar(50, 50, 50);
			add(image, dst, dst);
		}
		imshow("键盘响应", dst);
	}
}
void  QuickDemo::color_style_demo(Mat& image)
{
	int colormap[] = {
		COLORMAP_AUTUMN,
		COLORMAP_BONE,
		COLORMAP_JET,
		COLORMAP_WINTER,
		COLORMAP_RAINBOW,
		COLORMAP_OCEAN,
		COLORMAP_SUMMER,
		COLORMAP_SPRING,
		COLORMAP_COOL,
		COLORMAP_PINK,
		COLORMAP_HOT,
		COLORMAP_PARULA,
		COLORMAP_MAGMA,
		COLORMAP_INFERNO,
		COLORMAP_PLASMA,
		COLORMAP_VIRIDIS,
		COLORMAP_CIVIDIS,
		COLORMAP_TWILIGHT,
		COLORMAP_TWILIGHT_SHIFTED,
	};
	Mat dst = Mat::zeros(image.size(), image.type());
	int index = 0;
	while (true)
	{

		char c = waitKey(2000);
		if (c == 27)
		{
			break;
		}
		//滤镜函数1输入图像,2.输出图像,3.颜色类型
		applyColorMap(image, dst, colormap[index % 19]);
		index++;
		imshow("颜色style", dst);
	}
}
void QuickDemo::bitwise_demo(Mat& image)
{
	Mat m1 = Mat::zeros(Size(256,256),CV_8UC3);
	Mat m2 = Mat::zeros(Size(256,256),CV_8UC3);
	// 矩形函数1.图像,2.矩形顶点,3.对角线定点 3.线条颜色,4.线条粗细 ,5.线条类型,6.坐标小数点位数
	rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	Mat dst;
	//图像位运算函数,1,图片1,2.图片2,3.得到的图片
	//bitwise_or  bitwise_and
	bitwise_xor(m1, m2, dst);
	imshow("像素位操作",dst);
}
void QuickDemo::channels_demo(Mat& image)
{
	vector<Mat> mv;
	split(image, mv);
	imshow("蓝色风格", mv[0]);
	imshow("绿色风格", mv[1]);
	imshow("红色风格", mv[2]);

	Mat dst;
	mv[1] = 0;
	mv[2] = 0;
	//合并数据
	merge(mv, dst);
	imshow("蓝色", dst);
	int from_to[] = { 0,2,1,1,2,0 };
	//1.输入对象,2.输入对象个数,3.输出对象, 4.输出对象个数,5.拷贝构造
	mixChannels(&image,1, &dst, 1,from_to,3);
	imshow("通道混合", dst);
}
void QuickDemo::inrange_demo(Mat& image)
{
	Mat hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	Mat mask;
	//二值化HSV 1·处理图像,2·下界数组,3·上边界数组,4·输出图像
	inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 25), mask);
	imshow("mask", mask);

	Mat redback = Mat::zeros(image.size(), image.type());
	redback = Scalar(40, 40, 200);
	bitwise_not(mask, mask);
	image.copyTo(redback, mask);
}
void QuickDemo::pixel_statistic_demo(Mat& image)
{
	double minv, maxv;
	Point minLoc, maxLoc;
	vector<Mat> mv;
	split(image, mv);
	cout << endl;
	for (int i = 0; i <mv.size(); i++)
	{
	    //功能:从一个矩阵中找出全局的最大值和最小值。
	/*	参数1:InputArray类型的src,输入单通道数组(图像)。
		参数2:double* 类型的minVal,返回最小值的指针。若无须返回,此值置为NULL。
		参数3:double* 类型的maxVal,返回最大值的指针。若无须返回,此值置为NULL。
		参数4:Point* 类型的minLoc,返回最小位置的指针(二维情况下)。若无须返回,此值置为NULL。
		参数5:Point* 类型的maxLoc,返回最大位置的指针(二维情况下)。若无须返回,此值置为NULL。
		参数6:InputArray类型的mask,用于选择子阵列的可选掩膜。*/
		
	  minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());
	  cout <<"No.channels:" <<i<< "  " << "min value:" << minv << "  "<<"max value:" << maxv << endl;
	}
	Mat mean, stddev;
	    // 参数	  说明   用于:平均值和标准方差统计
		//src    	输入数组(图像)1 - 4通道都可以
		//mean	均值
		//stddev	标准差
		//mask	用于选择子阵列的可选掩码
	meanStdDev(image, mean, stddev);
	cout << "means:" <<endl<< mean << endl;
	cout <<"stddev:" <<endl<< stddev << endl;

}

void  QuickDemo::drawing_demo(Mat& image)
{
	Rect rect;
	rect.x = 170;
	rect.y = 100;
	rect.width = 100;
	rect.height = 120;
	Mat bg = Mat::zeros(image.size(), image.type());
	/*  参数	    说明
		img	        Mat类型 输入输出图像
		rec	        Rect类型 绘制好的矩形框(左上角坐标和长宽已确定)
		color	    用Scalar函数绘制颜色
		thickness	矩形框填充方式 thickness > 0为矩形框, thickness < 0为填充 默认为1
		lineType	矩形框的线条类型 默认为8
		shift	    点坐标小数数位 默认为0*/
	
	rectangle(image, rect, Scalar(0, 0, 255), -1, 8, 0);
	    //  参数	    说明
		//img	     Mat类型 输入输出图像
		//center	画圆的圆心坐标
		//radius	圆的半径
		//color	用Scalar函数绘制圆颜色
		//thickness	如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
		//lineType	线条类型 默认为8
		//shift	    圆心坐标点和半径值的小数点位数
	circle(image, Point(300, 450),20, Scalar(255, 0, 0), -1, 8, 0);

	/*    参数	说明
		img	    Mat类型 输入输出图像
		ptr1	point类型 线段起点
		ptr2	point类型 线段终点
		color	用Scalar函数绘制圆颜色
		thickness	如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
		lineType	线条类型 默认为8
		shift	坐标点的小数点位数*/
	line(bg, Point(100, 100), Point(350, 400), Scalar(0, 255, 0), 2, 8, 0);
	RotatedRect rrt;
	rrt.center = Point(200, 200);
	rrt.size = Size(100, 200);
	rrt.angle = 90.0;
	 /*   参数	说明
		img	    Mat类型 输入输出图像
		box	    RotatedRect类型 旋转好的外接矩阵内嵌椭圆(包括外接矩形的中心,变长和旋转角度)
		color	用Scalar函数绘制圆颜色
		thickness	如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
		lineType	线条类型 默认为8*/
	
	ellipse(bg, rrt, Scalar(0,255,255), 2, 8);
    
	Mat dst;
	addWeighted(image, 0.7, bg, 0.3, 0,dst);

	imshow("绘制演示",dst);
}
void  QuickDemo::random_drawing_demo(Mat& image)
{
	Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
	RNG rng(12345);
	int w = canvas.cols;
	int h = canvas.rows;
	while (true)
	{
		int c = waitKey(10);
		if (c == 27)
		{
			break;
		}
		int x1 = rng.uniform(0, w);
		int y1 = rng.uniform(0, h);
		int x2 = rng.uniform(0, w);
		int y2 = rng.uniform(0, h);
		int b = rng.uniform(0, 255);
		int g = rng.uniform(0, 255);
		int r = rng.uniform(0, 255);
		canvas = Scalar(0, 0, 0);
		line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b,g,r), 1, LINE_AA, 0);
		imshow("显示",canvas);
	}

}
void  QuickDemo::polyline_drawing_demo(Mat& image)
{
	Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
	Point p1(100, 100);
	Point p2(350, 100);
	Point p3(450, 280);
	Point p4(320, 450);
	Point p5(70, 400);

	vector<Point> pts;
	pts.push_back(p1);
	pts.push_back(p2);
	pts.push_back(p3);
	pts.push_back(p4);
	pts.push_back(p5);

	 /*
		fillPoly(img,ppt,npt,1,Scalar(255,255,255),lineType);
	    1、多边形将被画到img上

		2、多边形的顶点集为ppt

		3、绘制的多边形顶点数目为npt

		4、要绘制的多边形数量为1

		5、多边形的颜色定义为Scarlar(255, 255, 255),即RGB的值为白色*/
    fillPoly(canvas, pts, Scalar(255, 0, 0),8,0);

	/*  
	    void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, 
		bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 );		
	    参数	          说明
		img	          作为画布的矩阵
		pts	         折线顶点数组
		npts	     折线顶点个数
		ncontours	 待绘制折线数
		isClosed	 是否是闭合折线(多边形)
		color	     折线的颜色
		thickness	 折线粗细
		lineType	 线段类型
		shift	     缩放比例(0是不缩放, 4是1 / 4)
		*/
	polylines(canvas, pts, true, Scalar(0, 255, 0), 2,LINE_AA, 0);
	vector<vector<Point>> contours;
	contours.push_back(pts);
	/*
		void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx,
		const Scalar & color, int thickness = 1, int lineType = 8, InputArray hierarchy = noArray(), 
	    int maxLevel = INT_MAX, Point offset = Point())
		函数参数详解:
		第一个参数image表示目标图像,
		第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,
		第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,
		第四个参数color为轮廓的颜色,
		第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,
		第六个参数lineType为线型,
		第七个参数为轮廓结构信息,
		第八个参数为maxLevel
		*/
	drawContours(canvas, contours, -1, Scalar(0, 255, 0), 2);
	imshow("多边形绘制", canvas);
}

Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
static void on_draw(int event, int x, int y, int flags, void* userdata)
{
	Mat image = *((Mat*)userdata);
	if (event == EVENT_LBUTTONDOWN)
	{
		sp.x = x;
		sp.y = y;
		cout << "start point:" << sp << endl;

	}
	else if (event == EVENT_LBUTTONUP)
	{
		ep.x = x;
		ep.y = y;
		int dx = ep.x - sp.x;
		int dy = ep.y - sp.y;
		if (dx > 0 && dy > 0)
		{
			Rect box(sp.x, sp.y, dx, dy);
			rectangle(image,box, Scalar(0, 0, 255), 2, 8, 0);
			imshow("鼠标绘制", image);
			imshow("ROI区域", temp(box));
			//为下一次画图准备 更新操作
			sp.x = -1;
			sp.y = -1;
		}
	}
	else if(event == EVENT_MOUSEMOVE)
	{
		if(sp.x>0&&sp.y>0)
		{ 	ep.x = x;
		ep.y = y;
		int dx = ep.x - sp.x;
		int dy = ep.y - sp.y;
		if (dx > 0 && dy > 0)
		  {
			Rect box(sp.x, sp.y, dx, dy);
			temp.copyTo(image);
			rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
			imshow("鼠标绘制", image);
		  }
	    }
	
	}
}

void  QuickDemo:: QuickDemo::mouse_drawing_demo(Mat& image)
{

	namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
	namedWindow("ROI区域", WINDOW_NORMAL);
	setMouseCallback("鼠标绘制",on_draw,(void*)(&image));
	setMouseCallback("ROI区域", on_draw, (void*)(&image));
	imshow("鼠标绘制", image);

    temp = image.clone();	imshow("ROI区域", temp);
}
void  QuickDemo::norm_demo(Mat& image)
{
	Mat dst;
	cout << image.type() << endl;
	image.convertTo(dst,CV_32F);
	cout << dst.type() << endl;
	//归一化函数
	normalize(image, dst, 1.0, 0, NORM_MINMAX);
	cout << dst.type() << endl;
	imshow("图像数据归一化",dst);
}
void QuickDemo::resize_demo(Mat& image)
{
	Mat zoomin = Mat::zeros(image.size(), image.type()); 
	Mat zoomax = Mat::zeros(image.size(), image.type());
	int h = image.rows;
	int w = image.cols;

	resize(image, zoomin, Size(w / 2, h / 2), 0, 0, INTER_LINEAR);
	imshow("zoomin", zoomin);

	resize(image, zoomax, Size(w*1.5, h*1.5), 0, 0, INTER_LINEAR);
	imshow("zoomax", zoomax);
}
void QuickDemo::flip_demo(Mat& image)
{
	Mat dst;
	/*     参数 src 输入矩阵.

		参数 dst 输出矩阵,和输入矩阵一样大小。

		参数 flipCode 一个标志,决定怎么翻转矩阵; 0 是围绕着x轴翻转,
		正直是围绕着y轴翻转,负值是围绕着两个轴一起翻转。 around both axes.

		参考 transpose, repeat, completeSym
	*/
	flip(image, dst, 0);
	imshow("图像翻转",dst);
}
void QuickDemo::rotate_demo(Mat& image)
{
	Mat dst, M;
	int w = image.cols;
	int h = image.rows;
	M = getRotationMatrix2D(Point2f(w/2, h/2), 45, 1.0);
	double cos = abs(M.at<double>(0, 0));
	double sin = abs(M.at<double>(0, 1));
	double nw = cos * w + sin * h;
	double nh = sin * w + cos * h;
	M.at<double>(0, 2) +=  (nw / 2 - w / 2);
	M.at<double>(1, 2) +=  (nh / 2 - h / 2);
	warpAffine(image, dst, M, Size(nw,nh),INTER_LINEAR,0,Scalar(0,255,0));
	imshow("旋转演示", dst);
}
void QuickDemo::video_demo(Mat& image)
{
	VideoCapture capture(0);
	Mat frame;
	while (true)
	{
		capture.read(frame);
		flip(frame, frame,1);
		if (frame.empty())
		{
			break;
		}
		imshow("frame", frame);
		int c = waitKey(10);
		if (c == 27)
		{
			break;
		}
	}
}
void QuickDemo::videokeep_demo(Mat& image)
{
	
	VideoCapture capture("D:\\HONOR Magic-link\\Screenshot\\20220708_144725.mp4");
	double frame_width = capture.get(CAP_PROP_FRAME_WIDTH);
	double frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);
	double frame_count = capture.get(CAP_PROP_FRAME_COUNT);
	double frame_fps = capture.get(CAP_PROP_FPS);
	cout << " frame_fps:  " << frame_fps << endl;
	cout << "frame_width: "<<frame_width << endl;
	cout << "frame_height:"<<frame_height << endl;
	cout << "frame_count: "<<frame_count << endl;

	VideoWriter writer("D://HONOR Magic-link//Screenshot//text.mp4", capture.get(CAP_PROP_FOURCC),frame_fps,Size(frame_width,frame_height),true);
	Mat frame;
	while (true)
	{
		capture.read(frame);
		flip(frame, frame, 1);
		if (frame.empty())
		{
			break;
		}
		imshow("frame", frame);
		colorSpace_demo(frame);
		writer.write(frame);
		int c = waitKey(10);
		if (c == 27)
		{
			break;
		}
	}
	capture.release();
	writer.release();
}

void QuickDemo::showHistogram_demo(Mat& image)
{
	//三通道分离
	vector <Mat> bgr_plane;
	split(image, bgr_plane);
	//定义参数变量
	const int channels[1] = { 0 };
	const int bins[1] = { 256 };
	float hranges[2] = { 0,255 };
	const float* ranges[1] = { hranges };
	Mat b_hist;
	Mat g_hist;
	Mat r_hist;
	//计算Blue、Green、Red通道直方图
	calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);
	calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
	calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);
    //显示直方图
	int hist_w = 512;
	int hist_h = 400;
	int bin_w = cvRound((double)hist_w / bins[0]);
	Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	//归一化直方图数据-->将直方图的取值范围限制在画布高度中
	normalize(b_hist, b_hist,0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
	normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());

	//绘制直方图曲线
	for (int i = 1; i < bins[0]; i++)
	{
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);
	}

	//显示直方图
	namedWindow("Histogram Demo", WINDOW_AUTOSIZE);
	imshow("Histogram Demo", histImage);

}
void  QuickDemo::histogram_2d_demo(Mat& image)
{
	Mat hsv, hs_hist;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	int hbins = 30, sbins = 32;
	int hist_bins[] = { hbins,sbins };
	float h_range[] = { 0,180 };
	float s_range[] = { 0,256 };
	const float* hs_ranges[] = { h_range,s_range };
	int hs_channels[] = { 0,1 };
	calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);
	double maxVal = 0;
	minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
	int scale = 10;
	Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale,CV_8UC3);
	for (int h = 0; h < hbins; h++)
	{
		for (int s = 0; s < sbins; s++)
		{
			float binVal = hs_hist.at<float>(h, s);
			int intensity = cvRound( binVal* 255 / maxVal);
			rectangle(hist2d_image, Point(h * scale, s * scale),Point((h+1)*scale-1,(s+1)*scale-1),Scalar::all(intensity),-1);
		}
	}
	applyColorMap(hist2d_image, hist2d_image, COLORMAP_JET);
	imshow("H_s", hist2d_image);
}
void  QuickDemo::hisogram_eq_demo(Mat& image)
{
	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	imshow("灰度图像", gray);
	Mat dst;
	equalizeHist(gray, dst);
	imshow("直方图均衡化",dst);
}

void  QuickDemo::blur_demo(Mat& image)
{
	Mat dst;
	blur(image, dst, Size(3, 3), Point(-1, -1));
	imshow("图像模糊",dst);
}

void  QuickDemo::gaussian_blur_demo(Mat& image)
{
	Mat dst;
	GaussianBlur(image, dst, Size(5, 5), 15);
	imshow("高斯模糊",dst);
}

void  QuickDemo::bifilter_demo(Mat& image)
{
	Mat dst;
	bilateralFilter(image, dst, 0,100, 10);
	imshow("双边模糊", dst);
}

main.cpp

#include "quickopencv.h"
#include <fstream>
#include <string>
int main(int argc, char** argv)
{
    
	//Mat 矩阵 
	//imread() 读图片,参数1:图片位置(注意反斜线方向) 参数2:色域
	Mat src = imread("D:\\系统默认\\桌面\\OpenCV\\OpenCV_S02\\text.jpg");
	//判断是否找到图片位置,防止报错
	if (src.empty())
	{
		cout << "没找到图片" << endl;
		return -1;
	}	
	namedWindow("windowname",WINDOW_FREERATIO);
	imshow("windowname", src);
	QuickDemo qd;
	//qd.colorSpace_Demo(src);
	//qd.mat_creation_demo(src);
	//qd.pixel_visit_demo(src);
	//qd.operators_demo(src);
	//qd.tracking_bar_demo(src);
	//qd.key_demo(src);
	//qd.color_style_demo(src);
	//qd.bitwise_demo(src);
	//qd.channels_demo(src);
	//qd.inrange_demo(src);
	//qd.pixel_statistic_demo(src);
	//qd.drawing_demo(src);
	//qd.random_drawing(src);
	//qd.polyline_drawing_demo(src);
	//qd.mouse_drawing_demo(src);
	//qd.norm_demo(src);
	//qd.resize_demo(src);
	//qd.flip_demo(src);
	//qd.rotate_demo(src);
	//qd.video_demo(src);
	//qd.videokeep_demo(src);
	//qd.showHistogram_demo(src);
	//qd.histogram_2d_demo(src);
	//qd.hisogram_eq_demo(src);
	//qd.blur_demo(src);
	//qd.gaussian_blur_demo(src);
	//qd.bifilter_demo(src);
	
	waitKey(0);         //因为阻塞就会一直停留
    
	destroyAllWindows();
	system("cls");    
	return 0;
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开开心累兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值