当前位置: 首页>编程语言>正文

图像数据处理库OpenCV 自动驾驶 图像处理软件opencv


目录

  • VS2019 + opencv环境安装
  • OpenCV简单介绍(摘抄百度百科)
  • 知识点总结(主要总结的是图像分割)
  • 1.图像的加载、修改、保存
  • 2.矩阵的掩模操作
  • 3. Mat的简单用法
  • 4. 读写像素
  • 5. 图像混合
  • 6. 调整图像亮度和对比度
  • 7. 绘制形状和文字


VS2019 + opencv环境安装

1) 本人的环境是VS2019 + OpenCV
VS2019 社区版就够了(自己注册微软账号) 下载链接:link.

2) VS2019 opencv配置 网上有很多安装方法这边就不具体介绍了
下载opencv安装包(我下载的是3.4.11版本,其他版本还没试过) 下载链接:link

OpenCV简单介绍(摘抄百度百科)

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1] 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。

应用领域:
1、人机互动
2、物体识别
3、图像分割
4、人脸识别
5、动作识别
6、运动跟踪
7、机器人
8、运动分析
9、机器视觉
10、结构分析
11、汽车安全驾驶

知识点总结(主要总结的是图像分割)

1.图像的加载、修改、保存

1.imread 加载图片
Mat imread( const string& filename, int flags = 1 )
2.namedWindow 创建窗口,自动创建和释放无需销毁
void cv::namedWindow(const cv::String &winname, int flags = 1)
3.imshow 显示创建的窗口
void cv::imshow(const cv::String &winname, cv::InputArray mat)
4.cvtColor 修改图像颜色
void cv::cvtColor(cv::InputArray src, cv::OutputArray dst, int code, int dstCn = 0)
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("E:/fireBall.jpg");//读图片,加载
	//Mat我们可以理解为一个存储数据的容器,定义了一个img对象来存图片的数据
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}

	namedWindow("test opencv setup", CV_WINDOW_AUTOSIZE);//创建一个OpenCV窗口,自动创建和释放无需销毁
	imshow("test opencv setup", src);//显示窗口
	
	namedWindow("output window", CV_WINDOW_AUTOSIZE);
	Mat output_image;
	cvtColor(src, output_image, CV_BGR2HSV);//修改图像颜色
	imshow("output window", output_image);

	imwrite("E:/hlstrest.jpg", output_image);//保存图片
	waitKey(0);//等待按下函数:参数如果写负数或者0。当显示图片后,按下任意键后程序退出。如果参数写为3000就是3秒后程序自动退出
	return 0;
}

2.矩阵的掩模操作

掩模操作实现图像对比度的提高

获取图像像素指针	
CV_Assert(myImage.depth() == CV_8U);
Mat.ptr<uchar>(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
获得当前行指针const uchar*  current= myImage.ptr<uchar>(row );
获取当前像素点P(row, col)的像素值 p(row, col) =current[col]

像素范围处理saturate_cast<uchar>
saturate_cast<uchar>(-100),返回 0。
saturate_cast<uchar>(288),返回255
saturate_cast<uchar>(100),返回100
这个函数的功能是确保RGB值得范围在0~255之间

图像数据处理库OpenCV 自动驾驶 图像处理软件opencv,图像数据处理库OpenCV 自动驾驶 图像处理软件opencv_#include,第1张

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;

int main(int argc, char** argv) {
	Mat src, drt;
	src = imread("E:/fireBall.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	int cols = (src.cols - 1) * src.channels();// 边缘的像素点的不做处理
	int offsetx = src.channels();
	int rows = src.rows;
	drt = Mat::zeros(src.size(), src.type());// 创建一个和scr一样大小的,类型一样的全黑图像。
	//掩模操作************//
	for (int row = 1; row < (rows - 1); row++) {
		const uchar* previous = src.ptr<uchar>(row - 1);
		const uchar* current = src.ptr<uchar>(row);
		const uchar* next = src.ptr<uchar>(row + 1);
		uchar* output = drt.ptr<uchar>(row);
		for (int col = offsetx; col < cols; col++) {
			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));
		}
	}
	//掩模操作*************//

	/*//把上面的掩膜操作,注释掉,就这两行就可以代替。
	double t = getTickCount();//获取时间
	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//定义掩模
	filter2D(src, drt, src.depth(), kernel);//API
	double timeconsume = (getTickCount() - t) / getTickFrequency();//获取执行时间
	printf("tim consume %.2f\n", timeconsume);*/

	namedWindow("contrast image demo", CV_WINDOW_AUTOSIZE);
	imshow("contrast image demo", drt);

	waitKey(0);
	return 0;
}

