OpenCV之C++入门
1、Visual Studio安装及环境配置与搭建
-
下载地址:https://my.visualstudio.com/Downloads?q=Visual,下载后按照说明安装即可
登录账号下载即可,建议下载Visual Studio 2017 专业版,本教程使用该版本完成
该教程笔记是本人整理的OpenCV学堂视频教程内容,感谢贾志刚老师的视频教程,下面是OpenCV 4.5.4及源码下载链接
链接:https://pan.baidu.com/s/1HmWrX35P774rr6tlfUXB2A 提取码:urtd
-
配置系统环境变量,鼠标右键我的电脑,选择属性,之后按下图操作,复制opencv目录下的bin目录,vs2017选择vc15
-
安装完毕后,新建第一个项目如下图
-
右键源文件选择新建项新建一个main.cpp
-
添加包含目录、库目录及附加依赖项
-
在D盘下新建一个images文件夹,放入一张图片,图片名与下面代码段中的图片名字一致
-
在main.cpp中输入以下代码
#include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { Mat src = imread("D:/images/lena.jpg"); imshow("input", src); waitKey(0); destroyAllWindows(); return 0; }
-
点击
调试
→开始调试
,如果出现下图则表示运行成功,配置成功
至此,Visual Studio的准备工作完成!
2、图像基本操作
多行注释快捷键:Ctrl + K + Ctrl + C
2.1、图像读取与显示
#include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { //imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 Mat src = imread("D:/images/lena.jpg",IMREAD_GRAYSCALE); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()){ printf("could not load image.../n"); return -1; } namedWindow("输入窗口",WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名,imshow()只支持显示8位图像及浮点图像 waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
2.2、图像色彩空间转换
新建一个头文件quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); };
添加该项目包含目录为当前文件夹,操作如下
新建一个源文件quickdemo.cpp
#include<quickopencv.h> void QuickDemo::colorSpace_Demo(Mat &image) { Mat gray, hsv; cvtColor(image, hsv, COLOR_BGR2HSV); // H 0~180 S 0~255 V 0~255 cvtColor(image, gray, COLOR_BGR2GRAY); imshow("HSV", hsv); imshow("灰度", gray); imwrite("D:/images/hsv.png", hsv); imwrite("D:/images/gray.png", gray); }
修改源文件test440,进行调试
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { //imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 //引入类QuickDemo,调用方法 QuickDemo qd; qd.colorSpace_Demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.3、图像对象的创建与赋值
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); };
quickdemo.cpp
#include<quickopencv.h> void QuickDemo::colorSpace_Demo(Mat &image) { Mat gray, hsv; cvtColor(image, hsv, COLOR_BGR2HSV); // H 0~180 S 0~255 V 0~255 cvtColor(image, gray, COLOR_BGR2GRAY); imshow("HSV", hsv); imshow("灰度", gray); imwrite("D:/images/hsv.png", hsv); imwrite("D:/images/gray.png", gray); } void QuickDemo::mat_creation_demo() { //克隆和复制才会创建新的对象,赋值不会创建新的对象 //Mat m1, m2; //m1 = image.clone(); //image.copyTo(m2); // 创建空白图像 Mat m3 = Mat::ones(Size(512, 512), CV_8UC3); m3 = Scalar(127, 127, 127); // 为像素赋予指定的值 B,G,R顺序 std::cout << "width: " << m3.cols << " height: " << m3.rows << " channels: " << m3.channels() << std::endl; //std::cout << m3 << std::endl; Mat m4 = m3; //赋值后m4改变,会引起m3改变,clone或copyTo则会创建新对象,不影响原对象 m4 = Scalar(0, 255, 255); imshow("创建图像", m3); Mat kernel = (Mat_<char>(3, 3) << 0,-1,0, // 3*3卷积核 -1,5,-1, 0,-1,0); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.mat_creation_demo(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.4、图像像素的读写操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); };
quickdemo.cpp
#include<quickopencv.h> void QuickDemo::pixel_visit_demo(Mat &image) { int w = image.cols; int h = image.rows; int dims = image.channels(); //for (int row = 0; row < h; row++) { // for (int col = 0; col < w; col++) { // if (dims == 1) { //灰度图像 // int pv = image.at<uchar>(row, col); //row,col → y,x // image.at<uchar>(row, col) = 255 - pv; //对像素值反转,image.at<uchar>为获取某点格式为uchar的像素值 // } // if (dims == 3) { //彩色图像 // Vec3b bgr = image.at<Vec3b>(row, col); //Vec3b为bgr图像像素点存储格式,对像素值进行反转 // image.at<Vec3b>(row, col)[0] = 255 - bgr[0]; // image.at<Vec3b>(row, col)[1] = 255 - bgr[1]; // image.at<Vec3b>(row, col)[2] = 255 - bgr[2]; // } // } //} for (int row = 0; row < h; row++) { uchar* current_row = image.ptr<uchar>(row); //获取当前行最初位置的指针 for (int col = 0; col < w; col++) { if (dims == 1) { //灰度图像 int pv = *current_row; *current_row++ = 255 - pv; //每次运算完,指针右移一位 } if (dims == 3) { //彩色图像 *current_row++ = 255 - *current_row; //由于bgr图像矩阵是连续的,所以指针直接指向下一位 *current_row++ = 255 - *current_row; *current_row++ = 255 - *current_row; } } } imshow("像素读写演示", image); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.pixel_visit_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.5、图像像素的算数操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); };
quickdemo.cpp
#include<quickopencv.h> void QuickDemo::operators_demo(Mat &image) { Mat dst; Mat m = Mat::zeros(image.size(), image.type()); m = Scalar(2, 2, 2); //Scalar标量 //dst = image + Scalar(50, 50, 50); //dst = image - Scalar(50, 50, 50); //dst = image / Scalar(2, 2, 2); //加法手写实现,主要使用saturate_cast函数,运算可使用对应函数快速实现 /* int w = image.cols; int h = image.rows; int dims = image.channels(); for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { Vec3b p1 = image.at<Vec3b>(row, col); Vec3b p2 = m.at<Vec3b>(row, col); //saturate_cast函数,将大于255的数转换为255,小于0的数转换为0 dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]); dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]); dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]); } } imshow("加法操作", dst); */ //add(image, m, dst); //add(操作的图,对图片操作的参数,输出的结果) //subtract(image, m, dst); //减法 //divide(image, m, dst); //除法 multiply(image, m, dst); //乘法 //imshow("加法操作", dst); //imshow("减法操作", dst); //imshow("除法操作", dst); imshow("乘法操作", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/dark_face.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.operators_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.6、使用滚动条调整图像亮度(TrackBar)
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); };
quickdemo.cpp
Mat src, dst, m; int lightness = 50; //回调函数两个形参,第一个int为createTrackbar中当前滑块所在位置,初始为lightness,第二个为userdata,为createTrackbar最后一个参数,默认为0 static void on_track(int, void*) { m = Scalar(lightness, lightness, lightness); add(src, m, dst); imshow("亮度调整", dst); } void QuickDemo::tracking_bar_demo(Mat &image) { namedWindow("亮度调整", WINDOW_AUTOSIZE); dst = Mat::zeros(image.size(), image.type()); m = Mat::zeros(image.size(), image.type()); src = image; int max_value = 100; //createTrackbar(滑动条名,滑动条所在的窗口,滑动块初始位置,滑动条最大值,回调函数(滑块滑动时的处理)) createTrackbar("Value Bar:", "亮度调整", &lightness, max_value, on_track); on_track(50, 0); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/dark_face.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.tracking_bar_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.7、滚动条操作-通过参数传递度
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); };
quickdemo.cpp 对上一节函数优化
//回调函数两个形参,第一个int为createTrackbar中的当前滑块所在位置,第二个为userdata,为createTrackbar最后一个参数,默认为0 static void on_lightness(int b, void* userdata) { Mat image = *((Mat*)userdata); //指针转换成Mat类型数据 Mat dst = Mat::zeros(image.size(), image.type()); Mat m = Mat::zeros(image.size(), image.type()); addWeighted(image, 1.0, m, 0, b, dst); //dst = image*1.0 + m*0 + b imshow("亮度与对比度调整", dst); } static void on_contrast(int b, void* userdata) { Mat image = *((Mat*)userdata); //指针转换成Mat类型数据 Mat dst = Mat::zeros(image.size(), image.type()); Mat m = Mat::zeros(image.size(), image.type()); double contrast = b / 100.0; //addWeighted()函数可以实现两张图片混合 addWeighted(image, contrast, m, 0, 0, dst); //dst = image*contrast + m*0 + 0 imshow("亮度与对比度调整", dst); } void QuickDemo::tracking_bar_demo(Mat &image) { namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE); int lightness = 50; int light_max_value = 100; int contrast_value = 100; int contrast_max = 200; //createTrackbar(滑动条名,滑动条所在的窗口,滑动块初始位置,滑动条最大值,回调函数(滑块滑动时的处理),userdata(传递给回调函数的数据)) createTrackbar("Value Bar:", "亮度与对比度调整", &lightness, light_max_value, on_lightness, (void*)(&image)); createTrackbar("Contrast Bar:", "亮度与对比度调整", &contrast_value, contrast_max, on_contrast, (void*)(&image)); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/dark_face.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.tracking_bar_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.8、滚动条操作-键盘响应操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::key_demo(Mat &image) { Mat dst = Mat::zeros(image.size(), image.type()); while (true) { int c = waitKey(1); //waitKey(图像刷新时间间隔)不断刷新图像,刷新间隔时间为1ms,视频处理时尽量设置1ms if (c == 27) { // 退出 break; } if (c == 49) { // Key #1 cvtColor(image, dst, COLOR_BGR2GRAY); imshow("键盘响应01", dst); } if (c == 50) { // Key #2 cvtColor(image, dst, COLOR_BGR2HSV); imshow("键盘响应02", dst); } if (c == 51) { // Key #3 dst = Scalar(50, 50, 50); add(image, dst, dst); imshow("键盘响应03", dst); } //imshow("键盘响应", dst); } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.key_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.9、OpenCV自带颜色表操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::color_style_demo(Mat &image) { int colormap[] = { COLORMAP_AUTUMN, COLORMAP_BONE, COLORMAP_JET, COLORMAP_WINTER, COLORMAP_RAINBOW, COLORMAP_OCEAN, COLORMAP_SUMMER, COLORMAP_SPRING, COLORMAP_COOL, COLORMAP_PINK, COLORMAP_HOT, COLORMAP_PARULA, COLORMAP_MAGMA, COLORMAP_INFERNO, COLORMAP_PLASMA, COLORMAP_VIRIDIS, COLORMAP_CIVIDIS, COLORMAP_TWILIGHT, COLORMAP_TWILIGHT_SHIFTED }; Mat dst; int index = 0; while (true) { int c = waitKey(2000); if (c == 27) { break; } applyColorMap(image, dst, colormap[index%19]); index++; imshow("颜色风格", dst); } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.color_style_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.10、图像像素的逻辑操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::bitwise_demo(Mat &image) { Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3); Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3); //rectangle()函数第四个参数小于0表示填充,大于0表示绘制 //rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), 2, LINE_8, 0); //rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), 2, LINE_8, 0); rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0); rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0); imshow("m1", m1); imshow("m2", m2); Mat dst; //bitwise_and(m1, m2, dst); //bitwise_or(m1, m2, dst); //dst = ~image; //也可以实现图像取反操作 //bitwise_not(image, dst); //当前图像取反操作 bitwise_xor(m1, m2, dst); //异或((非m1 与 m2) 或 (m1 与 非m2)),相当于 m1或m2,相交的部分(非(m1 与 m2)) imshow("像素位操作", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.bitwise_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.11、通道分离与合并
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::channels_demo(Mat &image) { std::vector<Mat> mv; //Mat数组 split(image, mv); imshow("蓝色", mv[0]); imshow("绿色", mv[1]); imshow("红色", mv[2]); Mat dst; //mv[1] = 0; //mv[2] = 0; //merge(mv, dst); //imshow("蓝色", dst); //mv[0] = 0; //mv[2] = 0; //merge(mv, dst); //imshow("绿色", dst); mv[0] = 0; mv[1] = 0; merge(mv, dst); imshow("红色", dst); //from_to[]复制列表 int from_to[] = { 0,2,1,1,2,0 }; //通道0复制到通道2,通道1复制到通道1,通道2复制到通道0 //mixChannels(输入矩阵,输入矩阵数量,输出矩阵,输出矩阵数量,复制列表,复制列表中复制几次) mixChannels(&image, 1, &dst, 1, from_to, 3); imshow("通道混合", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.channels_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.12、图像色彩空间转换
HSV颜色空间表
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::inrange_demo(Mat &image) { Mat hsv; cvtColor(image, hsv, COLOR_BGR2HSV); Mat mask; inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask); imshow("mask01", mask); Mat redback = Mat::zeros(image.size(), image.type()); redback = Scalar(40, 40, 200); bitwise_not(mask, mask); //像素逻辑运算,mask取反 imshow("mask02", mask); //image.copyTo(拷贝到的图像,mask为1的部分拷贝为0的部分不拷贝) image.copyTo(redback, mask); //将image拷贝到其他图像中 imshow("roi区域提取", redback); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.inrange_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.13、图像像素值统计
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::pixel_statistic_demo(Mat &image) { double minv, maxv; Point minLoc, maxLoc; Mat mean, stddev; std::vector<Mat> mv; split(image, mv); for (int i = 0; i < mv.size(); i++) { //第一个参数需要是单通道的图像,可以先把多通道分离;最后一个参数为mask minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat()); std::cout << "No.channels: " << i << " min value: " << minv << " max value: " << maxv << std::endl; //第一个参数是单通道图像则计算一组均值、方差,如果是多通道图像,则同时计算多组均值、方差 meanStdDev(mv[i], mean, stddev); std::cout << "means: " << mean << std::endl; std::cout << "stddev: " << stddev << std::endl; } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.pixel_statistic_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.14、图像几何形状绘制,随机数与随机颜色
基本绘图
1 Point: 2 Point pt; 3 pt.x = 10; 4 pt.y = 8; 5 或者 6 Point pt = Point(10, 8); 7 8 Scalar: 9 Scalar( B, G, R ) //定义的RGB颜色值为:Blue,Green, Red 10 11 line 绘直线: 12 line( img, //输出图像 13 start, //起始点 14 end, //结束点 15 Scalar( 0, 0, 0 ), //颜色 16 thickness=2, //线条粗细 17 lineType=8 ); //线条类型 18 19 ellipse 绘椭圆: 20 ellipse( img, //输出图像 21 Point( w/2.0, w/2.0 ), //中心为点 (w/2.0, w/2.0) 22 Size( w/4.0, w/16.0 ), //大小位于矩形 (w/4.0, w/16.0) 内 23 angle, //旋转角度为 angle 24 0, 25 360, //扩展的弧度从 0 度到 360 度 26 Scalar( 255, 0, 0 ), //颜色 27 thickness, //线条粗细 28 lineType ); //线条类型 29 30 circle 绘圆: 31 circle( img, //输出图像 32 center, //圆心由点 center 定义 33 w/32.0, /圆的半径为: w/32.0 34 Scalar( 0, 0, 255 ), //颜色 35 thickness, //线条粗细 36 lineType ); //线条类型 37 38 rectangle 绘矩形: 39 rectangle( rook_image, 40 Point( 0, 7*w/8.0 ), 41 Point( w, w), //矩形两个对角顶点为 Point( 0, 7*w/8.0 ) 和 Point( w, w) 42 Scalar( 0, 255, 255 ), 43 thickness = -1, 44 lineType = 8 ); 45 46 fillPoly 绘填充的多边形: 47 fillPoly( img, 48 ppt, //多边形的顶点集为 ppt 49 npt, //要绘制的多边形顶点数目为 npt 50 1, //要绘制的多边形数量仅为 1 51 Scalar( 255, 255, 255 ), 52 lineType );
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); };
quickdemo.cpp
void QuickDemo::form_paint_random() { Mat image_line = Mat::zeros(512, 512, CV_8UC3); //新建两个512*512的三通道矩阵 Mat image_rect = Mat::zeros(512, 512, CV_8UC3); Rect rect; //新建一个矩形对象 RNG rng(0xFFFFFF); //生成随机数的类RNG,随机数产生器,用数值0xFFFFFF来实例化一个RNG对象 image_line.setTo(Scalar(0, 0, 0)); //将图像使用另一种颜色覆盖 image_rect.setTo(Scalar(0, 0, 0)); //将图像使用另一种颜色覆盖 for (int i = 0; i < 100000; i++) { int x1 = rng.uniform(0, 512); //获取[0,512)的均匀分布的随机数 int y1 = rng.uniform(0, 512); int x2 = rng.uniform(0, 512); int y2 = rng.uniform(0, 512); int b = rng.uniform(0, 256); int g = rng.uniform(0, 256); int r = rng.uniform(0, 256); //void line(绘制线段的图像,起点坐标,终点坐标,线段的颜色通过Scalar()定义,线段的宽度(线宽为负数时表示填充),线段的类型,坐标点小数点位数) line(image_line, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, LINE_AA, 0); //线段的类型。可以取值LINE_8,LINE_4和LINE_AA,分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用LINE_AA(采用了高斯滤波)。 imshow("image_line", image_line); rect.x = x1; //定义矩形的左上顶点坐标及宽高 rect.y = y1; rect.width = x2 - x1; rect.height = y2 - y1; rectangle(image_rect, rect, Scalar(b, g, r), 1, LINE_AA, 0); imshow("image_rect", image_rect); char c = waitKey(20); if (c == 27) break; } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.form_paint_random(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.15、多边形填充与绘制
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); };
quickdemo.cpp
void QuickDemo::polyline_drawing_demo() { Mat canvas01 = Mat::zeros(Size(512, 512), CV_8UC3); Mat canvas02 = 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); std::vector<Point> pts; pts.push_back(p1); pts.push_back(p2); pts.push_back(p3); pts.push_back(p4); pts.push_back(p5); fillPoly(canvas01, pts, Scalar(255, 255, 0), 8, 0); //polylines(绘制所在图像,要绘制的顶点集合,图形是否闭合,线的颜色,线宽,线的类型) //polylines(canvas, pts, true, Scalar(0, 0, 255), 3, LINE_8, 0); //不能设置线宽为负数进行填充 polylines(canvas01, pts, true, Scalar(0, 0, 255), 3, LINE_AA, 0); //使用LINE_AA抗锯齿 std::vector<std::vector<Point>> contours; contours.push_back(pts); //drawContours(绘制所在的图像,绘制的点集的集合,绘制第几个点集-1表示全部绘制,线段颜色,线宽-1表示填充) drawContours(canvas02, contours, -1, Scalar(255, 0, 0), -1); imshow("多边形绘制01", canvas01); imshow("多边形绘制02", canvas02); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.polyline_drawing_demo(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.16、鼠标操作与响应
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); };
quickdemo.cpp
Point sp(-1, -1); //起点 Point ep(-1, -1); //终点 //新建一个temp矩阵保存原图像,没有绘制的 Mat temp; 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; std::cout << "start point: " << sp << std::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); //去除绘制目标区域的边框 imshow("ROI区域", image(box)); //将绘制区域中的图像单独显示出来 rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); imshow("鼠标绘制", image); //ready for next drawing sp.x = -1; sp.y = -1; } } 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); } } } } void QuickDemo::mouse_drawing_demo(Mat &image) { namedWindow("鼠标绘制", WINDOW_AUTOSIZE); setMouseCallback("鼠标绘制", on_draw, (void*)(&image)); imshow("鼠标绘制", image); temp = image.clone(); //将加载的原图克隆到临时矩阵temp中 }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.mouse_drawing_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.17、图像像素类型转换与归一化
图像为什么要进行归一化:
归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在某个区间上是统计的坐标分布。归一化有同一、统一和合一的意思。
归一化的目的简而言之,是使得没有可比性的数据变得具有可比性,同时又保持相比较的两个数据之间的相对关系,如大小关系;或是为了作图,原来很难在一张图上作出来,归一化后就可以很方便的给出图上的相对位置等。
四种归一化方式:
其中的NORM_L2计算方式实例如下公式,其他归一化方式根据图片中的内容即可理解
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); };
quickdemo.cpp
//image.type()返回的数值与类型对应关系,第一行为通道数,第一列为数据类型 +--------+----+----+----+----+------+------+------+------+ | | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) | +--------+----+----+----+----+------+------+------+------+ | CV_8U | 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 | | CV_8S | 1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 | | CV_16U | 2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 | | CV_16S | 3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 | | CV_32S | 4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 | | CV_32F | 5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 | | CV_64F | 6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 | +--------+----+----+----+----+------+------+------+------+ void QuickDemo::norm_demo(Mat &image) { Mat dst; std::cout << image.type() << std::endl; image.convertTo(image, CV_32F); //将8UC3 Integer数据转换成32F float数据,以便用于后续归一化操作 std::cout << image.type() << std::endl; //值归一化与范围归一化:值归一化L1,L2,MINMAX;范围归一化可以自己设置归一化范围如[0,255] //normalize(输入数组,输出数组,1用来规范值2规范范围下限,0值归一化其他范围归一化上限,归一化选择的数学公式类型) normalize(image, dst, 1.0, 0, NORM_MINMAX); //转换为浮点数类型后必须进行归一化操作 std::cout << dst.type() << std::endl; imshow("图像数据归一化前", image); imshow("图像数据归一化后", dst); //CV_8UC3, CV_32FC3 }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.norm_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.18、图像放缩与插值
OpenCV图像放缩的五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。
1、最近邻:选取离目标点最近的点作为新的插入点;
2、双线性:由相邻的四像素(2 * 2)计算得出;
-
原理公式及矩阵
-
计算过程示意图
3、双三次:由相邻的4 * 4像素计算得出,公式类似于双线性插值;
4、基于像素区域关系:共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现;
5、兰索斯插值:由相邻的8 * 8像素计算得出,公式类似于双线性
总结:
- 速度比较:INTER_NEAREST(最近邻插值)>INTER_LINEAR(双线性插值)>INTER_CUBIC(三次样条插值)>INTER_AREA(区域插值)
- OpenCV推荐:如果要缩小图像,通常推荐使用 INTER_AREA插值效果最好;而要放大图像,通常使用 INTER_CUBIC(速度较慢,但效果最好),或者使用 INTER_LINEAR(速度较快,效果还可以)。至于最近邻插值 INTER_NEAREST,一般不推荐使用
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::resize_demo(Mat &image) { Mat zoomin, zoomout; int h = image.rows; int w = image.cols; //resize(输入图像,输出图像,大小变换方法Size(),x方向缩放系数,y方向缩放系数,插值算法) //如果size有值,使用size做放缩插值,否则根据fx与fy卷积 resize(image, zoomin, Size(w / 2, h / 2), 0, 0, INTER_LINEAR); imshow("zoomin", zoomin); resize(image, zoomout, Size(w * 1.5, h * 1.5), 0, 0, INTER_LINEAR); imshow("zoomout", zoomout); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.resize_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.19、图像翻转
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::flip_demo(Mat &image) { Mat dst; flip(image, dst, 0); //上下翻转 imshow("图像上下翻转", dst); flip(image, dst, 1); //左右翻转 imshow("图像左右翻转", dst); flip(image, dst, -1); //180°旋转 imshow("图像180°翻转", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.flip_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.20、图像旋转
公式:
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::rotate_demo(Mat &image) { Mat dst, M; int w = image.cols; int h = image.rows; M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0); double cos = abs(M.at<double>(0, 0)); double sin = abs(M.at<double>(0, 1)); int nw = cos * w + sin * h; int nh = sin * w + cos * h; M.at<double>(0, 2) += (nw / 2 - w / 2); M.at<double>(1, 2) += (nh / 2 - h / 2); warpAffine(image, dst, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 255, 0)); imshow("旋转展示", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.rotate_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.21、视频文件摄像头使用
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::video_demo(Mat &image) { //VideoCapture capture(0); //获取当前设备摄像头视频 VideoCapture capture("D:/images/video/example.mp4"); //获取该地址下的视频 Mat frame; while (true) { capture.read(frame); int h = frame.rows; //获取视频每一帧的宽高 int w = frame.cols; //flip(frame, frame, 1); //摄像头需要翻转,视频不需要翻转 if (frame.empty()) { break; } resize(frame, frame, Size(w / 4, h / 4), 0, 0, INTER_LINEAR); //缩放视频 imshow("frame", frame); //显示缩放后的视频 colorSpace_Demo(frame); //调用色彩空间转换函数,将视频转换为灰度图像及HSV图像并显示 // TODO: do something.... int c = waitKey(10); if (c == 27) { //退出 break; } } //release capture.release(); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.video_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.22、视频处理与保存
分辨率清晰度对照:
视频显示格式 | 分辨率尺寸名 | 汉语简称 |
---|---|---|
480p、576p | SD(Standard Definition) | 标清 |
720p | HD(High Definition) | 高清 |
1080p | FHD(Full High Definition) | 全高清 |
2k | QHD(Quad High Definition) | 四倍HD |
4k | UHD(Ultra High Definition) | 超高清 或 4k UHD |
8k | FUHD(Full Ultra High Definition) | 8k超高清 或 8k UHD |
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::video_demo(Mat &image) { //VideoCapture capture(0); //获取当前设备摄像头视频 VideoCapture capture("D:/images/video/example.mp4"); //获取该地址下的视频 int frame_width = capture.get(CAP_PROP_FRAME_WIDTH); //获取视频帧的宽高 int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT); int count = capture.get(CAP_PROP_FRAME_COUNT); //获取视频的全部帧数 double fps = capture.get(CAP_PROP_FPS); //获取视频每秒帧数fps std::cout << "frame width: " << frame_width << std::endl; std::cout << "frame height: " << frame_height << std::endl; std::cout << "FPS: " << fps << std::endl; std::cout << "Number of Frames: " << count << std::endl; int fourcc = VideoWriter::fourcc('a','v','c','1'); //H264编码格式的fourcc code //VideoWriter writer(保存地址,fourcc编码格式code,帧率,保存视频的画面宽高,是否是彩色); VideoWriter writer("D:/test.mp4", fourcc, fps, Size(frame_width, frame_height), true); Mat frame; Mat frame1; while (true) { capture.read(frame); int h = frame.rows; //获取视频每一帧的宽高 int w = frame.cols; //flip(frame, frame, 1); //摄像头需要翻转,视频不需要翻转 if (frame.empty()) { break; } resize(frame, frame1, Size(w / 4, h / 4), 0, 0, INTER_LINEAR); //缩放视频 imshow("frame", frame1); //显示缩放后的视频 //colorSpace_Demo(frame); //调用色彩空间转换函数,将视频转换为灰度图像及HSV图像并显示 writer.write(frame); //将每一帧保存到新的文件中 // TODO: do something.... int c = waitKey(10); if (c == 27) { //退出 break; } } //release capture.release(); writer.release(); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.video_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
运行过程中缺少H264编码器:
1、出现错误
2、到给出的网站中下载对应的dll
文件
3、将该文件下载解压后放到opencv的bin目录下
4、再次运行正常
注意:H264
对应的fourcc code
为avc1
! 具体原因可以自行百度,与OpenCV遵守的开源协议有关
2.23、图像直方图
图像直方图解释:
图像直方图使图像像素值的统计学特征,计算代价较小,具有图像平移、旋转、缩放不变性等众多优点,广泛地应用域图像处理的各个领域,特别是灰度图像的阈值分割、基于颜色的图像检索以及图像分类、反向投影跟踪。常见的分为灰度直方图、颜色直方图。
Bins是指直方图的大小范围,对于像素值取在0~255之间的,最少有256个bin,此外还可以有16、32、48、128等,256除以bin的大小应该是整数倍。
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::histogram_demo(Mat &image) { //三通道分离 std::vector<Mat> bgr_plane; //定义Mat类型的集合,用来保存三通道数据 split(image, bgr_plane); //将图像三通道分离,保存到定义的集合中 //定义参数变量 const int channels[1] = { 0 }; const int bins[1] = { 256 }; float hranges[2] = { 0,255 }; const float* ranges[1] = { hranges }; Mat b_hist; Mat g_hist; Mat r_hist; //计算Blue,Green,Red通道的直方图 calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges); calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges); calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges); //显示直方图 int hist_w = 512; int hist_h = 400; int bin_w = cvRound((double)hist_w / bins[0]); Mat histImage = Mat::zeros(hist_h, hist_w,CV_8UC3); //归一化直方图数据 normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); //绘制直方图曲线 for (int i = 1; i < bins[0]; i++) { line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA, 0); line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA, 0); line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA, 0); } //显示直方图 namedWindow("Histogram Demo", WINDOW_AUTOSIZE); imshow("Histogram Demo", histImage); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.histogram_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.24、二维直方图
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::histogram_2d_demo(Mat &image) { //2D直方图 Mat hsv, hs_hist; cvtColor(image, hsv, COLOR_BGR2HSV); int hbins = 30, sbins = 32; int hist_bins[] = { hbins,sbins }; float h_range[] = { 0,180 }; float s_range[] = { 0,256 }; const float* hs_ranges[] = { h_range,s_range }; int hs_channels[] = { 0,1 }; calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false); double maxVal = 0; minMaxLoc(hs_hist, 0, &maxVal, 0, 0); int scale = 10; Mat hist2d_image = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3); Mat hist2d_image_back = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3); for (int h = 0; h < hbins; h++) { for (int s = 0; s < sbins; s++) { float binVal = hs_hist.at<float>(h, s); int intensity = cvRound(binVal * 255 / maxVal); rectangle(hist2d_image, Point(h*scale, s*scale), Point((h + 1)*scale - 1, (s + 1)*scale - 1), Scalar::all(intensity), -1); } } applyColorMap(hist2d_image, hist2d_image_back, COLORMAP_JET); imshow("H-S Histogram", hist2d_image); imshow("H-S Histogram_back", hist2d_image_back); imwrite("D:/hist_2d.png", hist2d_image); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.histogram_2d_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.25、直方图均衡化
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); void histogram_eq_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::histogram_eq_demo(Mat &image) { Mat gray; cvtColor(image, gray, COLOR_BGR2GRAY); imshow("灰度图像", gray); Mat dst; equalizeHist(gray, dst); imshow("直方图均衡化演示", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.histogram_eq_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.26、图像卷积操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); void histogram_eq_demo(Mat &image); void blur_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::blur_demo(Mat &image) { Mat dst01, dst02, dst03, dst04, dst05; blur(image, dst01, Size(3, 3), Point(-1, -1)); blur(image, dst02, Size(13, 13), Point(-1, -1)); blur(image, dst03, Size(23, 23), Point(-1, -1)); blur(image, dst04, Size(13, 1), Point(-1, -1)); blur(image, dst05, Size(1, 13), Point(-1, -1)); imshow("图像模糊01", dst01); imshow("图像模糊02", dst02); imshow("图像模糊03", dst03); imshow("图像模糊04", dst04); imshow("图像模糊05", dst05); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.blur_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.27、高斯模糊
高斯模糊计算公式:
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); void histogram_eq_demo(Mat &image); void blur_demo(Mat &image); void gaussian_blue_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::gaussian_blue_demo(Mat &image) { Mat dst01, dst02, dst03; GaussianBlur(image, dst01, Size(5, 5), 15); GaussianBlur(image, dst02, Size(3, 3), 15); GaussianBlur(image, dst03, Size(0, 0), 15); imshow("高斯模糊01",dst01); imshow("高斯模糊02",dst02); imshow("高斯模糊03",dst03); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.gaussian_blue_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.28、高斯双边模糊
双边滤波原理:
-
空间距离:当前点距离滤波模板中心点的欧式距离。
-
灰度距离:当前点距离滤波模板中心点的灰度的差值的绝对值。
双边滤波的核函数是空间域核与像素范围域核的综合结果:
-
在图像的平坦区域,像素值变化很小,那么像素差值接近于0,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;
-
在图像的边缘区域,像素值变化很大,那么像素差值大,对应的像素范围域权重变大,即使距离远空间域权重小,加上像素域权重总的系数也较大,从而保护了边缘的信息。
双边滤波在突变的边缘上,使用了像素差权重,很好的保留了边缘。
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); void histogram_eq_demo(Mat &image); void blur_demo(Mat &image); void gaussian_blue_demo(Mat &image); void bifilter_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::bifilter_demo(Mat &image) { Mat dst; bilateralFilter(image, dst, 0, 100, 10); imshow("双边模糊", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.bifilter_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
3、案例:实时人脸识别
先下载三个文件置于opencv的face_detector路径下:D:/environment/opencv/sources/samples/dnn/face_detector
下载地址及文件如下:
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); void rotate_demo(Mat &image); void video_demo(Mat &image); void histogram_demo(Mat &image); void histogram_2d_demo(Mat &image); void histogram_eq_demo(Mat &image); void blur_demo(Mat &image); void gaussian_blue_demo(Mat &image); void bifilter_demo(Mat &image); void face_detection_demo(); };
quickdemo.cpp
#include<quickopencv.h> #include<opencv2/dnn.hpp> using namespace cv; using namespace std; void QuickDemo::face_detection_demo() { std::string root_dir = "D:/environment/opencv/sources/samples/dnn/face_detector/"; dnn::Net net = dnn::readNetFromTensorflow(root_dir + "opencv_face_detector_uint8.pb", root_dir + "opencv_face_detector.pbtxt"); VideoCapture capture("D:/images/video/example_dsh.mp4"); Mat frame; while (true) { capture.read(frame); if (frame.empty()) { break; } Mat blob = dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false); net.setInput(blob); //NCHW Mat probs = net.forward(); Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>()); //解析结果 for (int i = 0; i < detectionMat.rows; i++) { float confidence = detectionMat.at<float>(i, 2); if (confidence > 0.5) { int x1 = static_cast<int>(detectionMat.at<float>(i, 3)*frame.cols); int y1 = static_cast<int>(detectionMat.at<float>(i, 4)*frame.rows); int x2 = static_cast<int>(detectionMat.at<float>(i, 5)*frame.cols); int y2 = static_cast<int>(detectionMat.at<float>(i, 6)*frame.rows); Rect box(x1, y1, x2 - x1, y2 - y1); rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0); } } imshow("人脸检测演示", frame); //TODO: do something... int c = waitKey(1); if (c == 27) { //退出 break; } } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image.../n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.face_detection_demo(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果