下载安装

参考链接 VS2017配置opencv教程(超详细!!!)_Chosen One-CSDN博客_opencv

注意:

1. 后面的课程环境配置可能需要自己稍微改改,上面的配置教程可能学习到VS环境配置的基础知识,配一次大概就懂了

2. VS debug 模式下,链接器中的输入附加依赖项配置,opencv_world451d.lib

3. VS release 模式下,链接器中的输入附加依赖项配置,opencv_world451.lib

第一课 图像读取与显示

#include <opencv2/opencv.hpp>
#include <quickopencv.h>
#include <iostream>using namespace cv;
using namespace std;int main(int argc, char** argv) {Mat src = imread("E:/fig/input.jpg"); //B, G, R  openCV导入图片是BGR//Mat src = imread("E:/1/2.jfif", IMREAD_GRAYSCALE);//加载灰度图片if (src.empty()) {printf("could not load image....\n");return -1;}//namedWindow("输入窗口", WINDOW_FREERATIO);imshow("输入窗口", src);waitKey(0);destroyAllWindows();return 0;
}

第二课 图像色彩空间转换

1、色彩空间转换函数 cvtColor
2、图像的保存

void QuickDemo::colorSpace_Demo(Mat &image) {Mat gray, hsv;cvtColor(image, hsv, COLOR_BGR2HSV);//转hsv// H (0 ~ 180), S, V (三通道)// H (饱和度),S(),V(亮度)。调颜色可以改H,S。cvtColor(image, gray, COLOR_BGR2GRAY);//转灰度imshow("HSV", hsv);imshow("灰度", gray);//imwrite("E:/fig/hsv.png", hsv);//imwrite("E:/fig/gray.png", gray);
}

第三课 图像对象的创建与赋值

1、怎么操作mat
2、怎么访问每一个像素点
3、怎么创建一个空图或者mat

Mat的基本结构:头部加数据部分,在进行赋值操作是,是指针会指向同一块Data Block。如果要完全复制一个Mat对象需要使用克隆或者拷贝方法。

复制,克隆的具体实现。

void QuickDemo::mat_creation_demo(Mat &image) {Mat m1, m2;m1 = image.clone();image.copyTo(m2);// 创建空白图像Mat m3 = Mat::zeros(Size(8, 8), CV_8UC1);//CV_8UC1 单通道   CV_8UC3 三通道std::cout << m3 << std::endl;m3 = Mat::zeros(Size(8, 8), CV_8UC3);//CV_8UC1 单通道   CV_8UC3 三通道std::cout << m3 << std::endl;
}void QuickDemo::mat_creation_demo1() {// 创建空白图像Mat m3 = Mat::zeros(Size(8, 8), CV_8UC3);//zerosstd::cout << "width: " << m3.cols << " height: " << m3.rows << " channels: "<<m3.channels()<< std::endl;std::cout << m3 << std::endl;m3 = 127;//只会赋值第一个通道std::cout << m3 << std::endl;m3 = Scalar(0, 127, 127);//可以指定通道赋值std::cout << m3 << std::endl;Mat m3_1 = Mat::ones(Size(8, 8), CV_8UC3);//ones只会初始化每个像素点的第一个通道std::cout << "width: " << m3_1.cols << " height: " << m3_1.rows << " channels: " << m3_1.channels() << std::endl;std::cout << m3_1 << std::endl;
}void QuickDemo::mat_creation_demo2() {// 创建空白图像Mat m3 = Mat::zeros(Size(400, 400), CV_8UC3);//单通道m3 = Scalar(0, 0, 255);imshow("图像1", m3);//纯红色图Mat m4 = m3;m4 = Scalar(255, 0, 0);imshow("图像2", m3);//指向同一个地方,m3变成了蓝色
}void QuickDemo::mat_creation_demo3() {// 创建空白图像Mat m3 = Mat::zeros(Size(400, 400), CV_8UC3);//单通道m3 = Scalar(0, 0, 255);imshow("图像1", m3);//纯红色图Mat m4 = m3.clone();/*Mat m4;m3.copyTo(m4);*/m4 = Scalar(255, 0, 0);imshow("图像2", m3);imshow("图像3", m4);
}

第四课 图像像素的读写操作

如何遍历和修改每个像素点的数值,分为单通道和多通道。访问模式模式也有两种。第一种是数组访问模式,用最常规的数组下标访问像素值。第二种是指针访问模式,指定一个指针为图片的首地址,通过循环遍历,指针++,一次往后推。

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);//返回一个intimage.at<uchar>(row, col) = 255 - pv;//rgb值取反,改写}if (dims == 3) { // 彩色图像Vec3b bgr = image.at<Vec3b>(row, col);//返回一个Vec3bimage.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];}}}imshow("像素读写演示", image);
}void QuickDemo::pixel_visit_demo1(Mat &image) {int w = image.cols;int h = image.rows;int dims = image.channels();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) { // 彩色图像  其实数组长就是3*col,每一个col遍历三次*current_row++ = 255 - *current_row;*current_row++ = 255 - *current_row;*current_row++ = 255 - *current_row;}}}imshow("像素读写演示", image);
}

第五课  图像像素的算术操作

1、对图像的各个像素点实现加减乘除的操作

void QuickDemo::operators_demo(Mat &image) {Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());m = Scalar(5, 5, 5);Mat temp;multiply(image,Scalar(2,2,2),temp);imshow("乘法", temp);//add(image,m,dst);//divide(image,m,dst);//subtract(image, m, dst);//imshow("操作", dst);
}void QuickDemo::operators_demo1(Mat &image) {//自己实现一个加法Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());m = Scalar(5, 5, 5);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);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);
}

第六课第七课 滚动条操作演示-调整图片亮度&参数传递度

1、实现了图片亮度调节,对比度调节,并加上了进度条。


static void on_track_add(int b, void* userdata) {Mat image = *((Mat*)userdata);Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());m = Scalar(b, b, b);add(image, m, dst);imshow("亮度调整", dst);
}static void on_track_sub(int b, void* userdata) {Mat image = *((Mat*)userdata);Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());m = Scalar(b, b, b);subtract(image, m, dst);imshow("亮度调整", dst);
}void QuickDemo::tracking_bar_demo1(Mat &image) {namedWindow("亮度调整", WINDOW_AUTOSIZE);int lightness = 50;int max_value = 100;//createTrackbar("Value Bar:", "亮度调整", &bar_lightness, max_value, on_track_sub);//on_track_sub(50,0);createTrackbar("Value Bar:", "亮度调整", &lightness, max_value, on_track_add, (void*)(&image));;on_track_add(50, &image);
}static void on_lightness(int b, void* userdata) {Mat image = *((Mat*)userdata);Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());//image第一个原始图片,1.0第一个元素图片的权重,m第二个原始图片,0第二个原始图片的权重,b两个权重之和,dst输出图片addWeighted(image, 1.0, m, 0.0, b, dst);//改变gamma(b)imshow("亮度与对比度调整", dst);
}static void on_contrast(int b, void* userdata) {Mat image = *((Mat*)userdata);Mat dst = Mat::zeros(image.size(), image.type());Mat m = Mat::zeros(image.size(), image.type());double contrast = b / 100.0;addWeighted(image, contrast, m, 0.0, 0, dst);//grmma=0,只调对比度,。   改变alpha(contrast)imshow("亮度与对比度调整", dst);
}void QuickDemo::tracking_bar_demo(Mat &image) {namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE);int lightness = 50;int max_value = 100;int contrast_value = 100;createTrackbar("Value Bar:", "亮度与对比度调整", &lightness, max_value, on_lightness, (void*) (&image));createTrackbar("Contrast Bar:", "亮度与对比度调整", &contrast_value, 200, on_contrast, (void*)(&image));on_lightness(50, &image);
}

第八课 键盘响应操作

1、实现通过键入IO输入控制图片的响应

2、通过键盘输入,在终端得到响应,输入不同的键值,得到不一样的结果。

void QuickDemo::key_demo(Mat &image) {Mat dst = Mat::zeros(image.size(), image.type());while (true) {int c = waitKey(100);if (c == 27) { // 退出break;}if (c == 49) { // Key #1 变成灰度  输入1   waitKey返回的就是49std::cout << "you enter key # 1 "<< std::endl;cvtColor(image, dst, COLOR_BGR2GRAY);}if (c == 50) { // Key #2 std::cout << "you enter key # 2 " << std::endl;cvtColor(image, dst, COLOR_BGR2HSV);}if (c == 51) { // Key #3   加亮度std::cout << "you enter key # 3 " << std::endl;dst = Scalar(50, 50, 50);add(image, dst, dst);}imshow("键盘响应", dst);}
}

第九课 OpenCV自带颜色表操作

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(500);if (c == 27) { // 退出break;}applyColorMap(image, dst, colormap[index%19]);index++;imshow("颜色风格", dst);}
}

第十课 图像像素的逻辑操作

1、本节介绍如何对图像的像素进行操作,包括与、或、非、异或,矩形在图像中的绘制。

rectangle(m1,Rect(100,100,80,80),Scalar(255,255,0),-1,LINE_8,0);
这个函数参数1是图片名称,参数2是矩形的起始&末尾位置,参数3 Scalar表示将要绘制图像的颜色,参数4表示小于0表示填充,大于0表示绘制,参数5表示四邻域或者八邻域的绘制,参数6表示中心坐标或者半径坐标的小数位数。

void QuickDemo::bitwise_demo(Mat &image) {Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);//thinkness  -1 是填充,大于0是绘制  Scalar 填充的颜色   Rect 图片位置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);//两个矩阵交叉//bitwise_xor(m1, m2, dst);//bitwise_not(m2, dst);//dst = ~m2;//可读性差imshow("像素位操作", dst);
}

第十一课 通道分离与合并

1、本节介绍如何把不同的通道给分离,归并,使得能显现出来不同的通道颜色。

2、M[0],M[1],M[2]分别代表BGR个不同的通道。要开启某个通道只需要关闭另外的一个通道即可。
第二个内容为通道的合并,将不同通道的像素值进行转换操作,使图片呈现出不同的效果。

void QuickDemo::channels_demo(Mat &image) {std::vector<Mat> mv;split(image, mv);//分离通道//单通道灰图imshow("蓝色B", mv[0]);imshow("绿色G", mv[1]);imshow("红色R", mv[2]);Mat dst;mv[0] = 0;//第一个通道置为0,蓝色,不展显mv[2] = 0;//第三个通道置为0,红色,不展示merge(mv, dst);//合并通道imshow("绿色", dst);int from_to[] = { 0, 2, 1, 1, 2, 0 };//0-2; 1-1; 2-0mixChannels(&image, 1, &dst, 1, from_to, 3);//通道转换imshow("通道混合", dst);
}

第十二课 图像色彩空间转换

1、本节内容实现任务是提取任务的轮廓,首先把RGB色彩空间的图片转换到HSV空间中,其次,提取图片的mask,通过使用inrangle提取hsv色彩空间的颜色。

2、HSV色彩空间的颜色

void QuickDemo::inrange_demo(Mat &image) {//注意,请使用001.jpg图片Mat hsv;cvtColor(image, hsv, COLOR_BGR2HSV);Mat mask;//imshow("HSV", hsv);//cout << hsv << endl;inRange(hsv, Scalar(0, 43, 46), Scalar(180, 255, 255), mask);//蓝色最小值HSV=(100,43,46),最大值HSV=(124,255,255)imshow("mask", mask);
}void QuickDemo::inrange_demo1(Mat &image) {//注意,请使用001.jpg图片Mat hsv;cvtColor(image, hsv, COLOR_BGR2HSV);Mat mask;/*OpenCV中的inRange()函数可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0),该功能类似于之间所讲的双阈值化操作。*/inRange(hsv, Scalar(100, 43, 46), Scalar(124, 255, 255), mask);//Mat redback = Mat::zeros(image.size(), image.type());redback = Scalar(40, 40, 200);//创建一个红色幕imshow("幕布", redback);imshow("mask1", mask);bitwise_not(mask, mask);//取反,黑变成白,白变成黑imshow("mask2", mask);image.copyTo(redback, mask);//mask中像素不为0(黑色)的点才会copy到redback上,(所以之前要取个反,因为头像部分是黑色)imshow("roi区域提取", redback);
}

第十三课 图像像素值统计

1、分别定义双精度型变量 minv和maxv。指针变量minLoc,maxLoc;
2、因为这图片是多通道的,所以使用一个容器装取数值,并且用split分离图片到MV中,通过for循环操作,遍历图片信息,并且打印信息到终端。图像信息包括,方差,均值,大小。

void QuickDemo::pixel_statistic_demo(Mat &image) {double minv, maxv;Point minLoc, maxLoc;std::vector<Mat> mv;split(image, mv);for (int i = 0; i < mv.size(); i++) {minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());std::cout <<"No. channels:"<< i << " min value:" << minv << " max value:" << maxv << std::endl;}Mat mean, stddev;Mat redback = Mat::zeros(image.size(), image.type());redback = Scalar(40, 40, 200);meanStdDev(redback, mean, stddev);//求均值和方差imshow("redback", redback);std::cout << "means:" << mean << std::endl;std::cout<< " stddev:" << stddev << std::endl;
}

第十四课 图像几何形状绘制

1、介绍如何绘制椭圆,矩形,直线,圆等

void QuickDemo::drawing_demo(Mat &image) {//bgr//Rect rect(100, 100, 250, 300);Rect rect;//位置rect.x = 100;rect.y = 100;//大小rect.width = 250;rect.height = 300;Mat bg = Mat::zeros(image.size(), image.type());//矩形rectangle(bg, rect, Scalar(0, 0, 255), -1, 8, 0);//thinkness 线宽,如果是负数,那就是填充了//圆circle(bg, Point(350, 400), 15, Scalar(255, 0, 0), -1, 8, 0);//线line(bg, Point(100, 100), Point(350, 400), Scalar(0, 255, 0), 4, LINE_AA, 0);//参数2,3,就是对角线的坐标RotatedRect rrt;//椭圆的规格rrt.center = Point(200, 200);//中心位置rrt.size = Size(100, 200);rrt.angle = 90.0;//椭圆ellipse(bg, rrt, Scalar(0, 255, 255), 2, 8);Mat dst;//加起来,按权重加起来addWeighted(image, 0.7, bg, 0.3, 0, dst);imshow("绘制演示", bg);
}

第十五课 随机数与随机颜色

1、介绍如何能产生一个随机数字和随机颜色,并且用线条的方式显示出来。

void QuickDemo::random_drawing() {Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);int w = canvas.cols;int h = canvas.rows;RNG rng(12345);while (true) {int c = waitKey(10);if (c == 27) { // 退出break;}int x1 = rng.uniform(0, w);int y1 = rng.uniform(0, h);int x2 = rng.uniform(0, w);int y2 = rng.uniform(0, h);int b = rng.uniform(0, 255);int g = rng.uniform(0, 255);int r = rng.uniform(0, 255);//canvas = Scalar(0, 0, 0);//把之前的清掉//随机绘制矩形,圆,椭圆都可以line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, LINE_AA, 0);imshow("随机绘制演示", canvas);}
}

第十六课 多边形填充与绘制

1、介绍了2种多边形绘制的实现方式。

2、第一种方式,通过标记各个点,然后存储到容器中,之后对容器中的点进行操作。填充多边形调用fillPoly,绘制多边形调用polylines。第二种方式,使用一个API接口绘制。通过一个容器中的存储的点组成的另一个容器。

void QuickDemo::polyline_drawing_demo() {Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);int w = canvas.cols;int h = canvas.rows;Point p1(100, 100);Point p2(300, 150);Point p3(300, 350);Point p4(250, 450);Point p5(50, 450);std::vector<Point> pts;pts.push_back(p1);pts.push_back(p2);pts.push_back(p3);pts.push_back(p3);pts.push_back(p4);pts.push_back(p5);//polylines(canvas, pts, true, Scalar(0, 255, 0), 2, 8, 0);//相当于画折线图//fillPoly(canvas, pts, Scalar(255, 0, 255), 8, 0);//填充std::vector<std::vector<Point>> contours;contours.push_back(pts);//push一个,只有一个多边形drawContours(canvas, contours, 0, Scalar(0, 0, 255), -1, 8);imshow("绘制多边形", canvas);
}

第十七课 鼠标操作与响应

Point sp(-1, -1);//初始化起始点,(-1,-1)
Point ep(-1, -1);//初始化终结点,(-1,-1)
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);//Rect 类有是个成员变量,这个是直接实例化一个rect类temp.copyTo(image);//temp里面保存的最开始的image,每次绘画前,都将temp赋值给imageMat roi = image(box);imshow("ROI区域", roi);//截取一块ROI区域,新生成rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);imshow("鼠标绘制", image);// ready for next drawingsp.x = -1;sp.y = -1;//roi = Scalar(0, 0, 0);}}else if (event == EVENT_MOUSEMOVE) {//鼠标移动。把绘画过程展示出来if (sp.x > 0 && sp.y > 0) {//必须是鼠标按下之后(sp.x,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();
}

第十八课 图像像素类型转换与归一化

void QuickDemo::norm_demo(Mat &image) {Mat dst;std::cout << image.type() << std::endl;//16 CV_8UC3  八位3通道image.convertTo(image, CV_32F);//转化成CV_32FC3类型   单通道,每通道都是32位浮点数std::cout << image.type() << std::endl;//21 normalize(image, dst, 1.0, 0, NORM_MINMAX);//变成浮点数类型后,一定要归一化,不然显示有问题//转回去,乘以255,就行,然后转CV_8UC3std::cout << dst.type() << std::endl;//21imshow("图像数据归一化", dst);// CV_8UC3, CV_32FC3
}

第十九课 图像放缩与插值

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.5, h*1.5), 0, 0, INTER_LINEAR);imshow("zoomout", zoomout);
}

第二十课 图像翻转

void QuickDemo::flip_demo(Mat &image) {Mat dst;// flip(image, dst, 0); // 上下翻转 0 // flip(image, dst, 1); // 左右翻转 1flip(image, dst, -1); // 180°旋转  -1imshow("图像翻转", dst);
}

第二十一课 图像旋转

1、本节课主要介绍了翻转图像的指定角度,之后,确定得到新的图像信息,长宽也发生改变。

2、 图片旋转函数warpAffine()。

M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);//得到旋转矩阵M(如下图)。

图中:cos = M(0,0),sin = M(0,1)。图片中心点:(M(0,2),M(1,2))

旋转后的长宽:(w*cos+h*sin,  w*sin+h*cos)

void QuickDemo::rotate_demo(Mat &image) {Mat dst, M;int w = image.cols;int h = image.rows;//w/2, h/2 得到中心点M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);//得到旋转矩阵Mdouble 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);
}

第二十二课和第二十三课 视频文件摄像头使用 & 视频处理与保存

1、介绍了如何读取一个视频,以及调用电脑的摄像头。并且对读取到的视频进行操作。

void QuickDemo::video_demo1(Mat &image) {VideoCapture capture("C:/Users/WS/Videos/Captures/001.mp4");Mat frame;while (true) {capture.read(frame);//flip(frame, frame, 1);//图片翻转if (frame.empty()) {break;}//namedWindow("frame", WINDOW_FREERATIO);colorSpace_Demo(frame);imshow("frame", frame);int c = waitKey(1);if (c == 27) {break;}}capture.release();
}void QuickDemo::video_demo(Mat &image) {VideoCapture capture("C:/Users/WS/Videos/Captures/001.mp4");// frame 一针int frame_width = capture.get(CAP_PROP_FRAME_WIDTH);//frame的宽度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;VideoWriter writer("D:/test.mp4", capture.get(CAP_PROP_FOURCC), fps, Size(frame_width, frame_height), true);Mat frame;while (true) {capture.read(frame);//flip(frame, frame, -1);//图片翻转if (frame.empty()) {break;}imshow("frame", frame);//colorSpace_Demo(frame);writer.write(frame);// TODO: do something....int c = waitKey(1);if (c == 27) { // 退出break;}}// releasecapture.release();writer.release();
}

第二十四课 图像直方图

1、视频的属性,SD(标清),HD(高清),UHD(超清),蓝光。如何读取视频文件,以及读取视频文件的属性,衡量视频处理指标:FPS。保存视频时的编码格式。保存视频的实际size和create的size大小保持一致。

2、横坐标时像素值,纵坐标统计数量,但是直方图丢失了空间信息,只有图像的像素值信息。

void QuickDemo::histogram_demo(Mat &image) {// 三通道分离std::vector<Mat> bgr_plane;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);//bins表示坐标轴上面,直方图数组size,换句话说就是横坐标上面有bins个刻度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++) {//幕布上起始点Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1)))//bin_w*(i - 1) 起始点x     (i-1)第几个   bin_w:每个多宽, 然后乘起来//屏幕左上角是(0,0)。hist_h 减去,得到一个负数,这才是这条线的起始点//幕布上终止点Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(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, 8, 0);line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);}// 显示直方图namedWindow("Histogram Demo", WINDOW_AUTOSIZE);imshow("Histogram Demo", histImage);
}

第二十五课 二维直方图

1、直方图是图像的统计学特征。表示了图像的各个像素在0-255出现的频率。图像的平移旋转都不会对性质进行改变。缺点:不能表征一张图像。

void QuickDemo::histogram_2d_demo(Mat &image) {// 2D 直方图Mat hsv, hs_hist;cvtColor(image, hsv, COLOR_BGR2HSV);//H:0-180   S:0-255   V:0-255int 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 };//前两个通道//二维的,所以hist_bins 也是二维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);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, COLORMAP_JET);imshow("H-S Histogram", hist2d_image);//imwrite("D:/hist_2d.png", hist2d_image);
}

第二十六课 直方图均衡化

1、用途:用于图像增强,人脸检测,卫星遥感。均衡化的图像只支持单通道。

2、分为8个级别,将所有像素规约到这8个级别上,规约方式如下图,5,6,7(共有245+122+81个)都被规约到最高级别上去了,均衡化后他们的像素一样。

void QuickDemo::histogram_eq_demo(Mat &image) {Mat gray;cvtColor(image, gray, COLOR_BGR2GRAY);imshow("灰度图像", gray);Mat dst;equalizeHist(gray, dst);imshow("直方图均衡化演示", dst);
}

第二十七课 图像卷积操作

1、卷积的作用,高的往下降,低的往上升。但是会造成信息丢失。产生模糊效果。是一种线性操作,点乘,之后相加。

线性卷积:(12*1+12*1+14*1+2*1+4*1+6*1+6*1+8*1+10*1)/9 =(取整)8

void QuickDemo::blur_demo(Mat &image) {//模糊操作的实现就是通过卷积操作Mat dst;blur(image, dst, Size(15, 15), Point(-1, -1));//第三个参数就是卷积核的大小imshow("图像模糊", dst);
}

第二十八课 高斯模糊

1、高斯卷积数学表达式说明,中心的数值最大,离中心距离越远,数值越小。

void QuickDemo::gaussian_blur_demo(Mat &image) {Mat dst;GaussianBlur(image, dst, Size(0, 0), 5);//size(0,0)  一般最好是基数,设置0就是不设定卷积核大小,通过sigma去控制模糊程度imshow("高斯模糊", dst);
}

第二十九课 高斯双边模糊

1、抑制噪声,差异越大越保留,本来粗糙的就变得圆滑。

void QuickDemo::bifilter_demo(Mat &image) {Mat dst;bilateralFilter(image, dst, 0, 100, 10);imshow("双边模糊", dst);
}

第三十课 实时人脸检测

openCV中自带人脸检测模型,去OpenCV安装路径下比如:D:/opencv/sources/samples/dnn/face_detector下查看是否有opencv_face_detector_uint8.pb和root_dir+"opencv_face_detector.pbtxt文件,如果没有可以去下载。

需要的DNN模型下载

void QuickDemo::face_detection_demo() {std::string root_dir = "D:/opencv/sources/samples/dnn/face_detector/face_download/";dnn::Net net = dnn::readNetFromTensorflow(root_dir+ "opencv_face_detector_uint8.pb", root_dir+"opencv_face_detector.pbtxt");VideoCapture capture("C:/Users/WS/Videos/Captures/002.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);// N C H W 数量,通道数,高度,宽度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) {//大于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);int c = waitKey(1);if (c == 27) { // 退出break;}}
}

OpenCV基础知识相关推荐

  1. OpenCV基础知识 图像

    OpenCV基础知识 图像 位图模式 灰度模式 RGB模式 位图模式 位图模式是是1位深度的图像,只有黑和白两种颜色.它可以由扫描或置入黑色的矢量线条图像生成,也能由灰度模式转换而成.其他图像模式不能 ...

  2. Python计算机视觉编程第十章——OpenCV基础知识

    Python计算机视觉编程 (一)OpenCV 的 Python 接口 (二)OpenCV 基础知识 2.1 读取和写入图像 2.2 颜色空间 2.3 显示图像及结果 (三)处理视频 3.1 视频输入 ...

  3. python open-cv 基础知识总结(三)

    上一章:python open-cv 基础知识总结(二) 1. 轮廓中心计算 本教程的目标是 (1)  检测图像中每个形状的轮廓, (2)  计算轮廓的中心 -也称为区域的  质心 . 为了实现这些目 ...

  4. 【分享】计算机视觉方向必备opencv基础知识总览

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自 | 机器学习实验室 今天很开心与大家分享一篇关于OpenC ...

  5. OpenCv基础知识(入门)

    理论基础: 1.图像与矩阵 一般来说,图像是一个标准的矩形,有着宽度(width)和高度(height).而矩阵有着行(row)和列(column),矩阵的操作在数学和计算机中的处理都很常见且成熟,于 ...

  6. OpenCV基础知识入门

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文旨在让你快速入门opencv. OpenCV OpenCV是计 ...

  7. opencv基础知识-videowriter

    一.前言-简介 在试验中需要常常将实验结果进行保存,在opencv中提供很好用的录制视频的句柄,也可称之为类-videowriter. videowriter应用那是相当的简单,总之分为三步: //声 ...

  8. 基于机器学习的捡球机器人设计与实现(探索)第3篇——opencv基础知识学习(2019-02-02)

    2019-02-02  by 崔斐然 已经20多天没有更新了 这些天忙于驾照和英语复习项目暂时搁置了(toulan) 接下来主要开始更新OpenCV的学习笔记,从零开始.笔记将归档于<机器视觉学 ...

  9. opencv基础知识及其一些例子

    opencv官网 一.插值法 1.最近邻插值 上图可看出f(p)=f(Q11),缺点可能出现明显的块状. 2.线性插值 3.双线性插值 通过线性插值确定R1和R2,最终在确定P 二.cv2.putTe ...

最新文章

  1. 第十四章 梁山好汉中谁最惹人爱
  2. 《python核心编程第二版》第5章习题
  3. 干货 | 算法工程师入门第二期——穆黎森讲增强学习(一) 本文作者:大牛讲堂 编辑:刘芳平 2017-07-19 11:38 导语:地平线大牛讲堂算法工程师入门第二期来啦!本期地平线资深算法工程师、增
  4. 我的空间为什么叫IT人?
  5. SQL SERVER大话存储结构(2)
  6. 函数式接口的概念函数式接口的定义
  7. docker php镜像推荐,Docker 常用镜像整理
  8. Linq Expression
  9. c语言九九乘法表倒三角问题,c语言问题九九乘法表
  10. java-Web(js)作业
  11. java数组表示方法_Java中数组总结
  12. 大学追忆录(天空晴朗的梦)
  13. word操作 mathtype插入公式 表格
  14. dell服务器 指示灯_服务器指示灯说明
  15. Luminar 4:AI 人像照片增强器
  16. 您需要administrator权限才能对此文件进行更改
  17. Excel 函数大全之查找和引用函数 01 ADDRESS、AREAS、CHOOSE 、CHOOSECOLS、CHOOSEROWS、COLUMN 、COLUMNS教程含使用方法
  18. 云计算服务模型,第 2 部分: 平台即服务(PaaS)
  19. 浏览器检测麦克风音量
  20. 图像处理特征提取之局部特征

热门文章

  1. cpu排行计算机专业,cpu性能天梯图,详细教您电脑cpu排行榜
  2. think php 5(命令行)创建控制器、model
  3. ubuntu加了张固态_将ubuntu系统迁移到ssd固态
  4. 3、流量分析--分组TopN统计
  5. vmware中调整ubuntu的磁盘大小
  6. Jupyter Notebook使用的快捷键
  7. 第13天 缓冲、转换、对象(序列化)和打印流
  8. eclipse neon Java编辑器页面字体更改
  9. c开头英文语言,字母C开头的英文名
  10. 如何优雅地管理微信数据库?