这是一篇OpenCv4 C++版本入门的个人笔记,是B站课程30讲的部分笔记。代码中创建一个QuickDemo类,类中的每一个公有成员函数对应一个知识点。

分别有:1、将原图转为HSV和GRAY图像显示并保存;2、进行像素操作,加减乘除;3、滚动条调整亮度;4、键盘输入响应;5、改变图像颜色风格;6、像素逻辑运算;7、通道分离与合并;8、图像色彩空间转换;9、图像像素统计,最大最小值,均值方差;10、在图像中绘制几何图形;11、绘制多边形;12、鼠标响应,绘制矩形;13、像素类型转换与归一化;14、图像放缩;15、图像翻转;16、图像旋转;17、调用摄像头。

具体程序代码:

main.cpp

// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <opencv2\opencv.hpp>
#include "quickopencv.h"using namespace std;
using namespace cv;Mat img;int main(int argc,char** argv)
{img = imread("D:/exercise/opencv4/dog.jpeg");// 图像色彩空间转换用pig.jpgif (img.empty()){cout << "请确认图像名称是否正确!" << endl;return -1;}namedWindow("Original drawing", WINDOW_FREERATIO);imshow("Original drawing", img);QuickDemo qd;//qd.colorSpace_Demo(img);//将原图转为HSV和GRAY图像显示并保存//qd.operator_demo(img);//进行像素操作//qd.teacking_bar_demo(img);//滚动条调整亮度//qd.key_demo(img);//键盘输入响应//qd.color_style_demo(img);//改变图像颜色风格//qd.bitwise_demo(img);//图像像素逻辑操作//qd.channels_demo(img);//图像分离与合并//qd.inrange_demo(img); // 图像色彩空间转换//qd.pixel_static_demo(img);//图像像素统计,最大最小值,均值方差//qd.drawing_demo(img);//在图像中绘制几何图形//qd.polyline_drawing_demo();//绘制多边形//qd.mouse_drawing(img);使用鼠标绘制矩形//qd.norm_demo(img);//像素类型转换与归一化//qd.resize_demo(img);//图像放缩//qd.flip_demo(img);//图像翻转//qd.rotate_demo(img);//图像旋转qd.video_demo(img);//使用摄像头waitKey(0);
}

(注意:图片路径根据具体实际进行导入),可逐个调用各个类成员函数,进行OpenCv的学习。

quickopencv.cpp

