C++ Opencv初级 上

  1. main方法定义
int main(int argc, char **argv) {
	//图像输入和颜色展示(IMREAD_GRAYSCALE--灰色)
	Mat mat = imread("图像路径");
	//判断加载是否为空
	if (mat.empty()){
		cout << "加载错误" << endl;}
	else{
		cout << "加载正常" << endl;}
	//全窗口显示
	namedWindow("原图像",WINDOW_NORMAL);
	//窗口显示
	imshow("原图像", mat);
	//调用方法
	colordemo(mat);
	waitKey(0);//程序不自动退出
	destroyAllWindows();
	return 0;
  1. 定义图像并保存图片
void colordemo(Mat &image) {
	Mat gray, hsv;//定义两个图像层
	cvtColor(image, hsv, COLOR_BGR2HSV);//灰度
	cvtColor(image, gray, COLOR_BGR2GRAY);//彩色
	imshow("HSV", hsv);//imshow只支持8位图像展示
	imshow("灰度", gray);
	imwrite("保存路径/hsv.png", hsv);
	imwrite("保存路径/gray.png", gray);
}
  1. Mat函数浅解与图像克隆、复制
void mat_create(Mat &image) {
	Mat mat1,mat2;
	//两种复制方法
	mat1 = image.clone();//克隆
	image.copyTo(mat2);//复制
	namedWindow("克隆", WINDOW_FREERATIO);
	namedWindow("复制", WINDOW_FREERATIO);
	imshow("克隆",mat1);
	imshow("复制", mat2);
	//创建空白图像
	Mat mat3 = Mat::zeros(Size(8, 8), CV_8UC3); //8UC1中的1表示单通道
	mat3 = Scalar(255,0,0);
	mat3.cols;//高度
	mat3.rows;//宽度
	mat3.channels();//通道数
	std::cout<< mat3 <<endl;
	namedWindow("空白图像", WINDOW_FREERATIO);
	imshow("空白图像", mat3);
  1. 图像像素值遍历
void xiangsu1(Mat &image) {
	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++) {
			if (dims == 1) {//灰度图像
				int pv = image.at<uchar>(row, col);//将相应的像素值复制到样本集中
				image.at<uchar>(row, col) = 255 - pv;
			}
			if (dims == 3) {//彩色图像
				Vec3b bgr = image.at<Vec3b>(row, col);
				image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
				image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
				image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
			}
		}
	}
	namedWindow("像素读写演示", WINDOW_FREERATIO);
	imshow("像素读写演示", image);
}
  1. 对图像像素进行加减乘除操作
void xiangsu2(Mat &image) {
	Mat mat4,mat5,mat6,mat7;//输出图像
	Mat m = Mat::zeros(image.size(), image.type());//保持与原图像格式一致
	Mat n = Mat::zeros(image.size(), image.type());
	m = Scalar(2, 2, 2);
	n = Scalar(50, 50, 50);
	//参数依次为第一张图像,第二张图像和输出图像
	add(image, n, mat4);//加法
	subtract(image, n, mat5);//减法
	multiply(image, m, mat6);//乘法
	divide(image,m,mat7);//除法
	namedWindow("加法操作", WINDOW_FREERATIO);
	imshow("加法操作", mat4);
	namedWindow("减法操作", WINDOW_FREERATIO);
	imshow("减法操作", mat5);
	namedWindow("乘法操作", WINDOW_FREERATIO);
	imshow("乘法操作", mat6);
	namedWindow("除法操作", WINDOW_FREERATIO);
	imshow("除法操作", mat7);
}
  1. 图像滚动条定义
Mat m, dst, src;
int lightess = 50;
static void on_lightness(int b, void* userdata) {//亮度函数定义
	Mat image = *((Mat*)userdata);
	m = Mat::zeros(image.size(), image.type());//保持与原图像格式一致
	dst = Mat::zeros(image.size(), image.type());
	addWeighted(image, 1.0, m, 0, b, dst);//将图片m和图片dst进行融合
	imshow("亮度和饱和度调整", dst);
}
static void on_contrast(int b, void* userdata) {//饱和度函数定义
	Mat image = *((Mat*)userdata);
	m = Mat::zeros(image.size(), image.type());//保持与原图像格式一致
	dst = Mat::zeros(image.size(), image.type());
	double contrast = b / 100.0;
	addWeighted(image, contrast, m, 0.0, 0, dst);//将图片m和图片dst进行融合
	imshow("亮度和饱和度调整", dst);
}
void gundong(Mat &image) {
	namedWindow("亮度和饱和度调整",WINDOW_NORMAL);
	int lightness = 50;
	int contrast_value = 100;
	int max_value = 100;
	createTrackbar("亮度:", "亮度和饱和度调整", &lightess, max_value,on_lightness, (void*)(&image));//加载滚动条
	createTrackbar("饱和度:", "亮度和饱和度调整", &contrast_value, 200, on_contrast,(void*)(&image));//加载滚动条
	on_lightness(50, &image);
}
  1. 接收键盘信号操作
void key_value(Mat &image) {
	Mat dst = Mat::zeros(image.size(), image.type());//定义一张空白图片
	while (true)
	{
		int c = waitKey(100);//键盘输入字符进行整型转化
		if (c == 27) {//ESC键
			break;
		}
		if (c == 49) {//1键
			cout << "you enter key # 1" << endl;
			cvtColor(image, dst, COLOR_BGR2GRAY);//转化为灰色图像
		}
		if (c == 50) {//2键
			cout << "you enter key # 2" << endl;
			cvtColor(image, dst, COLOR_BGR2HSV);//转化为HSV图像
		}
		if (c == 51) {//3键
			cout << "you enter key # 3" << endl;
			dst = Scalar(100, 100, 100);//图像亮度增加100
			add(image, dst, dst);
		}
		namedWindow("键盘响应", WINDOW_NORMAL);
		imshow("键盘响应",dst);
	}
}
  1. 图像16种伪色彩转化轮播
