Opencv学习日志

本文档介绍了如何配置OpenCV环境,包括在Visual Studio中设置库和头文件路径。接着,详细讲解了如何使用C++加载、显示、修改和保存图像,涉及imread、namedWindow、imshow、cvtColor和imwrite函数。还探讨了矩阵的掩膜操作、Mat对象的使用以及图像的读写和像素操作。最后,展示了图像混合的线性操作及addWeighted函数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Opencv:视觉库函数学习文档

一、Opencv环境配置

基于Visual Studio 下C++/Python项目下,在视图-其他窗口-属性管理器中,一般在Debug|X64下创建Microsoft.Cpp.x64.user属性表在VC++目录下,在包含目录下放置以下文件:
D:\opencv\opencv\build\include\opencv2
D:\opencv\opencv\build\include\opencv
D:\opencv\opencv\build\include

在VC++目录下,在库目录下放置以下文件:
D:\opencv\opencv\build\x64\vc14\lib
在链接器目录下,在输入目录下放置以下文件:
opencv_world341.lib
opencv_world341d.lib

二、 读取图像文件

首先引用Opencv库文件
#include <opencv2/opencv.hpp>
using namespace cv;
OpenCV的函数都位于cv这一命名空间下,为了调用OpenCV的函数,需要在每个函数前加上cv::,向编译器说明你所调用的函数处于cv命名空间。为了摆脱这种繁琐的工作,可以使用using namespace cv;指令。
载入图像:引用imread()函数。
Mat src = imread(“D:/Downloads/XXX.jpg”);

实例:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc,char* argv[]) {
	Mat src = imread("D:/Downloads/XXX.jpg");
	if (src.empty()) {// 判断路径是否正确
		printf("Count't open image...\n");
		return -1;
	}
	namedWindow("test image", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
	imshow("test open stucp", src); // 功能主要载入一张图片

	waitKey(0);
	/*注释
		等待按下函数:参数如果写负数或者0。
		当显示图片后,按下任意键后程序退出。如果参数写为3000就是3秒后程序自动退出。
	*/
	return 0;
}

三、 加载、修改、保存图像

加载图像:cv::imread
修改图像:cv::cvtColor
保存图像:cv::imwrite

  1. 载入图像(cv::imread)
    Imread功能是加载图像文件成为一个Mat对象,其中第一个参数即为图像文件名称,第二个参数,表示加载图像的类型,一般支持参见三种参数值
  • IMREAD_UNCHANGED(<0)表示加载原图,不做任何改变
  • IMREAD_GRAYSCALE(0)表示吧原图作为灰色图像加载
  • IMREAD_COLOR(>0)表示把原图作为RGB图像加载

注意:Opencv支持JPG、PNG、TIFF等常见的格式图像文件
2)显示图像(cv::namedWindos与cv::imshow)

  • namedWindos功能是创建一个Opencv窗口,它是由Opencv自动创建与释放,无需取消销毁。
  • 参见用法namedWindow(“Windos Title”,WINDOW_AUTOSIZE)
  • WINDOW_AUTOSIZE会自动显示窗口大小,不能人为改变大小
  • Imshow根据窗口名称显示到指定窗口上,第一个参数为窗口名称,第二个参数为Mat对象
    3)修改图像(cv::cvtColor)
     cvtColor的功能是把图像从一个彩色空间转换到另一个彩色空间,有三个参数,第一个参数表示原图像、第二个参数表示色彩空间转换后的图像,第三个参数表示原和目标色彩空间:如COLOR_BGR2HLS等等。
    样例:
namedWindow("outputs Windows", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
	Mat output_image;
	cvtColor(src, output_image, CV_BGR2GRAY);
	imshow("outputs Windows", output_image); // 功能主要载入一张图片

4)保存图像(cv::imwrite)

  • 保存文件到指定目录
  • 只有8位、16位的PNG,JPEG,TIFF文件格式并且是单通道格式或者三通道RGB格式才可以保存。
  • 保存PNG格式可以保存透明通道格式图片
  • 可以指定压缩参数
    样例:imwrite("D:/Downloads/XXX.tif", output_image);//保存一张图片

四、矩阵的掩膜操作

  • 获取图像像素指针
  • 掩膜操作解释
  • 代码演示
    1)、获取图像像素指针
  • CV_Assert(myImage.depth() == CV_8U);
  • Mat.ptr(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
  • 获得当前行指针const uchar* current= myImage.ptr(row );
  • 获取当前像素点P(row, col)的像素值 p(row, col) =current[col]
    2)、像素范围处理saturate_cast
  • saturate_cast(-100),返回 0。
  • saturate_cast(288),返回255
  • saturate_cast(100),返回100
  • 这个函数的功能是确保RGB值得范围在0~255之间
    在这里插入图片描述

3)、调用filter2D功能
在这里插入图片描述