#include "quickopencv.h"
#include <vector>void QuickDemo::colorSpace_Demo(Mat& image)
{Mat gray, hsv;cvtColor(image, hsv, COLOR_BGR2HSV);//HSV分别表示色度、饱和度和亮度cvtColor(image, gray, COLOR_BGR2GRAY);imshow("HSV drawing", hsv);imshow("GRAY drawing", gray);imwrite("D:/exercise/opencv4/HSVdog.jpeg", hsv);imwrite("D:/exercise/opencv4/GRAYdog.jpeg", gray);
}void QuickDemo::operator_demo(Mat& image)
{//加减乘除可以用,add()、subtract()、multiply()、divide()Mat dst;dst = image + Scalar(50, 50, 50);//这种情况下,对每个像素进行操作,像素值超过255会截断,值就为255imshow("加法操作",dst);//减法同理,在这不做展示了dst = image / Scalar(2, 2, 2);imshow("除法操作", dst);multiply(image, Scalar(2, 2, 2), dst);imshow("乘法操作", dst);//乘法,像素值超过255会截断,值就为255}//滑动条改变图像亮度--------------------------------------------------------------
int lightness;static void callBack(int b, void* usedata)
{Mat img = *((Mat*)usedata);float a = lightness / 100.0;Mat img1 = img * a;imshow("滑动条改变亮度", img1);
}void QuickDemo::teacking_bar_demo(Mat& image)
{namedWindow("滑动条改变亮度",WINDOW_AUTOSIZE);int max_value = 100;//亮度最大值为100int contrast_value = 2;lightness = 50;//当前亮度默认值//创建亮度滑动条createTrackbar("亮度百分比", "滑动条改变亮度", &lightness, max_value, callBack, (void*)(&image));//callBack(0, (void*)&image);
}
//----------------------------------------------------------------------------------void QuickDemo::key_demo(Mat& image)
{Mat dst;while (true){int c = waitKey(100);//Waitkey函数会有一个返回值,是返回ascii码值的if (c == 27)//按esc键退出{break;}//键盘按1时,转换为灰度图像并显示if (c == 49){std::cout << "You enyer key #1,Convert image to grayscale" << std::endl;cvtColor(image, dst, COLOR_BGR2GRAY);imshow("按1转换为灰度",dst);}}
}//利用ColormapTypes,进行颜色风格变化
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_HSV, COLORMAP_PINK ,COLORMAP_HOT ,COLORMAP_PARULA ,COLORMAP_MAGMA ,COLORMAP_INFERNO ,COLORMAP_PLASMA ,COLORMAP_VIRIDIS ,COLORMAP_CIVIDIS ,COLORMAP_TWILIGHT ,COLORMAP_TWILIGHT_SHIFTED ,COLORMAP_TURBO ,COLORMAP_DEEPGREEN };Mat dst;int index = 0;while (true){int c = waitKey(2000);//Waitkey函数会有一个返回值,是返回ascii码值的if (c == 27)//按esc键退出{break;}applyColorMap(image,dst, colormap[index++ % 21]);imshow("颜色风格变化", dst);}
}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(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1,LINE_8,0);//-1小于0是填充rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);imshow("m1", m1);imshow("m2", m2);//进行逻辑运算Mat myAnd, myOr, myXor, myNot;bitwise_not(m1, myNot);bitwise_and(m1, m2, myAnd);bitwise_or(m1, m2, myOr);bitwise_xor(m1, m2, myXor);imshow("myAnd", myAnd);imshow("myOr", myOr);imshow("myXor", myXor);imshow("myNot", myNot);
}void QuickDemo::channels_demo(Mat& image)
{std::vector<Mat> imgv;split(image, imgv);imshow("分离蓝色", imgv.at(0));  //或者用imgv[0],显示分离后Bimshow("分离绿色", imgv.at(1));  //或者用imgv[1],显示分离后Gimshow("分离红色", imgv.at(2));  //或者用imgv[2],显示分离后RMat dst;imgv.at(1) = 0;imgv.at(2) = 0;merge(imgv, dst);  //合并图像imshow("合并蓝色", dst);
}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("mask", mask);Mat redback = Mat::zeros(image.size(), image.type());redback = Scalar(40, 40, 200);bitwise_not(mask, mask);imshow("mask", mask);image.copyTo(redback, mask);imshow("roi区域提取", redback);
}void QuickDemo::pixel_static_demo(Mat& image)
{double minVal, maxVal;  //用于存放矩阵中的最大值和最小值Point minIdx, maxIdx;  //用于存放矩阵中的最大值和最小值在矩阵中的位置Mat imgs_re = image.reshape(1, 0);  //将多通道矩阵变成单通道矩阵minMaxLoc(imgs_re, &minVal, &maxVal, &minIdx, &maxIdx);std::cout << "img中最大值是:" << maxVal << "  " << "在矩阵中的位置:" << maxIdx << std::endl;std::cout << "img中最小值是:" << minVal << "  " << "在矩阵中的位置:" << minIdx << std::endl;std::cout << "/* 用meanStdDev同时求取图像的均值和标准差 */" << std::endl;Mat myMeanMat, myStddevMat;meanStdDev(image, myMeanMat, myStddevMat);std::cout << "img均值=" << myMeanMat << "    " << std::endl;std::cout << "img标准差=" << myStddevMat << std::endl ;}void QuickDemo::drawing_demo(Mat& image)
{//绘制矩形//rectangle(image, Point(200, 200), Point(300, 300), Scalar(125, 125, 125), -1);//-1为填充rectangle(image,Rect(400,450,100,150), Scalar(0, 125, 125), 2);//2为线宽,不填充Mat bg = Mat::zeros(image.size(), image.type());rectangle(bg, Point(200, 200), Point(300, 300), Scalar(0, 0, 255), -1);Mat dst;addWeighted(image, 0.7, bg, 0.3, 0, dst);imshow("dst", dst);//绘制圆circle(image, Point(100, 100), 50, Scalar(255, 255, 255), 3);//绘制直线line(image, Point(50, 50), Point(50, 200),Scalar(255,0,0), 2, LINE_4, 0);//绘制椭圆//这里的RotatedRect参数表示,中心点,长轴短轴,旋转角度ellipse(image, RotatedRect(Point2f(300, 300), Size2f(200, 100), 0), Scalar(0, 255, 255), 2);imshow("形状绘制", image);
}void QuickDemo::polyline_drawing_demo()
{//绘制多边形Mat img = Mat::zeros(Size(512, 512), CV_8UC3);  //生成一个黑色图像用于绘制几何图形Point pp[2][6];pp[0][0] = Point(72, 200);pp[0][1] = Point(142, 204);pp[0][2] = Point(226, 263);pp[0][3] = Point(172, 310);pp[0][4] = Point(117, 319);pp[0][5] = Point(15, 260);pp[1][0] = Point(359, 339);pp[1][1] = Point(447, 351);pp[1][2] = Point(504, 349);pp[1][3] = Point(484, 433);pp[1][4] = Point(418, 449);pp[1][5] = Point(354, 402);Point pp2[5];pp2[0] = Point(350, 83);pp2[1] = Point(463, 90);pp2[2] = Point(500, 171);pp2[3] = Point(421, 194);pp2[4] = Point(338, 141);const Point* pts[3] = { pp[0],pp[1],pp2 };  //pts变量的生成int npts[] = { 6,6,5 };  //顶点个数数组的生成fillPoly(img, pts, npts, 3, Scalar(125, 125, 125), 8);  //绘制3个多边形,填充//---------------------------------------------------------Point p1(100, 100);Point p2(350, 100);Point p3(450, 280);Point p4(320, 450);Point p5(80, 400);std::vector<Point> ptt;ptt.push_back(p1);ptt.push_back(p2);ptt.push_back(p3);ptt.push_back(p4);ptt.push_back(p5);polylines(img, ptt, true, Scalar(0, 0, 255), 2, 8, 0);imshow("绘制多边形", img);
}//鼠标响应,绘制矩形------------------------------------------------------
Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
static void on_draw(int event,int x,int y,int flags,void* userdata)
{Mat img = *((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;std::cout << "start point." << ep << std::endl;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);rectangle(img, box, Scalar(0, 125, 125), 2,8,0);//2为线宽,不填充imshow("鼠标绘制矩形", img);//imshow("ROI区域",img(box));//为下一次绘制做准备sp.x = -1;sp.y = -1;}}else if (event == EVENT_MOUSEMOVE){if (sp.x > 0 && sp.y > 0){ep.x = x;ep.y = y;std::cout << "start point." << ep << std::endl;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(img);rectangle(img, box, Scalar(0, 0, 255), 2, 8, 0);//2为线宽,不填充imshow("鼠标绘制矩形", img);}}}
}
void QuickDemo::mouse_drawing(Mat& image)
{temp = image.clone();namedWindow("鼠标绘制矩形",WINDOW_AUTOSIZE);setMouseCallback("鼠标绘制矩形", on_draw,(void *)(&image));imshow("鼠标绘制矩形", image);}
//---------------------------------------------------------------------void QuickDemo::norm_demo(Mat& image)
{Mat dst;std::cout << image.type() << std::endl;image.convertTo(image, CV_32F);std::cout << image.type() << std::endl;normalize(image, dst, 1.0, 0, NORM_MINMAX);std::cout << dst.type() << std::endl;imshow("图像数据归一化", dst);
}void QuickDemo::resize_demo(Mat& image)
{Mat zoomin, zoomout;int h = image.rows;int w = image.cols;resize(image, zoomin,Size(w/2,h/2),0,0,INTER_LINEAR);imshow("zoomin", zoomin);resize(image, zoomout, Size(w*1.2, h*1.2), 0, 0, INTER_LINEAR);imshow("zoomout", zoomout);
}void QuickDemo::flip_demo(Mat& image)
{Mat img_x, img_y, img_xy;//数值大于0,表示绕 y 轴进行翻转;数值等于 0 ,表示绕 x 轴进行翻转;数值小于 0 ,表示绕两个轴旋转flip(image, img_x, 0);  //沿x轴对称flip(image, img_y, 1);  //沿y轴对称flip(image, img_xy, -1);  //先x轴对称,再y轴对称imshow("img_x", img_x);imshow("img_y", img_y);imshow("img_xy", img_xy);
}void QuickDemo::rotate_demo(Mat& image)
{Mat rotation0, rotation1, img_warp0, img_warp1, dst;double angle = 30;  //设置图像旋转的角度Size dst_size(image.rows, image.cols);  //设置输出图像的尺寸Point2f center(image.rows / 2.0, image.cols / 2.0);  //设置图像的旋转中心rotation0 = getRotationMatrix2D(center, angle, 1);  //计算仿射变换矩阵warpAffine(image, img_warp0, rotation0, dst_size, INTER_LINEAR, 0, Scalar(255, 0, 0));  //进行仿射变换imshow("旋转演示", img_warp0);//计算变换后的矩阵大小double cosx = abs(rotation0.at<double>(0,0));double sinx = rotation0.at<double>(0, 1);int nw = cosx * image.cols + sinx * image.rows;int nh = sinx * image.cols + cosx * image.rows;rotation0.at<double>(0, 2) = rotation0.at<double>(0, 2)+(nw/2- image.cols /2);rotation0.at<double>(1, 2) = rotation0.at<double>(1, 2) + (nh / 2 - image.rows / 2);warpAffine(image, dst, rotation0, Size(nw, nh), INTER_LINEAR, 0, Scalar(225, 125, 0));  //进行仿射变换imshow("旋转演示(计算变换后尺寸)", dst);}void  QuickDemo::video_demo(Mat& image)
{Mat frame;VideoCapture capture(0);while (true){if (!capture.isOpened())  //判断是否调用成功{std::cout << "打开摄像头失败,请确认摄像头是否安装成功";break;}capture.read(frame);if (frame.empty())  //判断读取图像是否成功{std::cout << "没有获取到图像" << std::endl;break;}imshow("frame", frame);char c = waitKey(10);if (c == 27) //ESC键退出{break;}}}

上述文件是对类中各个成员函数的实现,一个知识点对应一个成员函数。

quickopencv.h

#pragma once#include <opencv2\opencv.hpp>using namespace cv;class QuickDemo
{
public:void colorSpace_Demo(Mat& image);//将原图转为HSV和GRAY图像显示并保存void operator_demo(Mat& image);//进行像素操作,加减乘除void teacking_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_static_demo(Mat& image);//图像像素统计,最大最小值,均值方差void drawing_demo(Mat& image);//在图像中绘制几何图形void polyline_drawing_demo();//绘制多边形void mouse_drawing(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);
private:};

上述文件主要内容是QuickDemo类的声明。

OpenCv C++目前网上的视频课程质量均较差,最好的学习还是结合OpenCv官方文档和百度,进行学习。

OPenCv4 c++入门笔记(B站30讲课程的部分笔记)相关推荐

  1. 微服务架构核心20讲 课程的学习笔记

    微服务本身是组织架构的重组 https://www.cnblogs.com/yeyang/p/10225931.html

  2. 张鑫旭html入门,学习张鑫旭前辈课程的有关笔记(二)

    上一篇手记是第一部分,共5个属性,接下来的这篇,是另外5个属性. 同样,仅作为大家观看张鑫旭前辈视频的参考文档.作为查阅文档也是可以的. <深入理解vertical-align> vert ...

  3. 跟熊浩学沟通30讲读后感_得到《跟熊浩学沟通·30讲》课程介绍

    课程信息 课程名称:<跟熊浩学沟通·30讲> 上线时间:2019年10月25日 课程平台:得到APP 课程讲师:熊浩 课程讲数:30讲 课程价格:99元 课程介绍 沟通,是为了实现具体目标 ...

  4. 【个人笔记 - 目录】OpenCV4 C++ 快速入门 30讲

    个人资料,仅供学习使用 修改时间--2022年2月10日 09:51:53 学习课程:OpenCV4 C++ 快速入门视频30讲 视频老师:贾志刚 笔者对每一节课都做了详细的笔记,在包含了所有视频内容 ...

  5. openCV4.0 C++ 快速入门30讲学习笔记(自用 代码+注释)详细版

    课程来源:哔哩哔哩 环境:OpenCV4.5.1 + VS2019 目录 002.图像色彩空间转换 003.图像对象的创建与赋值 004.图像像素的读写操作 005.图像像素的算术操作(加减乘除4种不 ...

  6. OpenCV4 快速入门笔记

    OpenCV4 快速入门 (学习笔记 全) Excerpt <OpenCV4 快速入门>学习笔记 第1章 基础知识 1.1 基础结构介绍 作者博客https://blog.csdn.net ...

  7. 《商业洞察力30讲》学习笔记(上)

    [洞察力]| 作者 / Edison Zhou 这是恰童鞋骚年的第197篇原创文章 学习洞察力,也是新时代IT人员的一门进阶必修课... 1学习背景 2019年下半年至今,在领导的推荐下学习了刘润老师 ...

  8. 小啊呜产品读书笔记001:《邱岳的产品手记-16》第30讲产品案例分析:Primer的扑克牌交互 第31讲 产品分析的套路(下):如何出解决方案?

    小啊呜产品读书笔记001:<邱岳的产品手记-16>第30讲产品案例分析:Primer的扑克牌交互 & 第31讲 产品分析的套路(下):如何出解决方案? 一.今日阅读计划 二.泛读& ...

  9. Redis学习笔记(B站狂神说)(自己总结方便复习)

    Redis学习笔记B站狂神说 redis: 非关系型数据库 一.NoSQL概述 1.为什么要用Nosql 1.单机Mysql的年代 思考一下,这种情况下:整个网站的瓶颈是什么? 1.数据量如果太大,一 ...

最新文章

  1. Linux LVM 的使用详解
  2. Nature:“解构”母爱
  3. VTK:可视化之MultipleViewports
  4. Vue项目中的初始化
  5. eclipse中配置jad反编译插件
  6. Analyzer报表结果行
  7. 【软件测试】软件测试需要遵守哪些原则
  8. RACCommand
  9. elasticsearch -- 问题纪录
  10. 美国弗吉尼亚大学计算机科学,弗吉尼亚大学计算机科学专业怎么样?
  11. html盒模型中border的写法,CSS盒模型--边框设置:border: 1px solid red(像素 样式 颜色 ),border-bottom:1px dotted #ccc...
  12. Kalman实际应用总结
  13. C# 调用C++dll(以基恩士LKG5000为例)
  14. 在设备树中时钟的简单使用
  15. 计算机的系统保护选项,右击“我的电脑”,属性选项,没有“系统还原”怎么处理啊?...
  16. 通过这一篇文章就了解机器学习的主要内容和核心思想(包括一些算法思想总结)!!!
  17. 2022-2028年中国激光打印机行业市场调查研究及未来趋势预测报告
  18. Java基础:Java语言简介
  19. (三).类的小知识点
  20. Workflow 几个基本的概念

热门文章

  1. 风格迁移1-04:Liquid Warping GAN(Impersonator)-白话给你讲论文-翻译无死角(1)
  2. Redis和Mongodb应用场景研究
  3. 域名被微信封了 解决办法
  4. 教程 | 如何使用TensorFlow实现音频分类任务
  5. 微信小程序-毕业设计项目
  6. 前言中不允许有内容 问题解决
  7. 怎么通过大数据技术,找到更好的人才?
  8. Git分支管理办法,每个团队不一样,仅供参考!
  9. 世界第一个Bug的诞生,为什么软件缺陷叫BugDefect?
  10. 使用jode反编译java程序