图像数据处理库OpenCV 自动驾驶 图像处理软件opencv,图像数据处理库OpenCV 自动驾驶 图像处理软件opencv_opencv_02,第2张

3. Mat的简单用法

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;

int main(int argc, char** argv) {
	Mat src;
	src = imread("E:/fireBall.jpg");
	if (src.empty()) {
		cout << "could not load image..." << endl ;
		return -1;
	}
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);*/

	Mat dst;
	dst = Mat(src.size(), src.type());
	dst = Scalar(127, 0, 255);
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	imshow("output", dst);

	//Mat dst = src.clone();//克隆
	//Mat dst;
	src.copyTo(dst);//复制
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	

	cvtColor(src, dst, CV_BGR2GRAY);
	cout << "input channels :   " << src.channels() << endl;
	cout << "output channels :   " << dst.channels() << endl;
	
	int cols = dst.cols;
	int rows = dst.rows;
	const uchar* firstRow = dst.ptr<uchar>(0);
	cout << "rows :  " << rows << "  cols : " << cols << endl;
	cout << "first pixel value :  " << *firstRow << endl;

	Mat M(100, 100, CV_8UC3, Scalar(0, 0, 255));
	//cout << "M = " << endl << M << endl;

	imshow("output", M);

	waitKey(0);
	return 0;
}

4. 读写像素

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;

int main(int argc, char** argv) {
	Mat src, gray_src;
	src = imread("E:/fireBall.jpg");
	if (src.empty()) {
		cout << "could not load image..." << endl;
		return -1;
	}
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src); 

	cvtColor(src, gray_src, CV_BGR2GRAY);//图像变灰
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	imshow("output", gray_src);
	int height = gray_src.rows;
	int width = gray_src.cols;
	//单通道
	for (int row = 0; row < height; row++){
		for (int col = 0; col < width; col++) {
			int gray = gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 255 - gray;//反差图片
		}
	}
	
	imshow("output", gray_src);

	Mat dst;
	dst.create(src.size(), src.type());
	height = src.rows;
	width = src.cols;
	int nc = src.channels();
	//三通道
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			if (nc == 1) {
				int gray = gray_src.at<uchar>(row, col);
				gray_src.at<uchar>(row, col) = 255 - gray;
			}
			else if (nc == 3) {
				int b = src.at<Vec3b>(row, col)[0];
				int g = src.at<Vec3b>(row, col)[1];
				int r = src.at<Vec3b>(row, col)[2];
				dst.at<Vec3b>(row, col)[0] = 255 - b;
				dst.at<Vec3b>(row, col)[1] = 255 - g;
				dst.at<Vec3b>(row, col)[2] = 255 - r;
			}
		}
	}
	//bitwise_not(src, dst);//API反位操作//求反差图片
	imshow("output", dst);
	waitKey(0);
	return 0; 
}

5. 图像混合

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;

int main(int argc, char** argv) {
	Mat src1, src2, dst;
	src1 = imread("E:/1.png");
	src2 = imread("E:/2.png");
	if (src1.empty()) {
		cout << "could not load image..." << endl;
		return -1;
	}
	if (src2.empty()) {
		cout << "could not load image..." << endl;
		return -1;
	}
	double alpha = 0.5;
	if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type()) {
		addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst);
		//add(src1, src2, dst, Mat());//图像普通相加
		//multiply(src1, src2, dst, 1.0);//图像相乘
		imshow("src1", src1);
		imshow("src2", src2);
		namedWindow("blend demo", CV_WINDOW_AUTOSIZE);
		imshow("blend demo", dst);
	}
	else {
		cout << "could not blend images , the size of imagers is not same... \n" << endl;
		return -1;
	}
	
	waitKey(0);
	return 0;
}