五、 Mat对象

  • Mat对象与IplImage对象
  • Mat对象使用
  • Mat定义数组
    1)、Mat对象与IplImage对象
  • Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
  • plImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题
    2)、Mat对象构造函数与常用方法

常用方法:

void copyTo(Mat mat)
void convertTo(Mat dst, int type)
Mat clone()
int channels()
int depth()
bool empty();
uchar* ptr(i=0)

3)、Mat对象使用-四个要点

  • 输出图像的内存是自动分配的
  • 使用OpenCV的C++接口,不需要考虑内存分配问题
  • 赋值操作和拷贝构造函数只会复制头部分
  • 使用clone与copyTo两个函数实现数据完全复制

六、 图像操作

  • 读写图像
  • 读写像素
  • 修改像素值
    1)、读写图像
  • imread:可以指定加载为灰度或者RGB图像
  • imwrite: 保存图像文件,类型由扩展名决定

    2)、读写像素
  • 读一个GRAY像素点的像素值(CV_8UC1)
    Scalar intensity = img.at(y, x);
    或者 Scalar intensity = img.at(Point(x, y));
  • 读一个RGB像素点的像素值
    Vec3f intensity = img.at(y, x);
    float blue = intensity.val[0];
    float green = intensity.val[1];
    float red = intensity.val[2];
    3)、修改像素值
  • 灰度图像
    img.at(y, x) = 128;
  • RGB三通道图像
    img.at(y,x)[0]=128; // blue
    img.at(y,x)[1]=128; // green
    img.at(y,x)[2]=128; // red
  • 空白图像赋值
    img = Scalar(0);
  • ROI选择
    Rect r(10, 10, 100, 100);
    Mat smallImg = img(r);
    4)、Vec3b与Vec3F
  • Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。
  • Vec3f对应三通道的float类型数据
  • 把CV_8UC1转换到CV32F1实现如下:
	src.convertTo(dst, CV_32F);

反向输出图像通道值

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>

using namespace cv;
using namespace std;
int main(int argc, char** argv) {
	
	Mat src = imread("D:/Downloads/XXX.jpg");
	Mat dst, gray_src;
	if (src.empty()) {// 判断路径是否正确
		printf("Count't open image...\n");
		return -1;
	}
	namedWindow("test image", CV_WINDOW_AUTOSIZE); // 自动分辨窗体大小
	imshow("test open stucp", src); // 功能主要载入一张图片
	dst.create(src.size(), src.type());//获取对象src的大小,src的类型
	int height = src.rows;
	int weight = src.cols;
	int nc = src.channels();//获取对象src图像通道数量
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < weight; 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;
			}
		}
	}
	namedWindow("the next image",CV_WINDOW_AUTOSIZE);
	imshow("the next image", dst);//输出反向通道的值
	waitKey(0);
	return 0;
}

七、图像混合

  • 理论-线性混合操作
  • 相关API (addWeighted)
    1)、理论-线性混合操作
    在这里插入图片描述

其中 在这里插入图片描述的取值范围为0~1之间

2)、相关API (addWeighted)
在这里插入图片描述在这里插入图片描述

参数1:输入图像Mat – src1
参数2:输入图像src1的alpha值
参数3:输入图像Mat – src2
参数4:输入图像src2的alpha值
参数5:gamma值
参数6:输出混合图像

注意点:两张图像的大小和类型必须一致才可以

效果呈现

图片1

在这里插入图片描述

图片2

在这里插入图片描述

效果呈现

在这里插入图片描述
参考代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>

using namespace cv;
using namespace std;
int main(int argc, char** argv) {
//图像混合操作
	//alpha表示通道
	/*
		在RGB色彩空间三个通道的基础上,还可以加上一个A通道,也叫alpha通道,表示透明度
		alpha通道的赋值范围是[0,1],或者[0,255],表示从透明到不透明
	*/
	Mat src1, src2, dst;
	//为后期图像对比做知识铺垫
	src1 = imread("C:/Users/Administrator/Desktop/2.jpg");
	src2 = imread("C:/Users/Administrator/Desktop/3.jpg");
	if (!src1.data) {
		cout << "could not load image1..." << endl;
		return -1;
	}
	if (!src2.data) {
		cout << "could not load image2..." << endl;
		return -1;
	}
	double alpha = 0.5;
	//attention please(important):the image must coincide,and size together!
	//if two images size difference, must return -1
	if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type()) {
		addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst);
		//multiply(src1, src2, dst, 1.0);

		imshow("Logo1", src1);
		imshow("Logo2", src2);
		namedWindow("blend demo", CV_WINDOW_AUTOSIZE);
		imshow("blend demo", dst);
	}
	else {
		printf("could not blend images , the size of images is not same...\n");
		return -1;
	}
	waitKey(0);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不知名的MasaNvi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值