OpenCV 简单介绍

环境搭建

  1. 下载OpenCV库
    https://opencv.org/releases/
  2. 设置引用目录
    \opencv\sources\include\opencv2
  3. 设置库目录(我用的x64的)
    \opencv\build\x64\vc14\lib

基础讲解

  • cv::Mat 矩阵类型
    Mat中还含有每个像素的像素值

  • 图像文件格式
    CV_8UC1,CV_8UC2,CV_8UC3 等等
    含义是:8U 8bit的unsigned类型,CX指几个通道

  • 读取文件
    cv::Mat img = cv::imread(“C:/test.jpg”);

  • 新建一个显示窗口
    cv::namedWindow(“测试”, cv::WINDOW_AUTOSIZE);

  • 在“测试”这个窗口输出图片。
    cv::imshow(“测试”, img);

入门代码

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

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#pragma comment(lib,"opencv_world411d.lib")
int main()
{
	//读取文件
	cv::Mat img = cv::imread("C:/test.jpg");
	if (img.empty()) {
		printf_s("找不到图片\n");
		return -1;
	}

	
	/*
	flag 可以选
	WINDOW_AUTOSIZE 窗口大小自动适应图片大小,并且不可手动更改。(上面图1就是使用的它)
	WINDOW_NORMAL 用户可以改变这个窗口大小
	WINDOW_OPENGL 窗口创建的时候会支持OpenGL
	*/
	cv::namedWindow("测试", cv::WINDOW_AUTOSIZE);//新建一个显示窗口
	cv::imshow("测试", img);//在“测试”这个窗口输出图片。
	cv::waitKey(2000); //等待2秒

	cv::Mat output;
	//Convert Color
	cv::cvtColor(img, output, cv::COLOR_BGR2GRAY);//将img的bgr转为灰色 存到output
	cv::imshow("测试", output);//显示output
	cv::waitKey(5000);//等待5秒

	cv::Mat output2;
	output2 = cv::Scalar(255,255,255);//rgb颜色 会将output2 画成一个纯色图
	cv::imshow("测试", output2);//显示output2
	cv::waitKey(5000);//等待5秒
	
	cv::imwrite("d:/test.jpg", output);//保存output到test.jpg
}

掩膜操作

cv::Mat img = cv::imread("C:/test.jpg");
	if (img.empty()) {
		printf_s("找不到图片\n");
		return -1;
	}

	cv::namedWindow("测试", cv::WINDOW_AUTOSIZE);//新建一个显示窗口
	cv::imshow("测试", img);//在“测试”这个窗口输出图片。
	cv::waitKey(2000);

	cv::Mat BGR(1080, 1920, CV_8UC3, cv::Scalar(0, 180, 255));
	cv::imshow("测试", BGR);
	cv::waitKey(2000);




	cv::Mat output = cv::Mat::zeros(img.size(), img.type());//用来存储修改过的
	//获取像素指针
	/*
	Mat.ptr<uchar>(int i=0) //获取像素矩阵的指针,索引i表示第几行,从0开始
	P(row,col) //获取当前像素点 P(row,col) = Mat.ptr<uchar>(row)[col]
	//说白了就是个二维矩阵,程序里可以说是2级指针
	
	矩阵的掩膜操作
	根据掩膜重新计算每个像素的像素值 可以提高图像的对比度
	对比度公式
	img(row,col) = 5 * img(row,col)-[img(row-1,col)+img(row+1,col)+img(row,col-1)+img(row,col+1)]
	类似这样:
	0 -1 0
	-1 5 -1
	0 -1 0
	*/
	//我们现在就是手动的进行卷积运算,下面还有API可以很方便的操作
	//img.cols 就是宽度 1920,channels就是3,代表3个通道 rgb
	//*3的原因是我们获取到的其实是uchar 所以是8个bit,每个像素rgb是24bit(r、g、b各占8bit),所以我们需要*通道数
	int cols = (img.cols - 1) * img.channels(); 
	int rows = img.rows;
	int channels = img.channels();
	for (int row = 1; row < rows - 1; row++) {
		const uchar* previous = img.ptr<uchar>(row - 1);//上一行
		const uchar* current = img.ptr<uchar>(row);//当前行
		const uchar* next = img.ptr<uchar>(row + 1);//下一行
		uchar* outputCurrent = output.ptr<uchar>(row);//用于输出的
		for (int col = channels; col < cols; col++) {
			//保存到输出mask中
			/*
			saturate_cast<uchar> 就是最小不低于0 最大不超过255
			saturate_cast<type> 就是取type的最小或最大值,不能超过范围
			类似 math.max(math.min(value,255),0)
			*/
			outputCurrent[col] = cv::saturate_cast<uchar>(5 * current[col] - (current[col - channels] + current[col + channels] + previous[col] + next[col]));
		}
	}
	std::cout << img.size() << "changed!\n";
	cv::imshow("测试", output);
	cv::waitKey(2000);

