OPenCv4 c++入门笔记(B站30讲课程的部分笔记)

这是一篇OpenCv4 C++版本入门的个人笔记,是B站课程30讲的部分笔记。代码中创建一个QuickDemo类,类中的每一个公有成员函数对应一个知识点。

分别有:1、将原图转为HSV和GRAY图像显示并保存;2、进行像素操作,加减乘除;3、滚动条调整亮度;4、键盘输入响应;5、改变图像颜色风格;6、像素逻辑运算;7、通道分离与合并;8、图像色彩空间转换;9、图像像素统计,最大最小值,均值方差;10、在图像中绘制几何图形;11、绘制多边形;12、鼠标响应,绘制矩形;13、像素类型转换与归一化;14、图像放缩;15、图像翻转;16、图像旋转;17、调用摄像头。

OPenCv4 c++入门笔记(B站30讲课程的部分笔记)_第1张图片

 具体程序代码:

main.cpp

// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include 
#include "quickopencv.h"

using namespace std;
using namespace cv;

Mat img;

int main(int argc,char** argv)
{
	img = imread("D:/exercise/opencv4/dog.jpeg");// 图像色彩空间转换用pig.jpg
	if (img.empty())
	{
		cout << "请确认图像名称是否正确!" << endl;
		return -1;
	}
	namedWindow("Original drawing", WINDOW_FREERATIO);
	imshow("Original drawing", img);

	QuickDemo qd;
	//qd.colorSpace_Demo(img);//将原图转为HSV和GRAY图像显示并保存
	//qd.operator_demo(img);//进行像素操作
	//qd.teacking_bar_demo(img);//滚动条调整亮度
	//qd.key_demo(img);//键盘输入响应
	//qd.color_style_demo(img);//改变图像颜色风格
	//qd.bitwise_demo(img);//图像像素逻辑操作
	//qd.channels_demo(img);//图像分离与合并
	//qd.inrange_demo(img); // 图像色彩空间转换
	//qd.pixel_static_demo(img);//图像像素统计,最大最小值,均值方差
	//qd.drawing_demo(img);//在图像中绘制几何图形
	//qd.polyline_drawing_demo();//绘制多边形
	//qd.mouse_drawing(img);使用鼠标绘制矩形
	//qd.norm_demo(img);//像素类型转换与归一化
	//qd.resize_demo(img);//图像放缩
	//qd.flip_demo(img);//图像翻转
	//qd.rotate_demo(img);//图像旋转
	  qd.video_demo(img);//使用摄像头
	waitKey(0);
}

(注意:图片路径根据具体实际进行导入),可逐个调用各个类成员函数,进行OpenCv的学习。

quickopencv.cpp

#include "quickopencv.h"
#include 

void QuickDemo::colorSpace_Demo(Mat& image)
{
	Mat gray, hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);//HSV分别表示色度、饱和度和亮度
	cvtColor(image, gray, COLOR_BGR2GRAY);
	imshow("HSV drawing", hsv);
	imshow("GRAY drawing", gray);

	imwrite("D:/exercise/opencv4/HSVdog.jpeg", hsv);
	imwrite("D:/exercise/opencv4/GRAYdog.jpeg", gray);
}

void QuickDemo::operator_demo(Mat& image)
{
	//加减乘除可以用,add()、subtract()、multiply()、divide()
	Mat dst;
	dst = image + Scalar(50, 50, 50);//这种情况下,对每个像素进行操作,像素值超过255会截断,值就为255
	imshow("加法操作",dst);//减法同理,在这不做展示了


	dst = image / Scalar(2, 2, 2);
	imshow("除法操作", dst);

	multiply(image, Scalar(2, 2, 2), dst);
	imshow("乘法操作", dst);//乘法,像素值超过255会截断,值就为255

}

//滑动条改变图像亮度--------------------------------------------------------------
int lightness;

static void callBack(int b, void* usedata)
{
	Mat img = *((Mat*)usedata);
	float a = lightness / 100.0;
	Mat img1 = img * a;

	imshow("滑动条改变亮度", img1);
}

void QuickDemo::teacking_bar_demo(Mat& image)
{
	namedWindow("滑动条改变亮度",WINDOW_AUTOSIZE);
	int max_value = 100;//亮度最大值为100
	int contrast_value = 2;
	lightness = 50;//当前亮度默认值
	//创建亮度滑动条
	createTrackbar("亮度百分比", "滑动条改变亮度", &lightness, max_value, callBack, (void*)(&image));
	//callBack(0, (void*)&image);
}
//----------------------------------------------------------------------------------

void QuickDemo::key_demo(Mat& image)
{
	Mat dst;
	while (true)
	{
		int c = waitKey(100);//Waitkey函数会有一个返回值,是返回ascii码值的
		if (c == 27)//按esc键退出
		{
			break;
		}
		//键盘按1时,转换为灰度图像并显示
		if (c == 49)
		{
			std::cout << "You enyer key #1,Convert image to grayscale" << std::endl;
			cvtColor(image, dst, COLOR_BGR2GRAY);
			imshow("按1转换为灰度",dst);
		}
	}
}

//利用ColormapTypes,进行颜色风格变化
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_HSV, COLORMAP_PINK ,COLORMAP_HOT ,
	COLORMAP_PARULA ,COLORMAP_MAGMA ,COLORMAP_INFERNO ,COLORMAP_PLASMA ,COLORMAP_VIRIDIS ,COLORMAP_CIVIDIS ,
	COLORMAP_TWILIGHT ,COLORMAP_TWILIGHT_SHIFTED ,COLORMAP_TURBO ,COLORMAP_DEEPGREEN };
	Mat dst;
	int index = 0;
	while (true)
	{
		int c = waitKey(2000);//Waitkey函数会有一个返回值,是返回ascii码值的
		if (c == 27)//按esc键退出
		{
			break;
		}
		applyColorMap(image,dst, colormap[index++ % 21]);
		imshow("颜色风格变化", 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);
	rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1,LINE_8,0);//-1小于0是填充
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);
	imshow("m1", m1);
	imshow("m2", m2);
	//进行逻辑运算
	Mat myAnd, myOr, myXor, myNot;
	bitwise_not(m1, myNot);
	bitwise_and(m1, m2, myAnd);
	bitwise_or(m1, m2, myOr);
	bitwise_xor(m1, m2, myXor);
	imshow("myAnd", myAnd);
	imshow("myOr", myOr);
	imshow("myXor", myXor);
	imshow("myNot", myNot);
}

void QuickDemo::channels_demo(Mat& image)
{
	std::vector imgv;
	split(image, imgv);
	imshow("分离蓝色", imgv.at(0));  //或者用imgv[0],显示分离后B
	imshow("分离绿色", imgv.at(1));  //或者用imgv[1],显示分离后G
	imshow("分离红色", imgv.at(2));  //或者用imgv[2],显示分离后R

	Mat dst;
	imgv.at(1) = 0;
	imgv.at(2) = 0;
	merge(imgv, dst);  //合并图像
	imshow("合并蓝色", dst);
}

void QuickDemo::inrange_demo(Mat& image)
{
	Mat hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	Mat mask;
	inRange(hsv,Scalar(35,43,46),Scalar(77,255,255),mask);
	imshow("mask", mask);

	Mat redback = Mat::zeros(image.size(), image.type());
	redback = Scalar(40, 40, 200);
	bitwise_not(mask, mask);
	imshow("mask", mask);
	image.copyTo(redback, mask);
	imshow("roi区域提取", redback);
}

void QuickDemo::pixel_static_demo(Mat& image)
{
	double minVal, maxVal;  //用于存放矩阵中的最大值和最小值
	Point minIdx, maxIdx;  //用于存放矩阵中的最大值和最小值在矩阵中的位置
	Mat imgs_re = image.reshape(1, 0);  //将多通道矩阵变成单通道矩阵
	minMaxLoc(imgs_re, &minVal, &maxVal, &minIdx, &maxIdx);
	std::cout << "img中最大值是:" << maxVal << "  " << "在矩阵中的位置:" << maxIdx << std::endl;
	std::cout << "img中最小值是:" << minVal << "  " << "在矩阵中的位置:" << minIdx << std::endl;

	std::cout << "/* 用meanStdDev同时求取图像的均值和标准差 */" << std::endl;
	Mat myMeanMat, myStddevMat;

	meanStdDev(image, myMeanMat, myStddevMat);
	std::cout << "img均值=" << myMeanMat << "    " << std::endl;
	std::cout << "img标准差=" << myStddevMat << std::endl ;

}

void QuickDemo::drawing_demo(Mat& image)
{
	//绘制矩形
	//rectangle(image, Point(200, 200), Point(300, 300), Scalar(125, 125, 125), -1);//-1为填充
	rectangle(image,Rect(400,450,100,150), Scalar(0, 125, 125), 2);//2为线宽,不填充

	Mat bg = Mat::zeros(image.size(), image.type());
	rectangle(bg, Point(200, 200), Point(300, 300), Scalar(0, 0, 255), -1);
	Mat dst;
	addWeighted(image, 0.7, bg, 0.3, 0, dst);
	imshow("dst", dst);
	//绘制圆
	circle(image, Point(100, 100), 50, Scalar(255, 255, 255), 3);
	//绘制直线
	line(image, Point(50, 50), Point(50, 200),Scalar(255,0,0), 2, LINE_4, 0);
	//绘制椭圆
	//这里的RotatedRect参数表示,中心点,长轴短轴,旋转角度
	ellipse(image, RotatedRect(Point2f(300, 300), Size2f(200, 100), 0), Scalar(0, 255, 255), 2);
	imshow("形状绘制", image);
}

void QuickDemo::polyline_drawing_demo()
{
	//绘制多边形
	Mat img = Mat::zeros(Size(512, 512), CV_8UC3);  //生成一个黑色图像用于绘制几何图形
	Point pp[2][6];
	pp[0][0] = Point(72, 200);
	pp[0][1] = Point(142, 204);
	pp[0][2] = Point(226, 263);
	pp[0][3] = Point(172, 310);
	pp[0][4] = Point(117, 319);
	pp[0][5] = Point(15, 260);
	pp[1][0] = Point(359, 339);
	pp[1][1] = Point(447, 351);
	pp[1][2] = Point(504, 349);
	pp[1][3] = Point(484, 433);
	pp[1][4] = Point(418, 449);
	pp[1][5] = Point(354, 402);
	Point pp2[5];
	pp2[0] = Point(350, 83);
	pp2[1] = Point(463, 90);
	pp2[2] = Point(500, 171);
	pp2[3] = Point(421, 194);
	pp2[4] = Point(338, 141);
	const Point* pts[3] = { pp[0],pp[1],pp2 };  //pts变量的生成
	int npts[] = { 6,6,5 };  //顶点个数数组的生成
	fillPoly(img, pts, npts, 3, Scalar(125, 125, 125), 8);  //绘制3个多边形,填充
	//---------------------------------------------------------
	Point p1(100, 100);
	Point p2(350, 100);
	Point p3(450, 280);
	Point p4(320, 450);
	Point p5(80, 400);
	std::vector ptt;
	ptt.push_back(p1);
	ptt.push_back(p2);
	ptt.push_back(p3);
	ptt.push_back(p4);
	ptt.push_back(p5);
	polylines(img, ptt, true, Scalar(0, 0, 255), 2, 8, 0);
	imshow("绘制多边形", img);
}

//鼠标响应,绘制矩形------------------------------------------------------
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 img = *((Mat*)userdata);
	if (event == EVENT_LBUTTONDOWN)
	{
		sp.x = x;
		sp.y = y;
		std::cout << "start point." << sp << std::endl;
	}
	else if (event == EVENT_LBUTTONUP)
	{
		ep.x = x;
		ep.y = y;
		std::cout << "start point." << ep << std::endl;
		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(img, box, Scalar(0, 125, 125), 2,8,0);//2为线宽,不填充
			imshow("鼠标绘制矩形", img);
			//imshow("ROI区域",img(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;
			std::cout << "start point." << ep << std::endl;
			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(img);
				rectangle(img, box, Scalar(0, 0, 255), 2, 8, 0);//2为线宽,不填充
				imshow("鼠标绘制矩形", img);
			}
		}
	}
}
void QuickDemo::mouse_drawing(Mat& image)
{
	temp = image.clone();
	namedWindow("鼠标绘制矩形",WINDOW_AUTOSIZE);
	setMouseCallback("鼠标绘制矩形", on_draw,(void *)(&image));
	imshow("鼠标绘制矩形", image);
	
}
//---------------------------------------------------------------------

