本文共 4604 字,大约阅读时间需要 15 分钟。
- 下载OpenCV库
- 设置引用目录 \opencv\sources\include\opencv2
- 设置库目录(我用的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#include #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(int i=0) //获取像素矩阵的指针,索引i表示第几行,从0开始 P(row,col) //获取当前像素点 P(row,col) = Mat.ptr (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 (row - 1);//上一行 const uchar* current = img.ptr (row);//当前行 const uchar* next = img.ptr (row + 1);//下一行 uchar* outputCurrent = output.ptr (row);//用于输出的 for (int col = channels; col < cols; col++) { //保存到输出mask中 /* saturate_cast 就是最小不低于0 最大不超过255 saturate_cast 就是取type的最小或最大值,不能超过范围 类似 math.max(math.min(value,255),0) */ outputCurrent[col] = cv::saturate_cast (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 默认锚点为-1,-1 cv::Mat kernel = (cv::Mat_(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);
Mat src = imread("C:/test.jpg"); vectorrgb3Channels(3); //申请一个mat的vector 用来存放split后的矩阵信息 split(src, rgb3Channels);//将src进行分割,并存放在rgb3Channels Mat zero_mat= Mat::zeros(Size(src.cols, src.rows), CV_8UC1); //申请一个单通道全0矩阵 vector 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);
- 亮度对比度调节 公式: 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等方法,建议不要使用,效果非常差
转载地址:http://vtlsi.baihongyu.com/