用filter2D实现

下面这个效果相同,filter2D 就可以实现上面复杂的操作

	//filter2D 默认锚点为-1,-1
	cv::Mat kernel = (cv::Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	//img.depth() 位图深度 enum{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6} 
	cv::filter2D(img, output, img.depth(), kernel);
	cv::imshow("测试", output);//在“测试”这个窗口输出图片。
	cv::waitKey(2000);

3通道转4通道(也就是带透明度的图片)

	Mat src = imread("C:/test.jpg");
	vector<Mat> rgb3Channels(3); //申请一个mat的vector 用来存放split后的矩阵信息
	split(src, rgb3Channels);//将src进行分割,并存放在rgb3Channels
 
 
	Mat zero_mat= Mat::zeros(Size(src.cols, src.rows), CV_8UC1); //申请一个单通道全0矩阵

 
	vector<Mat> channels_4; //为merge做准备
	//注意 顺序是bgr
	channels_4.push_back(rgb3Channels[0]);	//b 这里存放的属于 src整个矩阵所有的b信息,下面相同
	channels_4.push_back(rgb3Channels[1]);	//g
	channels_4.push_back(rgb3Channels[2]);	//r
	channels_4.push_back(zero_mat);			//alpha=0
 
	Mat img_alpha_0;
	merge(channels_4, img_alpha_0); //channels_4是我们组合好的,但它是vector,我们需要合并,其实就是对应split的原理,说白了就是转成4通道矩阵

	imshow("img_alpha_0", img_alpha_0);
	waitKey(0);

常用API

  • 亮度对比度调节
    公式:
    float alpha = 1.2 //对比度
    float beta = 30 //亮度
    dst.at(row,col)[0] = saturate_cast(srcB * alpha + beta)
  • 均值模糊
    blur(Mat src,Mat dst,Size(x,y),Point(-1,-1));
    Size其实是kernel的大小,不是图像大小
    Point(-1,-1) 锚点位置
  • 高斯模糊
    GaussianBlur(Mat src,Mat dst,Size(x,y),sigmax,sigmay);
  • putText 文字
  • line 画线
  • rectangle 方框
  • ellipse 椭圆
  • circle 圆圈
  • fillPoly 填充
  • 线性混合
    f0为第一张图像,f1为第二章图像
    x为像素
    当x变化时,让2张图片的像素值相加,取值范围在1-0
    void cv::addWeighted(
    InputArray src1, //图像1
    double alpha, //图像1的alpha值
    InputArray src2,//图像2
    double beta,//图像2的alpha直 ,一般是用(1-第一张图的alpha)来算
    double gamma,//gamma值
    InputArray dst, //用来保存输出的图像
    int dtype = -1//输出混合图像
    )
    计算原理就是
    dst[i] = saturate_cast(src1[i] * alpha + src2[i] * beta + gamma)
    还有add,multiply等方法,建议不要使用,效果非常差
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

没事干写博客玩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值