void QuickDemo::norm_demo(Mat& image)
{
	Mat dst;
	std::cout << image.type() << std::endl;
	image.convertTo(image, CV_32F);
	std::cout << image.type() << std::endl;
	normalize(image, dst, 1.0, 0, NORM_MINMAX);
	std::cout << dst.type() << std::endl;
	imshow("图像数据归一化", dst);
}

void QuickDemo::resize_demo(Mat& image)
{
	Mat zoomin, zoomout;
	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, zoomout, Size(w*1.2, h*1.2), 0, 0, INTER_LINEAR);
	imshow("zoomout", zoomout);
}

void QuickDemo::flip_demo(Mat& image)
{
	Mat img_x, img_y, img_xy;
	//数值大于0,表示绕 y 轴进行翻转;数值等于 0 ,表示绕 x 轴进行翻转;数值小于 0 ,表示绕两个轴旋转
	flip(image, img_x, 0);  //沿x轴对称
	flip(image, img_y, 1);  //沿y轴对称
	flip(image, img_xy, -1);  //先x轴对称,再y轴对称
	imshow("img_x", img_x);
	imshow("img_y", img_y);
	imshow("img_xy", img_xy);
}

void QuickDemo::rotate_demo(Mat& image)
{
	Mat rotation0, rotation1, img_warp0, img_warp1, dst;
	double angle = 30;  //设置图像旋转的角度
	Size dst_size(image.rows, image.cols);  //设置输出图像的尺寸
	Point2f center(image.rows / 2.0, image.cols / 2.0);  //设置图像的旋转中心
	rotation0 = getRotationMatrix2D(center, angle, 1);  //计算仿射变换矩阵
	warpAffine(image, img_warp0, rotation0, dst_size, INTER_LINEAR, 0, Scalar(255, 0, 0));  //进行仿射变换
	imshow("旋转演示", img_warp0);
	//计算变换后的矩阵大小
	double cosx = abs(rotation0.at(0,0));
	double sinx = rotation0.at(0, 1);
	int nw = cosx * image.cols + sinx * image.rows;
	int nh = sinx * image.cols + cosx * image.rows;
	rotation0.at(0, 2) = rotation0.at(0, 2)+(nw/2- image.cols /2);
	rotation0.at(1, 2) = rotation0.at(1, 2) + (nh / 2 - image.rows / 2);
	warpAffine(image, dst, rotation0, Size(nw, nh), INTER_LINEAR, 0, Scalar(225, 125, 0));  //进行仿射变换
	imshow("旋转演示(计算变换后尺寸)", dst);
	
}

void  QuickDemo::video_demo(Mat& image)
{
	Mat frame;
	VideoCapture capture(0);
	while (true)
	{
		if (!capture.isOpened())  //判断是否调用成功
		{
			std::cout << "打开摄像头失败,请确认摄像头是否安装成功";
			break;
		}
		capture.read(frame);
		if (frame.empty())  //判断读取图像是否成功
		{
			std::cout << "没有获取到图像" << std::endl;
			break;
		}
		imshow("frame", frame);
		char c = waitKey(10);
		if (c == 27) //ESC键退出
		{
			break;
		}
	}

}

上述文件是对类中各个成员函数的实现,一个知识点对应一个成员函数。

quickopencv.h

#pragma once

#include 

using namespace cv;


class QuickDemo
{
public:
	void colorSpace_Demo(Mat& image);//将原图转为HSV和GRAY图像显示并保存
	void operator_demo(Mat& image);//进行像素操作,加减乘除
	void teacking_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_static_demo(Mat& image);//图像像素统计,最大最小值,均值方差
	void drawing_demo(Mat& image);//在图像中绘制几何图形
	void polyline_drawing_demo();//绘制多边形
	void mouse_drawing(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);
private:

};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

上述文件主要内容是QuickDemo类的声明。

OpenCv C++目前网上的视频课程质量均较差,最好的学习还是结合OpenCv官方文档和百度,进行学习。

你可能感兴趣的:(计算机视觉,c++,opencv,计算机视觉,图像处理)