OpenCV对图像的操作(3)

目录

官方在线帮助文档:OpenCV: OpenCV modules

用OpenCV对图像做一些简单的操作

1. 随机数与随机颜色

 2. 多边形绘制与填充

3. 鼠标操作与响应

4. 图像像素类型转换归一化

5. 图像放缩与插值

6. 图像翻转

7. 图像旋转


官方在线帮助文档:OpenCV: OpenCV modules

用OpenCV对图像做一些简单的操作

1. 随机数与随机颜色

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	
	
	class demo
	{
	public:
		void random_drawing()
		{
			Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
			int width = canvas.cols;
			int height = canvas.rows;
			RNG rng(12345);
			while (true) {
				int c = waitKey(100);
				if (c == 27) {
					break;
				}
				// 随机坐标
				int x1 = rng.uniform(0, width);
				int y1 = rng.uniform(0, height);
				int x2 = rng.uniform(0, width);
				int y2 = rng.uniform(0, height);
	
				// 随机颜色
				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), 4, LINE_AA, 0);
				imshow("随机绘制演示", canvas);
			}
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.random_drawing(); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

 2. 多边形绘制与填充

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	
	
	class demo
	{
	public:
		void polyline_drawing_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, 400);
	
			vector<Point> pts(5);
			pts.push_back(p1);
			pts.push_back(p2);
			pts.push_back(p3);
			pts.push_back(p4);
			pts.push_back(p5);
	
			// 绘制
			//polylines(canvas, pts, true, Scalar(0, 0, 255), 2, 8, 0);
			// 填充
			//fillPoly(canvas, pts, true, Scalar(255, 255, 0), 8, 0);
	
			vector<vector<Point>> contours;
			contours.push_back(pts);
			drawContours(canvas, contours, -1, Scalar(255, 0, 0), 2);
			// 2绘制形状,-1填充
			imshow("多边形绘制", canvas);
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.polyline_drawing_demo(); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

3. 鼠标操作与响应

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	
	// 鼠标响应
	Point sp(-1, -1);
	Point ep(-1, -1);
	// 设置一个临时图层,确保显示最后一个图片
	Mat temp;
	class demo
	{
	public:
		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);
					temp.copyTo(image);// 解决ROI区域有颜色框的问题
					imshow("ROI区域", image(box));
					rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
					imshow("鼠标绘制", image);
					// 每次绘制完成之后要更新数据
					sp.x = -1;
					sp.y = -1;
				}
				cout << "end point:" << ep << endl;			
			}
			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);
						
					}
					cout << "end point:" << ep << endl;
				}
			}
		}
		void mouse_drawing_demo(Mat &image)
		{
			namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
			setMouseCallback("鼠标绘制", on_draw,(void*)(&image));
			imshow("鼠标绘制", image);
			temp = image.clone();
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.mouse_drawing_demo(src); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

4. 图像像素类型转换归一化

四种归一化方法

  • NORM_MINMAX
  • NORM_INF
  • NORM_L1
  • NORM_L2

最常用的就是NORM_MINMAX归一化方法

关于API函数:

  • normalize(
  • InputArray src  ,       // 输入图像
  • InputOutputArray  dst,       // 输出图像
  • double alpha=1,     //NORM_MINMAX时候低值
  • double beta=0,     //NORM_MINMAX时候高值
  • int norm_type=NORM_L2,     // 只有alpha
  • int dtype=-1,      // 默认类型与src一致
  • InputArray    mask=noArray()     //mask默认值为空
	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	class demo
	{
	public:
		void norm_demo(Mat& image)
		{
			Mat dst;
			cout << image.type() << endl;
			image.convertTo(dst, CV_32F);
			cout << image.type() << endl;
			normalize(image, dst, 1.0, 0, NORM_MINMAX);
			cout << dst.type() << endl;
			imshow("图像数据归一化", dst);
			// CV_8UC3  转换为  CV_32FC3
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.norm_demo(src); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

5. 图像放缩与插值

图像插值(Image Interpolation)

最常见的四种插值算法

  • INTER_NEAREST=0;
  • INTER_LINEAR=1;
  • INTER_CUBIC=2
  • INTER_LANCZOS4=4

相关应用场景

几何变换,透视变换,插值计算新像素  resize

如果size有值,使用size做放缩插值,否则根据fx与fy卷积

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	class demo
	{
	public:
		void resize_demo(Mat& image)
		{
			Mat zoomin, zoomout;
			int height = image.rows;
			int width = image.cols;
			resize(image, zoomin, Size(width * 1.50, height * 1.50), 0, 0, INTER_LINEAR);
			imshow("zoomin", zoomin);// 放大
			resize(image, zoomout, Size(width / 2.0, height / 2.0), 0, 0, INTER_LINEAR);
			imshow("zoomout", zoomout);// 缩小
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.resize_demo(src); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

6. 图像翻转

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	class demo
	{
	public:
		void flip_demo(Mat& image)
		{
			Mat dst;
			flip(image, dst, 0);
			imshow("图像翻转(上下)", dst);// 上下翻转
			flip(image, dst, 1);
			imshow("图像翻转(左右)", dst);// 左右反转
			flip(image, dst, -1);
			imshow("旋转180度", dst);// 旋转180度
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.flip_demo(src); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

7. 图像旋转

	#include<opencv2/opencv.hpp>
	#include<iostream>
	#include<vector>
	
	using namespace cv;
	using namespace std;
	class demo
	{
	public:
		void rotate_demo(Mat& image)
		{
			Mat dst,M;
			int width = image.cols;
			int height = image.rows;
			M = getRotationMatrix2D(Point2f(width / 2, height / 2), 45, 1.0);
			double cos = abs(M.at<double>(0, 0));
			double sin = abs(M.at<double>(0, 1));
			int new_width = cos * width + sin * height;
			int new_height = sin * width + cos * height;
			M.at<double>(0, 2) += (new_width / 2 - width / 2);
			M.at<double>(1, 2) += (new_height / 2 - height / 2);
			warpAffine(image, dst, M, Size(new_width, new_height), INTER_LINEAR, 0, Scalar(255, 255, 0));
			imshow("旋转演示", dst);
		}
	};
	int main(int argc, char** argv)
	{
		Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
		// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
		// namedWindow("输出窗口", WINDOW_FREERATIO);
		// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
		if (src.empty()) {
			cout << "没有找到你的图片" << endl;
			return -1;
		}
	
		imshow("输出窗口", src);
	
		demo d;
		d.rotate_demo(src); 
		waitKey(0);// 设置图片显示时间
		destroyAllWindows();// 释放所有窗口
		return 0;
	}

写的比较简单,都是直接上代码了,关于每个方法的介绍我准备后期补上,大家先看官方文档的介绍。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值