void color_style(Mat &image) {
	int dex = 1;
	Mat dst = Mat::zeros(image.size(), image.type());
	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_VIRIDIS,COLORMAP_CIVIDIS,COLORMAP_TWILIGHT,COLORMAP_TWILIGHT_SHIFTED};
	while (true){
		int c = waitKey(1500);
		if (c == 27) {
			break;
		}
		if (c == 49) {
			applyColorMap(image, dst, colormap[dex % 16]);//伪彩色函数轮播
			dex++;
		}
		namedWindow("图像轮播", WINDOW_NORMAL);
		imshow("图像轮播", dst);
	}
}
  1. 图像矩阵绘制与图像逻辑操作
void bitwise_demo(Mat &image) {
	Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
	Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
	//画一个矩形,其中的1表示边框宽度,-1表示全部填充
	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 std1,std2,std3,std4;
	bitwise_and(m1,m2,std1);//取m1、m2的交集
	bitwise_not(m1, std2);//取反
	bitwise_xor(m1, m2, std3);//异或
	bitwise_or(m1, m2, std4);//或
	imshow("取交集", std1);
	imshow("取反", std2);
	imshow("异或集", std3);
	imshow("或集", std4);
}
  1. 三基色通道分离
void channels_demo(Mat &image) {
	vector<Mat>mv;//定义一个Mat类型的mv
	split(image, mv);
	//imshow("蓝色", mv[0]);
	//imshow("绿色", mv[1]);
	//imshow("红色", mv[2]);
	//显示单个颜色,其他颜色要为0,所以只需要改变其中某两个为0即可
		Mat dst;
		mv[1] = 0;
		mv[2] = 0;
		merge(mv, dst);
		//imshow("蓝色", dst);
	//通道颜色转化,例如将蓝色和红色互换,绿色部分不变
		int from_to[] = { 0,2,1,1,2,0 };
		mixChannels(&image, 1, &dst, 1, from_to, 3);//颜色转换
		imshow("通道颜色转换", dst);
}
  1. 色彩转换提取轮廓(红绿互换)
void inrange_demo(Mat &image) {
	Mat hsv,mask;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	inRange(hsv, Scalar(35,43,46), Scalar(77	, 255, 255), 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);
}
  1. 图像最大最小值和方差等特征提取
void mean_demo(Mat &image) {
	double minv, maxv;
	Point minLoc, maxLoc;
	vector<Mat>mv;
	split(image, mv);//将图像转化为单通道
	for (int i = 0; i < mv.size(); i++) {
		minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());//求图像最大最小值
		cout << "No.channels:" << i << ";min value:" << minv << ";max value:" << maxv << endl;
	}
	Mat mean, stddev;
	meanStdDev(image, mean, stddev);//求图像均值和方差
	cout << "means:" << mean << endl;
	cout << "stddev:" << stddev<<endl;
}
  1. 绘制矩形、圆、直线
void drawing_demo(Mat &image) {
	Rect rect;
	rect.x = 200;
	rect.y = 200;
	rect.width = 100;
	rect.height = 100;//上面5行相当于Rect rect(200,200,100,100);
	rectangle(image, rect, Scalar(0, 0, 255), 1, 8, 0);//绘制矩形
	circle(image, Point(350, 400), 40, Scalar(255, 0, 0), 1, 8, 0);//绘制一个圆
	line(image, Point(100, 100), Point(350, 400), Scalar(0, 255, 0), 4, LINE_AA, 0);//绘制一条线
	namedWindow("绘制演示", WINDOW_FREERATIO);
	imshow("绘制演示", image);
}
  1. 随机线条绘制
void random_drawing() {
	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(1000);
		if (c == 27) {
			break;
		}
		//随机选取2条线进行连接
		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);
	}
}
  1. 多边形的填充与绘制
void duobian_demo() {
	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(80, 100);
	std::vector<Point>pst;//定义vector容器Point点,名称为pst
	//在pst后添加元素
	pst.push_back(p1);
	pst.push_back(p2);
	pst.push_back(p3);
	pst.push_back(p4);
	pst.push_back(p5);
	std::vector<std::vector<Point>>contours;
	contours.push_back(pst);
	//fillPoly(canvas, pst, Scalar(255, 0, 255), 8, 0);//填充多边形
	//polylines(canvas, pst, true, Scalar(0, 0, 255), 2, LINE_AA, 0);//绘制多边形
	drawContours(canvas, contours, -1, Scalar(255, 0, 0), 2);//绘制和填充,填充将2改为-1
	imshow("多边形绘制", canvas);
}
  1. 鼠标事件绑定(图像区域截取并显示)
Point sp(-1, -1);//起始节点
Point ep(-1, -1);//终止节点
Mat temp;//为了保存原图建立一个空白图像
/*鼠标动作*/
void mouse_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 << "坐标:" << 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区域", image(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 mouse(Mat &image) {
	namedWindow("鼠标绘制", WINDOW_FREERATIO);
	setMouseCallback("鼠标绘制", mouse_draw, (void*)(&image));
	imshow("鼠标绘制", image);
	temp = image.clone();//克隆原图
}

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