6. 调整图像亮度和对比度

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;//使用命名空间cv,使用过C++的都明白,我们写C++程序必须使用using namespace std
using namespace std;
	Mat src, dst;
	src = imread("E:/fireBall.jpg");
	if (src.empty()) {
		cout << "could not load image..." << endl;
		return -1;
	}
	char input_win[] = "input image";
	//cvtColor(src, src, CV_RGB2GRAY);//转为单通道
	namedWindow(input_win, CV_WINDOW_AUTOSIZE);
	imshow("input", src);

	//contrast and brightness change
	int height = src.rows;
	int width = src.cols;
	dst = Mat::zeros(src.size(), src.type());
	float alpha = 1.2;//对比度
	float beta = 30;//亮度

	Mat ml;
	src.convertTo(ml, CV_32F);
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			if (src.channels() == 3) {
				float b = ml.at<Vec3f>(row, col)[0];
				float g = ml.at<Vec3f>(row, col)[1];
				float r = ml.at<Vec3f>(row, col)[2];

				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);//公式
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
			}
			else if (src.channels() == 1) {
				float v = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
			}
		}
	}

	char output_title[] = "contrast and brightness change demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow(output_title, dst);

	waitKey(0);
	return 0;
}

7. 绘制形状和文字

函数

1.直线
void cv::line(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, const cv::Scalar &color, int thickness = 1, int     lineType = 8, int shift = 0)
2.矩形
void cv::rectangle(cv::Mat &img, cv::Rect rec, const cv::Scalar &color, int thickness = 1, int lineType = 8, int shift =    0)
3.椭圆
void cv::ellipse(cv::InputOutputArray img, cv::Point center, cv::Size axes, double angle, double startAngle, double     endAngle, const cv::Scalar &color, int thickness = 1, int lineType = 8, int shift = 0)
4.圆
void cv::circle(cv::InputOutputArray img, cv::Point center, int radius, const cv::Scalar &color, int thickness = 1, int     lineType = 8, int shift = 0)
5.填充区域
void cv::fillPoly(cv::Mat &img, const cv::Point **pts, const int *npts, int ncontours, const cv::Scalar &color, int     lineType = 8, int shift = 0, cv::Point offset = cv::Point())
6.文字水印
void cv::putText(cv::InputOutputArray img, const cv::String &text, cv::Point org, int fontFace, double fontScale, cv::    Scalar color, int thickness = 1, int lineType = 8, bool bottomLeftOrigin = false)
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>


using namespace cv;
using namespace std;

Mat bgImge;
const char* drawdemo_win = "draw shapes and text demo";

//直线
void MyLines() {
	Point p1 = Point(20, 30);
	Point p2;
	p2.x = 300;
	p2.y = 300;
	Scalar color = Scalar(0, 0, 255);
	line(bgImge, p1, p2, color, 1, LINE_8);
}

//矩形
void MyRectangle() {
	Rect rect = Rect(200, 100, 300, 300);
	Scalar color = Scalar(255, 0, 255);
	rectangle(bgImge, rect, color, 2, LINE_8);
}

//椭圆
void MyEllipse() {
	Scalar color = Scalar(255, 0, 255);
	ellipse(bgImge, Point(bgImge.cols / 2, bgImge.rows / 2), Size(bgImge.cols / 4, bgImge.rows / 8), 90, 0, 360, color, 2, LINE_8);
}

//圆
void MyCircle() {
	Scalar color = Scalar(0, 255, 255);
	Point center = Point(bgImge.cols / 2, bgImge.rows / 2);
	circle(bgImge, center, 100, color, 2, 8);
}

//填充区域
void MyPolygon() {
	Point pts[1][5];
	pts[0][0] = Point(100, 100);
	pts[0][1] = Point(100, 200);
	pts[0][2] = Point(200, 200);
	pts[0][3] = Point(200, 100);
	pts[0][4] = Point(100, 100);

	const Point* ppts[] = { pts[0] };
	int  npt[] = { 5 };
	Scalar color = Scalar(255, 12, 255);
	fillPoly(bgImge, ppts, npt, 1, color, 8);
}

//随机线条
void RandomLineDemo() {
	RNG rng(12345);//生成随机数
	Point pt1;
	Point pt2;
	Mat bg = Mat::zeros(bgImge.size(), bgImge.type());
	namedWindow("random line demo", CV_WINDOW_AUTOSIZE);
	for (int i = 0; i < 100000; i++) {
		pt1.x = rng.uniform(0, bgImge.cols);
		pt2.x = rng.uniform(0, bgImge.cols);
		pt1.y = rng.uniform(0, bgImge.rows);
		pt2.y = rng.uniform(0, bgImge.rows);
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		if (waitKey(50) > 0) {
			break;
		}
		line(bg, pt1, pt2, color, 1, 8);
		imshow("random line demo", bg);
	}
}

在此说明,知识点为博主从b站up ggi2016 学习的总结,如有侵权,可私信于我。
学习小白,若有错误,还望指正,山高水长。。。



https://www.xamrdz.com/lan/57g1930502.html

相关文章: