作者丨卡拉肖克X 来源丨OpenCV学堂 编辑丨极市平台01环境搭建 环境配置了一个早上,到10。48分配置完毕,有点难受。还好最后显示出第一张图片。includeopencv2opencv。intmain(){Matsrcimread(D:images011。jpg,IMREADGRAYSCALE);读取进来的数据以矩阵的形势,第二个参数代表显示一张灰度图像。if(src。empty()){printf(couldnotloadimage);如果图片不存在将无法读取,打印到终端。}超过屏幕的图像无法显示时候调用此函数。namedWindow(输入窗口,WINDOWFREERATIO);创建了一个新窗口,参数1表示名称,第二个参数代表一个自由的比例imshow(输入窗口,src);表示显示在新创建的输入窗口上,第一个参数表示窗口名称,src表示数据对象MatwaitKey(0);执行到这句,程序阻塞。参数表示延时时间。单位msdestroyAllWindows();销毁前面创建的显示窗口return0;} 第一节课介绍了如何读取第一张图片,并且显示出来,通过调用imread函数读取照片,再调用imshow显示图片到窗口。同时,讲述了如何打印灰度图像,图片读取失败的处理方式,代码注释详细介绍了每条语句的意思。02显示图象 1、色彩空间转换函数cvtColor 2、图像的保存includeopencv2opencv。classQuickDemo创建一个QuickDemo对象{public:voidcolorSpaceDemo(Matimge);定义一个类,里面包含输入一个图片,对图片操作};includequickopencv。hvoidQuickDemo::colorSpaceDemo(Matimage){Matgray,定义2个矩阵类的图像gray和hsv,cvtColor(image,hsv,COLORBGR2HSV);图像转换函数,可以把image转成hsv,第三个参数是转成的类型cvtColor(image,gray,COLORBGR2GRAY);图像转换函数,可以把image转成hsv,第三个参数是转成的类型imshow(HSV,hsv);imshow(灰度,gray);imwrite(D:hsv。jpg,hsv);保存图片,前面是保存图的地址,后面是保存图的名称imwrite(D:gray。jpg,gray);}includeopencv2opencv。hppincludeiostreamincludequickopencv。intmain(){Matsrcimread(D:images1。jpg,IMREADANYCOLOR);B,G,R实际上0255三色。3通道读取进来的数据以矩阵的形势,第二个参数代表显示一张灰度图像。if(src。empty()){printf(couldnotloadimage);如果图片不存在将无法读取,打印到终端。return1;}超过屏幕的图像无法显示时候调用此函数。namedWindow(输入窗口,WINDOWFREERATIO);创建了一个新窗口,参数1表示名称,第二个参数代表一个自由的比例imshow(输入窗口,src);表示显示在新创建的输入窗口上,第一个参数表示窗口名称,src表示数据对象Mat在主函数中调用之前创建的类对象QuickDqd。colorSpaceDemo(src);waitKey(0);执行到这句,程序阻塞。参数表示延时时间。单位msdestroyAllWindows();销毁前面创建的显示窗口return0;} 这节主要介绍了创建一个类对象,然后通过类对象调用函数,在main主函数中进行调用实现类对象中的功能,比如转换成HSV类型图片和GRAY类型图片,最后通过imwrite函数进行图像的保存。03图像对象的创建与赋值 1、怎么操作mat 2、怎么访问每一个像素点 3、怎么创建一个空图或者matvoidQuickDemo::matcreationdemo(Matimage){Matm1,m2;m1image。clone();image。copyTo(m2);创建空白图像Matm3Mat::ones(Size(400,400),CV8UC3);创建88的CV8位的无符号的n通道的unsignedcharoneszeros是初始化的方法m3Scalar(255,0,0);给三个通道都赋值127,单通道赋值方法m3127;m3初始为蓝色数据的宽度和长度是由通道数决定的。std::coutwidth:m3。colsheightm3。rowschannelsm3。channels()std::用来查看宽度,高度与通道数。std::coutm3std::Matm4m3。clone();赋值M4就是M3M4改变了,M3也改变了,没有产生新的自我(M4与M3同体)M4为M3的克隆,M3还是原来的颜色,不会改变。(M4与M3不同体,各自是各自的颜色)m3。copyTo(m4);把M3赋值给M4,M4就是蓝色m4Scalar(0,255,255);改变m4的颜色为黄色,m4也改变imshow(图像3,m3);标题和图像名称显示图像m3纯蓝色imshow(图像4,m4);标题和图像名称} 本节课介绍了如何创建一个Mat对象,通过创建新的Mat对象来创建用户的特定的底色画布,创建图像的基本类型有两种一种是ones一种是zeros,ones()中的第一个参数代表图像的大小,第二个参数代表创建几维的图像,UC代表无符号字符型,数组3代表通道数。克隆和赋值的区别,克隆就是产生一个新的对象,新对象改变属性,旧对象属性不变(各自为政)。赋值是二者同体,当新属性发生改变,旧属性也发生改变(二者同体)。04图像像素的读写操作 如何遍历和修改每个像素点的数值,分为单通道和多通道。访问模式模式也有两种。第一种是数组访问模式,用最常规的数组下标访问像素值。voidQuickDemo::pixelvisitdemo(Matimage){intdimsimage。channels();inthimage。intwimage。for(introw0;row){for(intcol0;col){if(dims1)单通道的灰度图像{intpvimage。atuchar(row,col);得到像素值image。atuchar(row,col)255给像素值重新赋值}if(dims3)三通道的彩色图像{Vec3bbgrimage。atVec3b(row,col);opencv特定的类型,获取三维颜色,3个值image。atVec3b(row,col)〔0〕255bgr〔0〕;image。atVec3b(row,col)〔1〕255bgr〔1〕;image。atVec3b(row,col)〔2〕255bgr〔2〕;对彩色图像读取它的像素值,并且对像素值进行改写。}}}namedWindow(像素读写演示,WINDOWFREERATIO);imshow(像素读写演示,image);} 第二种为指针访问模式,指定一个指针为图片的首地址,通过循环遍历,指针,一次往后推。voidQuickDemo::pixelvisitdemo(Matimage){intdimsimage。channels();inthimage。intwimage。for(introw0;row){ucharcurrentrowimage。ptruchar(row);for(intcol0;col){if(dims1)单通道的灰度图像{得到像素值currentrow255给像素值重新赋值}if(dims3)三通道的彩色图像{currentrow255指针每做一次运算,就向后移动一位currentrow255currentrow255}}}namedWindow(像素读写演示,WINDOWFREERATIO);imshow(像素读写演示,image);} 本节主要介绍了通过两种遍历的方式访问图像的像素值,并且改变图像的像素值。05图像像素的操作 对图像的各个像素点实现加减乘除的操作。介绍了常用的除爆函数saturatecast,防止数值过界。voidQuickDemo::operatorsdemo(Matimage){MatdstMat::zeros(image。size(),image。type());MatmMat::zeros(image。size(),image。type());dstimageScalar(50,50,50);mScalar(50,50,50);multiply(image,m,dst);乘法操作apiimshow(乘法操作,dst);add(image,m,dst);加法操作apiimshow(加法操作,dst);subtract(image,m,dst);减法操作apiimshow(减法操作,dst);pide(image,m,dst);除法操作apinamedWindow(加法操作,WINDOWFREERATIO);imshow(加法操作,dst);加法操作底层intdimsimage。channels();inthimage。intwimage。for(introw0;row){for(intcol0;col){Vec3bp1image。atVec3b(row,col);opencv特定的类型,获取三维颜色,3个值Vec3bp2m。atVec3b(row,col);dst。atVec3b(row,col)〔0〕saturatecastuchar(p1〔0〕p2〔0〕);saturatecast用来防爆,小于0就是0,大于255就是255dst。atVec3b(row,col)〔1〕saturatecastuchar(p1〔1〕p2〔1〕);dst。atVec3b(row,col)〔2〕saturatecastuchar(p1〔2〕p2〔2〕);对彩色图像读取它的像素值,并且对像素值进行改写。}}imshow(加法操作,dst);} 介绍了四种不同的API实现,并且演示了一种加法的算法。06滚动条演示操作调整图片亮度 本节介绍怎么通过createTrackbar来设置一个进度条,实现图片的亮度调节。Matsrc,dst,m;intlightness50;定义初始的亮度为50staticvoidontrack(int,void){mScalar(lightness,lightness,lightness);创建调整亮度的数值subtract(src,m,dst);定义亮度变化为减imshow(亮度调整,dst);显示调整亮度之后的图片}voidQuickDemo::trackingbardemo(Matimage){namedWindow(亮度调整,WINDOWAUTOSIZE);dstMat::zeros(image。size(),image。type());图片的初始化创建一个和image大小相等,种类相同的图像mMat::zeros(image。size(),image。type());图片的初始化创建一个和image大小相等,种类相同的图像给src赋值intmaxvalue100;定义最大值为100createTrackbar(ValueBar:,亮度调整,lightness,maxvalue,ontrack);调用函数实现功能。ontrack(50,0);}07滚动条演示操作传递参数 无类型指针类型转换与参数传递!staticvoidonlightness(intb,voiduserdata){Matimage((Mat)userdata);MatdstMat::zeros(image。size(),image。type());MatmMat::zeros(image。size(),image。type());mScalar(b,b,b);addWeighted(image,1。0,m,0,b,dst);融合两张图imshow(亮度对比度调整,dst);}staticvoidoncontrast(intb,voiduserdata){Matimage((Mat)userdata);MatdstMat::zeros(image。size(),image。type());MatmMat::zeros(image。size(),image。type());doublecontrastb100。0;addWeighted(image,contrast,m,0。0,0,dst);融合两张图imshow(亮度对比度调整,dst);}voidQuickDemo::trackingbardemo(Matimage){namedWindow(亮度对比度调整,WINDOWAUTOSIZE);intlightness50;intmaxvalue100;intcontrastvalue100;createTrackbar(ValueBar:,亮度对比度调整,lightness,maxvalue,onlightness,(void)(image));createTrackbar(ContrastBar:,亮度对比度调整,contrastvalue,200,oncontrast,(void)(image));onlightness(50,image);}08键盘响应操作 本节介绍通过键盘输入,终端能够读取响应的信息。voidQuickDemo::keydemo(Matimage){MatdstMat::zeros(image。size(),image。type());while(true){charcwaitKey(100);停顿100ms做视频处理都是1if(c27){esc退出应用程序}if(c49)key1{std::coutyouenterkey1std::cvtColor(image,dst,COLORBGR2GRAY);}if(c50)key1{std::coutyouenterkey2std::cvtColor(image,dst,COLORBGR2HSV);}if(c51)key1{std::coutyouenterkey3std::dstScalar(50,50,50);add(image,dst,dst);}imshow(键盘响应,dst);std::coutcstd::}} 通过键盘输入,在终端得到响应,输入不同的键值,得到不一样的结果。09opencv自带颜色操作voidQuickDemo::colorstyledemo(Matimage){intcolormap〔〕{COLORMAPAUTUMN,COLORMAPBONE,COLORMAPCIVIDIS,COLORMAPDEEPGREEN,COLORMAPHOT,COLORMAPHSV,COLORMAPINFERNO,COLORMAPJET,COLORMAPMAGMA,COLORMAPOCEAN,COLORMAPPINK,COLORMAPPARULA,COLORMAPRAINBOW,COLORMAPSPRING,COLORMAPTWILIGHT,COLORMAPTURBO,COLORMAPTWILIGHT,COLORMAPVIRIDIS,COLORMAPTWILIGHTSHIFTED,COLORMAPWINTER};Mintindex0;while(true){charcwaitKey(100);停顿100ms做视频处理都是1if(c27){esc退出应用程序}if(c49)key1按下按键1时,保存图片到指定位置{std::coutyouenterkey1std::imwrite(D:gray。jpg,dst);}applyColorMap(image,dst,colormap〔index19〕);循环展示19种图片imshow(循环播放,dst);}} 伪色彩填充与颜色表匹配10图像像素的逻辑操作 本节介绍如何对图像的像素进行操作,包括与、或、非、异或,矩形在图像中的绘制。voidQuickDemo::bitwisedemo(Matimage){Matm1Mat::zeros(Size(256,256),CV8UC3);Matm2Mat::zeros(Size(256,256),CV8UC3);rectangle(m1,Rect(100,100,80,80),Scalar(255,255,0),1,LINE8,0);小于0表示填充,大于0表示绘制rectangle(m2,Rect(150,150,80,80),Scalar(0,255,255),1,LINE8,0);imshow(m1,m1);imshow(m2,m2);Mbitwiseand(m1,m2,dst);位操作与bitwiseor(m1,m2,dst);位操作或bitwisenot(image,dst);取反操作bitwisexor(m1,m2,dst);异或操作imshow(像素位操作,dst);}rectangle(m1,Rect(100,100,80,80),Scalar(255,255,0),1,LINE8,0); 这个函数参数1是图片名称,参数2是矩形的起始末尾位置,参数3Scalar表示将要绘制图像的颜色,参数4表示小于0表示填充,大于0表示绘制,参数5表示四邻域或者八邻域的绘制,参数6表示中心坐标或者半径坐标的小数位数。11通道的分离与合并 本节介绍如何把不同的通道给分离,归并,使得能显现出来不同的通道颜色。voidQuickDemo::channelsdemo(Matimage){std::vectorMsplit(image,mv);imshow(蓝色,mv〔0〕);0,1,2三个通道分别代表BGR。关闭2个通道意味着开启一个通道。imshow(绿色,mv〔1〕);imshow(红色,mv〔2〕);Mmv〔0〕0;mv〔2〕0;merge(mv,dst);imshow(蓝色,dst);intfromto〔〕{0,2,1,1,2,0};把通道相互交换,第0第2,第一第一,第二第0mixChannels(image,1,dst,1,fromto,3);3表示3个通道参数1指针引用图像参数2引用到dstimshow(通道混合,dst);} M〔0〕,M〔1〕,M〔2〕分别代表BGR个不同的通道。要开启某个通道只需要关闭另外的一个通道即可。第二个内容为通道的合并,将不同通道的像素值进行转换操作,使图片呈现出不同的效果。12图像色彩空间转换 本节内容实现任务是提取任务的轮廓,首先把RGB色彩空间的图片转换到HSV空间中,其次,提取图片的mask,通过使用inrangle提取hsv色彩空间的颜色。HSV色彩空间的颜色voidQuickDemo::inrangedemo(Matimage){McvtColor(image,hsv,COLORBGR2HSV);MinRange(hsv,Scalar(35,43,46),Scalar(77,255,255),mask);35,43,46根据图片中绿色最低来确定最小值。77,255,255提取参数1低范围,参数2高范围将hsv中的由低到高的像素点提取出来并且存储到mask当中。imshow(mask,hsv);MatredbackMat::zeros(image。size(),image。type());redbackScalar(40,40,200);bitwisenot(mask,mask);imshow(mask,mask);image。copyTo(redback,mask);把redback复制到mask,mask通过inRange得到。imshow(roi提取,hsv);}13图像像素值统计 分别定义双精度型变量minv和maxv。指针变量minLoc,maxL因为这图片是多通道的,所以使用一个容器装取数值,并且用split分离图片到MV中通过for循环操作,遍历图片信息,并且打印信息到终端。图像信息包括,方差,均值,大小。voidQuickDemo::pixelstatisticdemo(Matimage){doubleminv,定义最值PointminLoc,maxL定义最值地址std::vectorMmv是一个Mat类型的容器装在这个容器内split(image,mv);for(inti0;imv。size();i){分别打印各个通道的数值minMaxLoc(mv〔i〕,minv,maxv,minLoc,maxLoc,Mat());求出图像的最大值和最小值。std::coutNo。channels:iminvalue:minvmaxvalue:maxvstd::}Matmean,meanStdDev(image,mean,stddev);求出图像的均值和方差std::coutmean:meanstd::std::coutstddev:stddevstd::}14图像几何形状的绘制 本节课介绍如何绘制椭圆,矩形,直线,圆等voidQuickDemo::drawingdemo(Matimage){Rrect。x200;rect。y200;rect。width100;rect。height100;MatbgMat::zeros(image。size(),image。type());rectangle(image,rect,Scalar(0,0,255),1,8,0);参数1为绘图的底图或者画布名称,参数2位图片的起始,宽度,高度参数3代表填充颜色。参数4大于0是线小于0是填充参数5表示邻域填充,参数6默认值为0circle(bg,Point(350,400),15,Scalar(0,0,255),2,LINEAA,0);参数2位图片中心位置,参数3为半径为15的圆MaddWeighted(image,0。7,bg,0。3,0,dst);RotatedRrtt。centerPoint(200,200);rtt。sizeSize(100,200);rtt。angle0。0;line(bg,Point(100,100),Point(350,400),Scalar(0,0,255),8,LINEAA,0);lineAA表示去掉锯齿ellipse(bg,rtt,Scalar(0,0,255),2,8);imshow(矩形的绘制,bg);}15随机数与随机颜色 本节主要介绍如何能产生一个随机数字和随机颜色,并且用线条的方式显示出来。 voidQuickDemo::randomdrawing(){MatcanvasMat::zeros(Size(512,512),CV8UC3);intwcanvas。inthcanvas。RNGrng(12345);while(true){intcwaitKey(10);if(c27){}intx1rng。uniform(0,canvas。cols);inty1rng。uniform(0,h);intx2rng。uniform(0,canvas。cols);inty2rng。uniform(0,h);intbrng。uniform(0,255);intgrng。uniform(0,255);intrrng。uniform(0,255);canvasScalar(0,0,0);line(canvas,Point(x1,y1),Point(x2,y2),Scalar(b,g,r),8,LINEAA,0);lineAA表示去掉锯齿imshow(随机绘制演示,canvas);}}16多边形填充与绘制 这节课介绍了2种多边形绘制的实现方式。voidQuickDemo::polylinedrawingdemo(Matimage){MatcanvasMat::zeros(Size(512,512),CV8UC3);Pointp1(100,100);Pointp2(350,100);Pointp3(450,280);Pointp4(320,450);Pointp5(80,400);std::vectorP将5个点装入一个容器内。pts。pushback(p1);未初始化数组容量,只能用pushback操作如果初始化,可以用数组下标操作。pts。pushback(p2);pts。pushback(p3);pts。pushback(p4);pts。pushback(p5);fillPoly(canvas,pts,Scalar(122,155,255),8,0);填充多边形polylines(canvas,pts,true,Scalar(0,0,255),2,8,0);绘制多边形参数1表示画布,参数2表示点集,参数3表示true,参数4颜色参数5表示线宽,参数6表示渲染方式,参数7表示相对左上角(0,0)的位置单个API搞定图片的绘制填充std::vectorstd::vectorPcontours。pushback(pts);drawContours(canvas,contours,1,Scalar(0,0,255),1);参数2表示容器名称,参数3为正表示多边形的绘制,为负表示多边形的填充imshow(多边形绘制,canvas);} 第一种方式,通过标记各个点,然后存储到容器中,之后对容器中的点进行操作。填充多边形调用fillPoly,绘制多边形调用polylines。第二种方式,使用一个API接口绘制。通过一个容器中的存储的点组成的另一个容器。17鼠标操作与响应 鼠标事件响应与绘制!考察基本的图形绘制编程能力。参数1表示鼠标事件。Pointsp(1,1);鼠标的开始的位置Pointep(1,1);Mstaticvoidondraw(intevent,intx,inty,intflags,voiduserdata){Matimage((Mat)userdata);if(eventEVENTLBUTTONDOWN)如果鼠标的左键按下{sp。sp。std::coutstartpointspstd::}elseif(eventEVENTLBUTTONUP){ep。ep。intdxep。xsp。x;intdyep。ysp。y;if(dx0dy0){Rectbox(sp。x,sp。y,dx,dy);imshow(ROI区域,image(box));rectangle(image,box,Scalar(0,0,255),2,8,0);imshow(鼠标绘制,image);sp。x1;sp。y1;复位,为下一次做准备}}elseif(eventEVENTMOUSEMOVE){if(sp。x0sp。y0){ep。ep。intdxep。xsp。x;intdyep。ysp。y;if(dx0dy0){Rectbox(sp。x,sp。y,dx,dy);temp。copyTo(image);rectangle(image,box,Scalar(0,0,255),2,8,0);imshow(鼠标绘制,image);}}}}voidQuickDemo::mousedrawingdemo(Matimage){namedWindow(鼠标绘制,WINDOWAUTOSIZE);setMouseCallback(鼠标绘制,ondraw,(void)(image));设置窗口的回调函数。参数1表示名称,参数2表示调用ondrawimshow(鼠标绘制,image);tempimage。clone();}18图像像素类型的转换与归一化 像素值归一化是很常见的预处理方式,OpenCV支持字节与浮点数的图象显示。voidQuickDemo::normdemo(Matimage){M定义一个名为dst的二值化类型的数据std::coutimage。type()std::打印出来图片的类型image。convertTo(image,CV32F);将dst数据转换成浮点型float32位数据。std::coutimage。type()std::再次打印转换后的数据类型normalize(image,dst,1。0,0,NORMMINMAX);进行归一化操作std::coutdst。type()std::打印归一化操作之后的数据imshow(图像的归一化,dst);显示归一化的图像CV8UC3,CV32FC33通道每个通道8位的UC类型转换后3通道每个通道32位的浮点数}19图像的放缩与插值 介绍基本的图像变换大小的方法。图像的差值处理主要有线性、双线性差值、卢卡斯差值、双立方差值。voidQuickDemo::resizedemo(Matimage){Matzoomin,inthimage。intwimage。resize(image,zoomin,Size(w2,h2),0,0,INTERLINEAR);线性差值操作。imshow(zoomin,zoomin);;resize(image,zoomout,Size(w1。5,h1。5),0,0,INTERLINEAR);imshow(zoomin,zoomout);}20图像的翻转 图像的上下、左右、对角线翻转voidQuickDemo::flipdemo(Matimage){Mflip(image,dst,0);上下翻转x对称flip(image,dst,1);左右翻转y对称flip(image,dst,1);旋转180imshow(图像翻转,dst);}21图像的旋转 图像旋转的基本原理,变换矩阵M的计算,中心位置偏移计算等。voidQuickDemo::rotatedemo(Matimage){Matdst,M;inthimage。定义图片的高度intwimage。定义图片的宽度MgetRotationMatrix2D(Point(w2,h2),45,1。0);doublecosabs(M。atdouble(0,0));doublesinabs(M。atdouble(0,1));M。atdouble(0,2)(nw2w2);M。atdouble(1,2)(nh2h2);参数1原来图像的中心位置。参数2角度是多少。参数3是图像本身大小的放大缩小warpAffine(image,dst,M,Size(nw,nh),INTERLINEAR,0,Scalar(0,0,255));imshow(旋转演示,dst);}22视频文件摄像头使用 本节介绍了如何读取一个视频,以及调用电脑的摄像头。并且对读取到的视频进行操作。voidQuickDemo::videodemo(Matimage){VideoCapturecapture(D:images123。mp4);读取视频的地址M定义一个二值化的framewhile(true){capture。read(frame);读取视频flip(frame,frame,1);图像镜像操作if(frame。empty())如果视频为空的话跳出操作{}imshow(frame,frame);显示视频colorSpaceDemo(frame);对视频调用之前的demointcwaitKey(100);停顿100ms做视频处理都是1if(c27){esc退出应用程序}}capture。release();释放相机的资源} 对读取到的视频操作方式有镜像对称。加各种滤镜等等。23视频处理与保存 视频的属性,SD(标清),HD(高清),UHD(超清),蓝光。如何读取视频文件,以及读取视频文件的属性,衡量视频处理指标:FPS。保存视频时的编码格式。保存视频的实际size和create的size大小保持一致。voidQuickDemo::videodemo(Matimage){VideoCapturecapture(D:images123。mp4);intframewidthcapture。get(CAPPROPFRAMEWIDTH);获取视频的宽度intframeheightcapture。get(CAPPROPFRAMEHEIGHT);获取视频的高度intcountcapture。get(CAPPROPFRAMECOUNT);视频总的帧数fps是衡量处理视频的能力doublefpscapture。get(CAPPROPFPS);std::coutframewidthframewidthstd::std::coutframeheightframeheightstd::std::coutframeFPSfpsstd::std::coutframecountcountstd::VideoWriterwriter(D:test。mp4,capture。get(CAPPROPFOURCC),fps,Size(framewidth,frameheight),true);参数1保存地址。参数2获取图片的格式参数3图片的帧数参数4视频宽高参数5真Mwhile(true){capture。read(frame);flip(frame,frame,1);图像镜像操作if(frame。empty()){}imshow(frame,frame);colorSpaceDemo(frame);writer。write(frame);intcwaitKey(100);停顿100ms做视频处理都是1if(c27){esc退出应用程序}}capture。release();释放相机的资源writer。release();释放存放的资源} 本节课,介绍了视频的一些基本熟悉,紧接介绍如何获取视频的属性,并且通过特定的格式保存到相应的存储位置上。24图像的直方图 直方图是图像的统计学特征。表示了图像的各个像素在0255出现的频率。图像的平移旋转都不会对性质进行改变。缺点:不能表征一张图像。 25直方图的均衡化 用途:用于图像增强,人脸检测,卫星遥感。均衡化的图像只支持单通道。 voidQuickDemo::histogrameqdemo(Matimage){McvtColor(image,gray,COLORBGR2GRAY);直方图均衡化只支持灰度图像,不支持彩色图像。imshow(灰度图像,gray);MequalizeHist(gray,dst);imshow(直方图均衡化,dst);}26图像的卷积操作 卷积的作用,高的往下降,低的往上升。但是会造成信息丢失。产生模糊效果。是一种线性操作,点乘,之后相加。 voidQuickDemo::blurdemo(Matimage){Mblur(image,dst,Size(15,15),Point(1,1));参数1原始图像,参数2卷积之后的图像,参数3卷积的矩阵大小,支持单行或者单列的卷积操作,参数4卷积的起始点。imshow(图像卷积操作,dst);}27高斯模糊 中心的数值最大,离中心距离越远,数值越小。高斯卷积数学表达式说明: voidQuickDemo::gaussianblurdemo(Matimage){MGaussianBlur(image,dst,Size(5,5),15);imshow(高斯模糊,dst);参数1表示初始图像,参数2表示处理后的图像,参数3表示高斯矩阵大小正数而且是奇数,参数4表示西格玛x为15西格玛y为15}28高斯双边模糊 边缘保留的滤波算法!去噪! voidQuickDemo::bifilterdemo(Matimage){MbilateralFilter(image,dst,0,100,0);参数1代表原图,参数2代表处理之后的图像,参数3色彩空间。参数4表示坐标空间,双边是指色彩空间和坐标空间。namedWindow(双边模糊,WINDOWFREERATIO);创建了一个新窗口,参数1表示名称,第二个参数代表一个自由的比例imshow(双边模糊,dst);表示显示在新创建的}29实时视频人脸检测 OpenCV4。x中基于深度神经网络模型的高实时,稳定的人脸检测演示。 dnn::Netnetdnn::readNetFromTensorflow(rootdiropencvfacedetectoruint8。pb,rootdiropencvfacedetector。pbtxt);VideoCapturecapture(D:imagesvideoexampledsh。mp4);Mwhile(true){capture。read(frame);if(frame。empty()){}Matblobdnn::blobFromImage(frame,1。0,Size(300,300),Scalar(104,177,123),false,false);net。setInput(blob);NCHWMatprobsnet。forward();MatdetectionMat(probs。size〔2〕,probs。size〔3〕,CV32F,probs。ptrfloat());解析结果for(inti0;idetectionMat。i){floatconfidencedetectionMat。atfloat(i,2);if(confidence0。5){intx1staticcastint(detectionMat。atfloat(i,3)frame。cols);inty1staticcastint(detectionMat。atfloat(i,4)frame。rows);intx2staticcastint(detectionMat。atfloat(i,5)frame。cols);inty2staticcastint(detectionMat。atfloat(i,6)frame。rows);Rectbox(x1,y1,x2x1,y2y1);rectangle(frame,box,Scalar(0,0,255),2,8,0);}}imshow(人脸检测演示,frame);intcwaitKey(1);if(c27){退出}}