牡丹江网站开发吉林省长春网站建设

当前位置: 首页 > news >正文

牡丹江网站开发,吉林省长春网站建设,怎么上百度推广产品,苏中建设网站计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割OpenCVPytorchNLP自然语言处理 OpenCV 一、OpenCV简介1.1 简介1.2 OpenCV部署1.3 OpenCV模块 二、OpenCV基本操作2.1 图像的基本操作2.1.1 图像的IO操作2.1.2 绘制几何图像2.1.3 获取并修改图像的像素…计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割OpenCVPytorchNLP自然语言处理 OpenCV 一、OpenCV简介1.1 简介1.2 OpenCV部署1.3 OpenCV模块 二、OpenCV基本操作2.1 图像的基本操作2.1.1 图像的IO操作2.1.2 绘制几何图像2.1.3 获取并修改图像的像素点2.1.4 获取图像的属性2.1.5 图像通道的拆分和合并2.1.6 色彩空间的改变 2.2 算数操作2.2.1 图像的加法2.2.2 图像的混合 三、OpenCV图像处理3.1 图像的几何变换3.2 图像的形态学操作3.3 图像的平滑3.4 直方图3.1.4 灰度直方图3.1.5 直方图均衡化 3.5 边缘检测3.5.1 Sobel检测算子3.5.2 Laplacian算子3.5.3 Canny边缘检测 3.6 模板匹配和霍夫变换的应用3.6.1 模板匹配3.6.2 霍夫变换 3.7 图像变化3.7.1 傅里叶变换3.7.2 高通和低通滤波3.7.3 带通和带阻滤波 3.8 轮廓检测与轮廓特征3.8.1 轮廓检测3.8.2 轮廓特征 3.9 图像分割3.9.1 全阈值分割3.9.2 自适应阈值分割3.9.3 Ostu阈值大律法3.9.4 分水岭算法3.9.5 GrabCut算法 四、图像的特征提取与描述4.1 Harris角点检测4.2 Shi-Tomasi角点检测4.3 sift算法4.4 fast检测算法4.5 orb角点检测 五、视频操作5.1 视频读写5.2 视频保存5.3 视频追踪5.3.1 meanshift算法5.3.2 camshift算法 六、人脸、眼睛检测案例6.1 人脸以及眼睛检测(图片)6.2 人脸以及眼睛检测(视频) 一、OpenCV简介 1.1 简介 OpenCV是⼀个计算机视觉处理开源软件库⽀持与计算机视觉和机器学习相关的众多算法。 1.2 OpenCV部署 创建虚拟环境 在Anaconda终端中创建虚拟环境OpenCV_env conda create –name OpenCV_env激活虚拟环境 conda activate OpenCV_env安装OpenCV 安装OpenCV之前需要先安装numpy, matplotlib pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple如果我们要利用SIFT和SURF算法进行特征提取时还需安装 pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple查看是否安装成功 import cv2 cv2.version1.3 OpenCV模块 core模块实现了最核心的数据结构及其基本运算如绘图函数、数组操作相关函数等。highgui模块实现了视频与图像的读取、显示、存储等接口。imgproc模块实现了图像处理的基础方法包括图像滤波、图像的几何变换、平滑、阈值分割、形态学处理、边缘检测、目标检测、运动分析和对象跟踪等。features2d模块用于提取图像特征以及特征匹配nonfree模块实现了一些专利算法如sift特征。objdetect模块实现了一些目标检测的功能经典的基于Haar、LBP特征的人脸检测基于HOG的行人、汽车等目标检测分类器使用CascadeClassification级联分类和Latent SVM等。 二、OpenCV基本操作 2.1 图像的基本操作 2.1.1 图像的IO操作

读取图像

import numpy as np import cv2 as cv import matplotlib.pyplot as plt#以灰度图的方式读取图像 img cv.imread(dog.jpg,0)# 显示图像

Jupyter Notebook 是一个基于 Web 的交互式计算环境不支持传统的 GUI 窗口显示

cv.imshow(image,img)

cv.waitKey(0)

plt.imshow(img,cmapgray)# 以彩色图的方式读取图像 img1 cv.imread(dog.jpg,1)

img1[:,:,::-1]将BGR图像转换为RGB图像

plt.imshow(img1[:,:,::-1])使用cv.imread()读取的图像是BGR而matplot使用是的RGB图像
img.shape# 图像保存 cv.imwrite(dog1.jpg,img)2.1.2 绘制几何图像

创建图像

img np.zeros((512,512,3),np.uint8)# 直线的起点、终点、颜色、宽度 cv.line(img,(0,0),(512,512),(255,0,0),5)

圆形的圆心、半径、颜色、填充、宽度

cv.circle(img,(250,250),130,(0,255,0),-1,5)

矩形的左上角、右下角、颜色、宽度

cv.rectangle(img,(50,50),(450,450),(0,0,255),5)

图像中添加文字 文本、位置、字体、字体大小、颜色、宽度

cv.putText(img,OpenCV,(130,250),cv.FONT_HERSHEY_COMPLEX,2,(255,0,255),2) plt.imshow(img[:,:,::-1]) plt.show()2.1.3 获取并修改图像的像素点 img2 np.zeros((250,250,3),np.uint8) plt.imshow(img2[:,:,::-1])# 获取位置50200的像素点 img2[50,200]#获取位置50100蓝色通道的强度值0表示蓝色1表示绿色2表示红色 img2[50,100,0]# 修改位置50100的像素值 img2[50,100] [255,0,0]plt.imshow(img2[:,:,::-1])2.1.4 获取图像的属性 img2.shapeimg2.sizeimg2.dtype2.1.5 图像通道的拆分和合并

通道拆分

b,g,r cv.split(img1)plt.imshow(b,cmapgray)# 通道合并 img3 cv.merge((b,g,r))plt.imshow(img3[:,:,::-1])2.1.6 色彩空间的改变

将BGR通道图像转变为HSV通道图像

img3 cv.cvtColor(img1,cv.COLOR_BGR2HSV)plt.imshow(img3[:,:,::-1])# 将BGR通道图像变为GRAY通道图像 img4 cv.cvtColor(img1,cv.COLOR_BGR2GRAY)plt.imshow(img4,cmapgray)2.2 算数操作 2.2.1 图像的加法

读取图像

img_sun cv.imread(sun.jpg) img_tree cv.imread(tree.jpg)plt.imshow(img_tree[:,:,::-1])plt.imshow(img_sun[:,:,::-1])# 查看图像形状 img_sun.shape,img_tree.shape形状相同才能进行相加

缩小图形形状

img_sun cv.resize(img_sun,(350,251))img_sun.shape# 加法操作 img_cvadd cv.add(img_sun,img_tree) img_add img_sunimg_treefig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img_cvadd[:,:,::-1]) axes[0].set_title(cv中的加法) axes[1].imshow(img_add[:,:,::-1]) axes[1].set_title(直接相加) plt.show()2.2.2 图像的混合

读取图像

img_sun cv.imread(sun.jpg) img_tree cv.imread(tree.jpg)# 缩小图形形状 img_sun cv.resize(img_sun,(350,251))# 图像混合gamma参数会影响最终图像的亮度 img5 cv.addWeighted(img_sun,0.3,img_tree,0.7,0)# 图像的显示 plt.imshow(img5[:,:,::-1]) plt.show()三、OpenCV图像处理 3.1 图像的几何变换 import cv2 as cv import matplotlib.pyplot as plt图像缩放

读取图片

img cv.imread(dog.jpg)# 图像缩放

绝对尺寸

rows,cols img.shape[:2] res cv.resize(img,(2*cols,2*rows))

相对尺寸

res1 cv.resize(img,None,fx0.5,fy0.5)# 图像显示 fig,axes plt.subplots(1,3,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原始图像) axes[1].imshow(res[:,:,::-1]) axes[1].set_title(绝对尺寸) axes[2].imshow(res1[:,:,::-1]) axes[2].set_title(相对尺寸) plt.show()图像平移 import numpy as npimg cv.imread(dog.jpg)# 像素点平移50100 rows,cols img.shape[:2]

平移矩阵

m np.float32([[1,0,50],[0,1,100]]) res cv.warpAffine(img,m,(cols,rows))fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原始图像) axes[1].imshow(res[:,:,::-1]) axes[1].set_title(平移后图像) plt.show()图像旋转 img cv.imread(dog.jpg)rows,cols img.shape[:2]

旋转矩阵

m cv.getRotationMatrix2D((cols//2,rows//2),90,0.5) res cv.warpAffine(img,m,(cols,rows))fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原始图像) axes[1].imshow(res[:,:,::-1]) axes[1].set_title(旋转后图像) plt.show()仿射变换 rows,cols img.shape[:2]

原点集

pts1 np.float32([[50,50],[200,50],[50,200]])

目标点集

pts2 np.float32([[100,100],[200,50],[100,250]])

仿射变化矩阵

m cv.getAffineTransform(pts1,pts2)res cv.warpAffine(img,m,(cols,rows))fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原始图像) axes[1].imshow(res[:,:,::-1]) axes[1].set_title(仿射后图像) plt.show()投射变换 img cv.imread(dog.jpg)rows,cols img.shape[:2]

投射变换矩阵

pts1 np.float32([[56,65],[368,52],[28,387],[389,390]]) pts2 np.float32([[100,145],[300,100],[80,290],[310,300]]) m cv.getPerspectiveTransform(pts1,pts2)

进行变换

res cv.warpPerspective(img,m,(cols,rows))fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原图像) axes[1].imshow(res[:,:,::-1]) axes[1].set_title(仿射后图像) plt.show()图像金字塔 img cv.imread(dog.jpg)# 上采样 img_up cv.pyrUp(img)

下采样

img_down cv.pyrDown(img)fig,axes plt.subplots(1,3,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原图像) axes[1].imshow(img_up[:,:,::-1]) axes[1].set_title(上采样图像) axes[2].imshow(img_down[:,:,::-1]) axes[2].set_title(下采样图像) plt.show()3.2 图像的形态学操作 膨胀和腐蚀 img cv.imread(img_five.jpg)# 创建核结构 kernel np.ones((5,5),np.uint8)# 腐蚀 erode cv.erode(img,kernel)

膨胀

dilate cv.dilate(img,kernel)fig,axes plt.subplots(1,3,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(原图像) axes[1].imshow(erode[:,:,::-1]) axes[1].set_title(腐蚀后图像) axes[2].imshow(dilate[:,:,::-1]) axes[2].set_title(膨胀后图像) plt.show()开闭运算 img_1 cv.imread(img1.png) img_2 cv.imread(img2.png)kernel np.ones((10,10),np.uint8) Open cv.morphologyEx(img_1,cv.MORPH_OPEN,kernel) Close cv.morphologyEx(img_2,cv.MORPH_CLOSE,kernel)fig,axes plt.subplots(2,2,figsize(10,8)) axes[0][0].imshow(img_1[:,:,::-1]) axes[0][0].set_title(原图像) axes[0,1].imshow(Open[:,:,::-1]) axes[0,1].set_title(开运算图像) axes[1,0].imshow(img_2[:,:,::-1]) axes[1,0].set_title(原图像) axes[1,1].imshow(Close[:,:,::-1]) axes[1,1].set_title(闭运算图像) plt.show()礼貌和黑帽 img_1 cv.imread(img1.png) img_2 cv.imread(img2.png)kernel np.ones((10,10),np.uint8) Open cv.morphologyEx(img_1,cv.MORPH_TOPHAT,kernel) Close cv.morphologyEx(img_2,cv.MORPH_BLACKHAT,kernel)fig,axes plt.subplots(2,2,figsize(10,8)) axes[0][0].imshow(img_1[:,:,::-1]) axes[0][0].set_title(原图像) axes[0,1].imshow(Open[:,:,::-1]) axes[0,1].set_title(礼帽运算结果) axes[1,0].imshow(img_2[:,:,::-1]) axes[1,0].set_title(原图像) axes[1,1].imshow(Close[:,:,::-1]) axes[1,1].set_title(黑帽运算结果) plt.show()3.3 图像的平滑 img_girl cv.imread(girl_img.png)# 均值滤波 blur cv.blur(img_girl,(7,7))

高斯滤波

gaublur cv.GaussianBlur(img_girl,(9,9),0)

中值滤波

medblur cv.medianBlur(img_girl,5)fig,axes plt.subplots(2,2,figsize(10,8)) axes[0][0].imshow(img_girl[:,:,::-1]) axes[0][0].set_title(原图像) axes[0,1].imshow(blur[:,:,::-1]) axes[0,1].set_title(均值滤波运算结果) axes[1,0].imshow(gaublur[:,:,::-1]) axes[1,0].set_title(高斯滤波结果) axes[1,1].imshow(medblur[:,:,::-1]) axes[1,1].set_title(中值滤波结果) plt.show()3.4 直方图 3.1.4 灰度直方图 直方图的计算和绘制 img_dog cv.imread(dog.jpg,0)# 统计灰度图 histr cv.calcHist(img_dog,[0],None,[256],[0,256])fig,axes plt.subplots(1,2,figsize(18,6)) axes[0].imshow(img_dog,cmapgray) axes[1].plot(histr) axes[1].grid() axes[1].set_xlabel(Pixel Value) axes[1].set_ylabel(Frequency)

调整布局

plt.tight_layout() plt.show()掩码的应用 img_dog1 cv.imread(dog.jpg,0)# 创建遮挡 mask np.zeros(img_dog1.shape[:2],np.uint8) mask[50:130,150:230] 255# 进行按位与运算 mask_img cv.bitwise_and(img_dog1,img_dog1,maskmask)mask_histr cv.calcHist([img_dog1],[0],mask,[256],[0,256])fig,axes plt.subplots(2,2,figsize(10,8)) axes[0,0].imshow(img_dog1,cmapgray) axes[0,0].set_title(原图) axes[0,1].imshow(mask,cmapgray) axes[0,1].set_title(遮挡) axes[1,0].imshow(mask_img,cmapgray) axes[1,0].set_title(遮挡后数据) axes[1,1].plot(mask_histr) axes[1,1].set_title(灰度直方图) plt.show()3.1.5 直方图均衡化 应用 img_dog cv.imread(dog.jpg,0)dst cv.equalizeHist(img_dog)fig,axes plt.subplots(1,2,figsize(18,6)) axes[0].imshow(img_dog,cmapgray) axes[0].set_title(原图) axes[1].imshow(dst,cmapgray) axes[1].set_title(均衡化后的结果)

plt.tight_layout()

plt.show()自适应的直方图均衡化 img_dog cv.imread(dog.jpg,0)clahe cv.createCLAHE(clipLimit2,tileGridSize(12,12)) cl1 clahe.apply(img_dog)fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img_dog,cmapgray) axes[0].set_title(原图) axes[1].imshow(cl1,cmapgray) axes[1].set_title(自适应后图像) plt.show()3.5 边缘检测 3.5.1 Sobel检测算子 import cv2 as cv import matplotlib.pyplot as plt import numpy as npimg_horse cv.imread(horse.jpg,0)# 计算Sobel卷积结果边缘检测 x cv.Sobel(img_horse,cv.CV_16S,1,0) y cv.Sobel(img_horse,cv.CV_16S,0,1)# 数据转换将其缩放到uint8 scale_x cv.convertScaleAbs(x) scale_y cv.convertScaleAbs(y)# 结果合成 gamma为正亮度增加0亮度不变负数亮度降低 res cv.addWeighted(scale_x,0.5,scale_y,0.5,0)fig,axes plt.subplots(1,2,figsize(9,10)) axes[0].imshow(img_horse,cmapgray) axes[0].set_title(原图) axes[1].imshow(res,cmapplt.cm.gray) axes[1].set_title(Sobel滤波后结果) plt.show()# ksize为-1时使用3x3的Scharr滤波器 x cv.Sobel(img_horse,cv.CV_16S,1,0,ksize-1) y cv.Sobel(img_horse,cv.CV_16S,0,1,ksize-1)scale_x cv.convertScaleAbs(x) scale_y cv.convertScaleAbs(y) res cv.addWeighted(scale_x,0.5,scale_y,0.5,0)fig,axes plt.subplots(1,2,figsize(9,10)) axes[0].imshow(img_horse,cmapgray) axes[0].set_title(原图) axes[1].imshow(res,cmapplt.cm.gray) axes[1].set_title(Scharr滤波后结果) plt.show()3.5.2 Laplacian算子 img_horse cv.imread(horse.jpg,0)res cv.Laplacian(img_horse,cv.CV_16S,ksize3) scale_res cv.convertScaleAbs(res)fig,axes plt.subplots(1,2,figsize(9,10)) axes[0].imshow(img_horse,cmapgray) axes[0].set_title(原图) axes[1].imshow(scale_res,cmapplt.cm.gray) axes[1].set_title(Laplacian滤波后结果) plt.show()3.5.3 Canny边缘检测 img_horse cv.imread(horse.jpg,0)# Canny边缘检测min_threshold最小阈值 min_threshold 20 max_threshold 100 res cv.Canny(img_horse,min_threshold,max_threshold)fig,axes plt.subplots(1,2,figsize(9,10)) axes[0].imshow(img_horse,cmapgray) axes[0].set_title(原图) axes[1].imshow(res,cmapplt.cm.gray) axes[1].set_title(Canny滤波后结果) plt.show()3.6 模板匹配和霍夫变换的应用 3.6.1 模板匹配 img_party cv.imread(party.jpg) template cv.imread(template.jpg)h,w template.shape[:2]# 模板匹配 res cv.matchTemplate(img_party,template,cv.TM_SQDIFF)

返回图像最佳匹配位置确定左上角的坐标

min_val,max_val,min_loc,max_loc cv.minMaxLoc(res)# 使用平方差时(cv.TM_SQDIFF)最小值为最佳匹配位置 top_left min_loc bottom_right (top_left[0]h,top_left[1]w)cv.rectangle(img_party,top_left,bottom_right,(0,255,0),2) fig,axes plt.subplots(1,2,figsize(10,8),gridspec_kw{width_ratios: [1, 6]}) axes[0].imshow(template[:,:,::-1]) axes[0].set_title(匹配模板) axes[1].imshow(img_party[:,:,::-1]) axes[1].set_title(匹配结果) plt.tight_layout() plt.show()3.6.2 霍夫变换

读取图像

img_rili cv.imread(rili.jpg)# 使用Canny转换为二值图 gray cv.cvtColor(img_rili,cv.COLOR_BGR2GRAY) edges cv.Canny(gray,100,200)# 霍夫直线变换 lines cv.HoughLines(edges,0.8,np.pi/180,150)# 检查是否检测到直线 for line in lines:rho, theta line[0]a np.cos(theta)b np.sin(theta)x0 a * rhoy0 b * rhox1 int(x0 - 1000 * b)y1 int(y0 1000 * a)x2 int(x0 1000 * b)y2 int(y0 - 1000 * a)cv.line(img_rili, (x1, y1), (x2, y2), (0, 0, 255), 2)# 使用matplotlib显示图像 plt.imshow(img_rili[:, :, ::-1]) plt.xticks([]), plt.yticks([]) plt.title(霍夫变换直线检测) plt.show()3.7 图像变化 3.7.1 傅里叶变换 读取图像 读取图像并转换为灰度图像。 傅里叶变换 正变换将图像转换为频域表示。 频谱中心化将频谱的低频部分移到中心高频部分移到四周。 计算频谱和相位谱将复数形式的频谱转换为幅度和相位并对幅度谱进行对数变换。 傅里叶逆变换 反变换将频域表示转换回时域或空域。 计算灰度值计算逆变换后的图像的幅度。 显示结果 使用 matplotlib 显示原始图像、频谱图和逆变换后的图像。 img_dog cv.imread(dog.jpg,0)# 傅里叶正变换,cv.DFT_COMPLEX_OUTPUT指定输出为复数形式 dft cv.dft(np.float32(img_dog),flagscv.DFT_COMPLEX_OUTPUT)

频谱中心化

dft_shift np.fft.fftshift(dft)# 计算频谱和相位谱 mag,angle cv.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,-1],angleInDegreesTrue)

对幅度谱进行对数变换以便更好地可视化。对数变换可以压缩动态范围使图像的细节更明显。

mag 20 * np.log(mag)# 傅里叶反变换 img_back cv.idft(dft) img_back cv.magnitude(img_back[:,:,0],img_back[:,:,1])fig,axes plt.subplots(2,2,figsize(10,8)) axes[0,0].imshow(img_dog,cmapgray) axes[0,0].set_title(原图) axes[0,1].imshow(mag,cmapgray) axes[0,1].set_title(频谱) axes[1,0].imshow(angle,cmapgray) axes[1,0].set_title(相位谱) axes[1,1].imshow(img_back,cmapgray) axes[1,1].set_title(逆变换结果) plt.show()3.7.2 高通和低通滤波

高通滤波

dog_img cv.imread(dog.jpg,0)rows,cols dog_img.shape mask np.ones((rows,cols,2),np.uint8) mask[int(rows/2)-30:int(rows/2)30,int(cols/2)-30:int(cols/2)30,:] 0# 正变换 dft cv.dft(np.float32(dog_img),flagscv.DFT_COMPLEX_OUTPUT)

频谱中心化

dft_shift np.fft.fftshift(dft)

滤波(移除低频)

dft_shift dft_shift * mask

频谱中心化

dft_shift np.fft.fftshift(dft_shift)# 反变化 img_back cv.idft(dft_shift)

计算灰度值

img_back cv.magnitude(img_back[:,:,0],img_back[:,:,1])fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(dog_img, cmap gray) axes[0].set_title(原图) axes[1].imshow(img_back, cmap gray) axes[1].set_title(高通滤波结果) plt.show()# 低通滤波 dog_img cv.imread(dog.jpg,0)rows,cols dog_img.shape mask np.zeros((rows,cols,2),np.uint8) mask[int(rows/2)-30:int(rows/2)30,int(cols/2)-30:int(cols/2)30,:] 1# 正变换 dft cv.dft(np.float32(dog_img),flagscv.DFT_COMPLEX_OUTPUT)

频谱中心化

dft_shift np.fft.fftshift(dft)

滤波(移除低频)

dft_shift dft_shift * mask

频谱中心化

dft_shift np.fft.fftshift(dft_shift)# 反变化 img_back cv.idft(dft_shift)

计算灰度值

img_back cv.magnitude(img_back[:,:,0],img_back[:,:,1])fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(dog_img, cmap gray) axes[0].set_title(原图) axes[1].imshow(img_back, cmap gray) axes[1].set_title(低通滤波结果) plt.show()3.7.3 带通和带阻滤波

带通滤波

dog_img cv.imread(dog.jpg,0)rows,cols dog_img.shape mask1 np.ones((rows,cols,2),np.uint8) mask1[int(rows/2)-8:int(rows/2)8,int(cols/2)-8:int(cols/2)8] 0 mask2 np.zeros((rows,cols,2),np.uint8) mask2[int(rows/2)-80:int(rows/2)80,int(cols/2)-80:int(cols/2)80] 1 mask mask1*mask2# 正变换 dft cv.dft(np.float32(dog_img),flagscv.DFT_COMPLEX_OUTPUT)

频谱中心化

dft_shift np.fft.fftshift(dft)

滤波(移除低频)

dft_shift dft_shift * mask

频谱中心化

dft_shift np.fft.fftshift(dft_shift)# 反变化 img_back cv.idft(dft_shift)

计算灰度值

img_back cv.magnitude(img_back[:,:,0],img_back[:,:,1])fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(dog_img, cmap gray) axes[0].set_title(原图) axes[1].imshow(img_back, cmap gray) axes[1].set_title(带通滤波结果) plt.show()# 带阻滤波 dog_img cv.imread(dog.jpg,0)rows,cols dog_img.shape mask np.ones((rows,cols,2),np.uint8) mask[int(rows/2)60:int(rows/2)130,int(cols/2)-130:int(cols/2)130] 0 mask[int(rows/2)-130:int(rows/2)-60,int(cols/2)-130:int(cols/2)130] 0 mask[int(rows/2)-130:int(rows/2)130,int(cols/2)60:int(cols/2)130] 0 mask[int(rows/2)-130:int(rows/2)130,int(cols/2)-130:int(cols/2)-60] 0# 正变换 dft cv.dft(np.float32(dog_img),flagscv.DFT_COMPLEX_OUTPUT)

频谱中心化

dft_shift np.fft.fftshift(dft)

滤波(移除低频)

dft_shift dft_shift * mask

频谱中心化

dft_shift np.fft.fftshift(dft_shift)# 反变化 img_back cv.idft(dft_shift)

计算灰度值

img_back cv.magnitude(img_back[:,:,0],img_back[:,:,1])fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(dog_img, cmap gray) axes[0].set_title(原图) axes[1].imshow(img_back, cmap gray) axes[1].set_title(带阻滤波结果) plt.show()3.8 轮廓检测与轮廓特征 3.8.1 轮廓检测 import cv2 as cv import matplotlib.pyplot as plt import numpy as npditu cv.imread(ditu.jpg)

复制原图

img_ditu ditu.copy() imggray cv.cvtColor(ditu,cv.COLOR_BGR2GRAY) canny cv.Canny(imggray,120,255)# 轮廓提取 contours,hierarchy cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

将轮廓绘制在图形上

img cv.drawContours(ditu,contours,-1,(0,0,255),2)fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img_ditu[:,:,::-1]) axes[0].set_title(原图) axes[1].imshow(img[:,:,::-1]) axes[1].set_title(轮廓) plt.show()3.8.2 轮廓特征 轮廓面积 area sum(cv.contourArea(cnt) for cnt in contours) area轮廓周长 perimeter sum(cv.arcLength(cnt,True) for cnt in contours) perimeter轮廓近似

读取图像

img cv.imread(jinsi.jpg)# 灰度转换 imggray cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 二值化处理 ret, thresh cv.threshold(imggray, 127, 255, cv.THRESH_BINARY)# 轮廓提取 contours, hierarchy cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)# 初始化绘制图像 img_contours img.copy() img_approx img.copy()# 处理所有轮廓 for cnt in contours:# 计算轮廓的弧长arc_length cv.arcLength(cnt, True)# 计算近似多边形epsilon 0.1 * arc_lengthapprox cv.approxPolyDP(cnt, epsilon, True)# 绘制原始轮廓和近似多边形(-1表示绘制所有轮廓)img_contours cv.drawContours(img_contours, [cnt], -1, (0, 255, 0), 2)img_approx cv.drawContours(img_approx, [approx], -1, (0, 255, 0), 2)# 显示图像 fig, axes plt.subplots(1, 3, figsize(10, 13)) axes[0].imshow(ditu[:, :, ::-1]) axes[0].set_title(原图) axes[1].imshow(img_contours[:, :, ::-1]) axes[1].set_title(原始轮廓) axes[2].imshow(img_approx[:, :, ::-1]) axes[2].set_title(近似多边形) plt.show()凸包 star cv.imread(star.jpg)# 灰度处理 imggray cv.cvtColor(star,cv.COLOR_BGR2GRAY)

边缘检测

canny cv.Canny(imggray,50,200)# 获取轮廓 contours,hierarchy cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)# 图像复制 img_star star.copy()#凸包检测 Hulls [] for cnt in contours:hull cv.convexHull(cnt)Hulls.append(hull)# 绘制图形 img_contour cv.drawContours(star,contours,-1,(255,0,0),2) img_hull cv.drawContours(img_star,Hulls,-1,(255,0,0),2)fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img_contour[:,:,::-1]) axes[0].set_title(轮廓检测结果) axes[1].imshow(img_hull[:,:,::-1]) axes[1].set_title(凸包结果) plt.show()边界矩形 rect cv.imread(rect.jpg)# 灰度处理 imggray cv.cvtColor(rect,cv.COLOR_BGR2GRAY)

转换为二值化

ret,thresh cv.threshold(imggray,127,255,0)# 轮廓提取 contours,hierarchy cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)# 图像复制 rect_img rect.copy()# 直边界矩形 bounding_box [] for cnt in contours:x,y,w,h cv.boundingRect(cnt)bounding_box.append((x,y,w,h)) for x,y,w,h in bounding_box:cv.rectangle(rect,(x,y),(xw,yh),(0,255,0),2)# 旋转边界矩形 min_area_rects [] for cnt in contours:rect_min cv.minAreaRect(cnt)box cv.boxPoints(rect_min)box np.int0(box)min_area_rects.append(box) for box in min_area_rects:cv.polylines(rect_img,[box],True,(0,255,0),2)fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(rect[:,:,::-1]) axes[0].set_title(直边界矩形) axes[0].set_xticks([]),axes[0].set_yticks([]) axes[1].imshow(rect_img[:,:,::-1]) axes[1].set_title(旋转边界矩形) axes[1].set_xticks([]),axes[1].set_yticks([]) plt.show()最小外接圆 img cv.imread(rect.jpg)imggray cv.cvtColor(img,cv.COLOR_BGR2GRAY) ret,thresh cv.threshold(imggray,127,255,0)contours,hierarchy cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)boundings [] for cnt in contours:(x,y),radius cv.minEnclosingCircle(cnt)center (int(x),int(y))radius int(radius)boundings.append((center,radius)) for center,radius in boundings:cv.circle(img,center,radius,(0,255,0),2)plt.imshow(img[:,:,::-1]) plt.xticks([]) plt.yticks([]) plt.show()椭圆拟合 img cv.imread(rect.jpg)imggray cv.cvtColor(img,cv.COLOR_BGR2GRAY) ret,thresh cv.threshold(imggray,127,255,0)contours,hierarchy cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)boundings [] for cnt in contours:# 过滤掉点数少于5个和面积过小的轮廓if len(cnt) 5 and cv.contourArea(cnt) 100:ellipse cv.fitEllipse(cnt)boundings.append(ellipse) for ellipse in boundings:cv.ellipse(img,ellipse,(0,255,0),2)plt.imshow(img[:,:,::-1]) plt.xticks([]) plt.yticks([]) plt.show()3.9 图像分割 3.9.1 全阈值分割 img cv.imread(gradient.jpg,0)ret,thresh1 cv.threshold(img,127,255,cv.THRESH_BINARY) ret,thresh2 cv.threshold(img,127,255,cv.THRESH_BINARY_INV) ret,thresh3 cv.threshold(img,127,255,cv.THRESH_TRUNC) ret,thresh4 cv.threshold(img,127,255,cv.THRESH_TOZERO) ret,thresh5 cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)titles [原图,阈值二值化,阈值反二值化,截断,阈值取零,阈值反取零] images [img,thresh1,thresh2,thresh3,thresh4,thresh5] plt.figure(figsize(10,8)) for i in range(6):plt.subplot(2,3,i1)plt.imshow(images[i],cmapgray)plt.title(titles[i])plt.show()3.9.2 自适应阈值分割 fruit cv.imread(fruit.jpg,0)# 固定阈值 ret,threshold cv.threshold(fruit,127,225,cv.THRESH_BINARY)

自适应阈值

领域内求平均值

th1 cv.adaptiveThreshold(fruit,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,4)

领域内高斯加权

th2 cv.adaptiveThreshold(fruit,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,17,6)title [原图,固定阈值,自适应阈值(求均值),自适应阈值(高斯加权)] images [fruit,threshold,th1,th2]plt.figure(figsize(10,8)) for i in range(4):plt.subplot(2,2,i1)plt.imshow(images[i],cmapgray)plt.title(title[i]) plt.show()3.9.3 Ostu阈值大律法 littledog cv.imread(littledog.jpg,0)# 固定阈值 ret,thresh cv.threshold(littledog,40,255,cv.THRESH_BINARY)

ostu分割

ret1,thresh2 cv.threshold(littledog,0,255,cv.THRESH_BINARYcv.THRESH_OTSU)fig,axes plt.subplots(1,3,figsize(10,8)) axes[0].imshow(littledog,cmapgray) axes[0].set_title(原图) axes[1].imshow(thresh,cmapgray) axes[1].set_title(全阈值分割) axes[2].imshow(thresh2,cmapgray) axes[2].set_title(OStu分割) plt.show()3.9.4 分水岭算法 img cv.imread(horse.jpg)imggray cv.cvtColor(img,cv.COLOR_BGR2GRAY)

边缘检测

canny cv.Canny(imggray,127,255)

轮廓检测

contours,hierarchy cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

初始化标记图像

marks np.zeros(img.shape[:2],np.int32)# 绘制轮廓 for index in range(len(contours)):# index-1 绘制所有的轮廓非负数要绘制的轮廓的索引marks cv.drawContours(marks,contours,index,(index,index,index),1,8,hierarchy)# 使用分水岭算法

img必须是8位无符号整数的三通道图像marks必须是32位有符号整数的单通道图像

返回值正整数表示该像素属于某个特定区域-1表示该像素是区域的边界

marks cv.watershed(img,marks)# 生成随机颜色 colours np.zeros((np.max(marks) 1,3)) for i in range(len(colours)):aa np.random.uniform(0,255)bb np.random.uniform(0,255)cc np.random.uniform(0,255)colours[i] np.array([aa,bb,cc],np.uint8)# 对每个区域进行颜色填充 bgrimg np.zeros(img.shape,np.uint8) index 0 for i in range(marks.shape[0]):for j in range(marks.shape[1]):index marks[i][j]if index -1:bgrimg[i][j] np.array([255,255,255])else:bgrimg[i][j] colours[index]plt.imshow(bgrimg[:,:,::-1]) plt.title(图像分割结果) plt.show()3.9.5 GrabCut算法 img cv.imread(liying.jpg)masks np.zeros(img.shape[:2],np.uint8)

矩形窗口指定前景区域

rect [260,50,740,730]# 前景和背景分割 cv.grabCut(img,masks,tuple(rect),None,None,30,cv.GC_INIT_WITH_RECT)# 抠取图像 mask2 np.where((masks2)|(masks0),0,1).astype(uint8) img_show img * mask2[:,:,np.newaxis]

将矩形绘制在图像上

cv.rectangle(img,(260,50),(1000,780),(255,0,0),2)fig,axes plt.subplots(1,2,figsize(10,8)) axes[0].imshow(img[:,:,::-1]) axes[0].set_title(矩形框选位置) axes[1].imshow(img_show[:,:,::-1]) axes[1].set_title(扣取结果) plt.show()四、图像的特征提取与描述 图像特征要有区分性容易被比较。一般认为角点、斑点等是比较好的图像特征特征检测找到图像中的特征特征描述对特征及其周围的区域描述 4.1 Harris角点检测 Harris角点检测的思想是通过图像的局部的小窗口观察图像角点的特征是窗口沿任意方向移动都会导致图像灰度明显变化。 import cv2 as cv import matplotlib.pyplot as plt import numpy as np# 对棋盘进行角点检测 qipan cv.imread(qipan.jpg)gray cv.cvtColor(qipan,cv.COLOR_BGR2GRAY) gray np.float32(gray)

Harris角点检测

2,blockSize计算每个像素的角点响应时考虑的窗口大小

3,Sobel 算子用于计算图像的梯度进而用于计算角点响应。

0.04,用于平衡角点检测的灵敏度

dst cv.cornerHarris(gray,2,3,0.04)

设置阈值选择 dst 中角点响应值大于阈值的像素位置

qipan[dst 0.001*dst.max()] [0,255,0]plt.figure(figsize(10,8)) plt.imshow(qipan[:,:,::-1]) plt.show()4.2 Shi-Tomasi角点检测 tv cv.imread(tv.jpg) gray cv.cvtColor(tv,cv.COLOR_BGR2GRAY)# 提取角坐标 conners cv.goodFeaturesToTrack(gray,1000,0.01,10)

绘制角点

for i in conners:# 将坐标展平为一维x,y i.ravel()x,y int(x),int(y)cv.circle(tv,(x,y),3,(0,255,0),-1)plt.figure(figsize(10,8)) plt.imshow(tv[:,:,::-1]) plt.show()4.3 sift算法 通过多尺度空间检测极值点作为关键点确保尺度不变性再对关键点邻域进行方向赋值确保旋转不变性从而实现对图像特征的稳定提取。 tv cv.imread(tv.jpg)gray cv.cvtColor(tv,cv.COLOR_BGR2GRAY)# 实例化shif sift cv.xfeatures2d.SIFT_create()

角点检测kp角点的信息包括坐标方向等 des角点描述

kp, des sift.detectAndCompute(gray,None)

绘制角点

cv.drawKeypoints(tv,kp,tv,flagscv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)plt.figure(figsize(10,8)) plt.imshow(tv[:,:,::-1]) plt.show()4.4 fast检测算法 若一个像素周围有一定数量的像素与该点像素值不同则认为其为角点 tv cv.imread(tv.jpg)# 实例化fast对象 fast cv.FastFeatureDetector_create(threshold30)

检测关键的

kp fast.detect(tv,None)

绘制关键点默认开启非极大值抑制抑制候选角点的重叠

img1 cv.drawKeypoints(tv,kp,None,(0,0,255))# 关闭非极大值抑制 fast.setNonmaxSuppression(0) kp fast.detect(tv,None) img2 cv.drawKeypoints(tv,kp,None,(0,0,255))plt.figure(figsize(10,8)) plt.subplot(121) plt.imshow(img1[:,:,::-1]) plt.title(开启非极大值抑制) plt.subplot(122) plt.imshow(img2[:,:,::-1]) plt.title(关闭非极大值抑制) plt.show()4.5 orb角点检测 tv cv.imread(tv.jpg)# 实例化ORB

nfeatures设置要检测的最大特征点数量

orb cv.ORB_create(nfeatures200)

角点检测

kp,des orb.detectAndCompute(tv,None)

绘制角点

cv.drawKeypoints(tv,kp,tv,(0,255,0))plt.figure(figsize(5,4)) plt.imshow(tv[:,:,::-1]) plt.show()五、视频操作 import cv2 as cv import numpy as np import matplotlib.pyplot as plt5.1 视频读写 video_ying cv.VideoCapture(赵丽颖.mp4)# 查看是否捕获成功 video_ying.isOpened()# 判断是否读取成功 while(video_ying.isOpened()):# 获取每一帧图像ret,frame video_ying.read()if ret True:cv.imshow(frame,frame)# 每一帧间隔50秒按q退出if cv.waitKey(50) 0xFF ord(q):break

释放VideoCapture对象关闭视频文件

video_ying.release()

关闭OpenCV所创建的窗口

cv.destroyAllWindows()5.2 视频保存

读取视频

cap cv.VideoCapture(赵丽颖.mp4)# 获取图像的属性宽度和高度并将其转换为整数 frame_width int(cap.get(3)) frame_height int(cap.get(4))# 创建保存视频的对象设置编码格式帧率图像的宽度和高度 out cv.VideoWriter(outpy.avi, cv.VideoWriter_fourcc(M, J, P, G), 10, (frame_width, frame_height))# 循环读取视频中的每一帧图像 while True:# 获取视频中的每一帧图像ret, frame cap.read() # 如果读取成功将每一帧图像写入到输出文件中if ret True:out.write(frame)else:break# 释放资源 cap.release() out.release() cv.destroyAllWindows()5.3 视频追踪 目标追踪视频中的小柯基 5.3.1 meanshift算法 简单迭代次数少。但不能适应运动目标的形状和大小的变化 import cv2 as cv import numpy as np

视频捕获

video_dog cv.VideoCapture(dog.mp4)# 获取第一帧图像并指定目标位置 ret, frame video_dog.read()# 目标位置行高列宽 r, h, c, w 140, 230, 300, 150 track_window (c, r, w, h)# 指定目标的感兴趣区域 roi frame[r:rh, c:cw]# 计算直方图

转换色彩空间HSV

hsv_roi cv.cvtColor(roi, cv.COLOR_BGR2HSV)# 去除低亮度的值(色调饱和度亮度) mask cv.inRange(hsv_roi, np.array((0, 100, 52)), np.array((180, 255, 255)))# 计算直方图

[0] 只计算第一个通道即色调(hue)通道的直方图

[180] 定义直方图bin数量

[0,180] 计算从0到180之间的色调值的直方图

roi_hist cv.calcHist([hsv_roi],[0],mask,[180],[0,180])# 归一化 cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)# 目标追踪

设置窗口搜索终止条件最大迭代次数窗口中心漂移最小值

term_crit (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)while True:# 获取每一帧图像ret, frame video_dog.read()if ret:# 算直方图的反向投影生成一个概率图 dst指示当前帧中哪些区域最可能包含目标。hsv cv.cvtColor(frame, cv.COLOR_BGR2HSV)dst cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)# 进行Meanshift追踪ret, track_window cv.meanShift(dst, track_window, term_crit)# 追踪的位置绘制在视频上并进行显示x, y, w, h track_windowimg2 cv.rectangle(frame, (x, y), (x w, y h), 255, 2)cv.imshow(frame, img2)if cv.waitKey(65) 0xFF ord(q):breakelse:breakvideo_dog.release() cv.destroyAllWindows()5.3.2 camshift算法 camshift算法可以适应目标大小形状的改变具有较好的追踪效果。但当背景色和目标颜色接近时容易使目标的区域变大。 import cv2 as cv import numpy as npvideo_dog cv.VideoCapture(dog.mp4)# 获取第一帧图像并指定目标位置 ret, frame video_dog.read()# 目标位置 r, h, c, w 170, 150, 350, 90 track_window (c, r, w, h)# 指定目标区域 roi frame[r:rh, c:cw]# 计算直方图

转换色彩空间HSV

hsv_roi cv.cvtColor(roi, cv.COLOR_BGR2HSV)# 去除低亮度的值(色调饱和度亮度) mask cv.inRange(hsv_roi, np.array((0, 100, 50)), np.array((180, 255, 255)))# 计算直方图

[0] 只计算第一个通道即色调(hue)通道的直方图

[180] 定义直方图bin数量

[0,180] 计算从0到180之间的色调值的直方图

roi_hist cv.calcHist([hsv_roi],[0],mask,[180],[0,180])# 归一化 cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)# 目标追踪

设置窗口搜索终止条件最大迭代次数窗口中心漂移最小值

term_crit (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)while True:ret, frame video_dog.read()if ret:# 计算直方图的反向投影生成一个概率图 dst指示当前帧中哪些区域最可能包含目标。hsv cv.cvtColor(frame, cv.COLOR_BGR2HSV)dst cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)# CamShift追踪ret, track_window cv.CamShift(dst, track_window, term_crit)# 将追踪的位置绘制在视频上并进行显示# pst矩形框的四个坐标pts cv.boxPoints(ret)pts np.intp(pts)img2 cv.polylines(frame,[pts],True, 255,2)# 显示图像cv.imshow(frame, img2)if cv.waitKey(60) 0xFF ord(q):breakelse:breakvideo_dog.release() cv.destroyAllWindows()六、人脸、眼睛检测案例 OpenCV中自带已训练好的检测器包括面部、眼睛等都保存在XML中我们可以通过以下程序找到他们 import cv2 as cv print(cv.file)所有的XML文件都在D:\Anaconda\Lib\site-packages\cv2\data\中 6.1 人脸以及眼睛检测(图片) img cv.imread(liying2.jpg) gray cv.cvtColor(img,cv.COLOR_BGR2GRAY)# 定义训练器路径 cascade_path D:\Anaconda\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml eye_cascade_path D:\Anaconda\Lib\site-packages\cv2\data\haarcascade_eye.xml# 实例化人脸级联分类器 face_cas cv.CascadeClassifier(cascade_path)

实例化眼睛级联分类器

eyes_cas cv.CascadeClassifier(eye_cascade_path)# 人脸检测 faceRects face_cas.detectMultiScale(gray,scaleFactor1.05,minNeighbors5,minSize(20,20))

遍历人脸

for faceRect in faceRects:x,y,w,h faceRectcv.rectangle(img,(x,y),(xw,yh),(0,255,0),2)roi_color img[x:xw,y:yh]roi_gray gray[x:xw,y:yh]eyes eyes_cas.detectMultiScale(roi_gray,scaleFactor1.2, minNeighbors5, minSize(30, 30), maxSize(100, 100))for x,y,w,h in eyes:cv.rectangle(roi_color,(x,y),(xw,yh),(255,0,0),2)plt.figure(figsize(7,4)) plt.imshow(img[:,:,::-1]) plt.title(检测结果) plt.show()6.2 人脸以及眼睛检测(视频) import cv2 as cv import matplotlib.pyplot as pltvideo cv.VideoCapture(赵丽颖.mp4)cascade_path D:\Anaconda\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml eyes_cascade_path D:\Anaconda\Lib\site-packages\cv2\data\haarcascade_eye.xmlwhile True:ret,frame video.read()if retTrue:gray cv.cvtColor(frame,cv.COLOR_BGR2GRAY)# 实例化人脸级联分类器face_cas cv.CascadeClassifier(cascade_path)# 实例化眼睛级联分类器eyes_cas cv.CascadeClassifier(eyes_cascade_path)# 检测人脸faceRects face_cas.detectMultiScale(gray,scaleFactor1.2,minNeighbors3,minSize(60,60))for faceRect in faceRects:x,y,w,h faceRectcv.rectangle(frame,(x,y),(xw,yh),(0,255,0),2)roi_color frame[y:yh,x:xw]# 定位人脸上半部分roi_gray gray[y:yint(h*0.7),x:xw]eyes eyes_cas.detectMultiScale(roi_gray,scaleFactor1.3,minNeighbors5, minSize(20,20), maxSize(100, 100))for x,y,w,h in eyes:cv.rectangle(roi_color,(x,y),(xw,yh),(255,0,0),2)cv.imshow(frame,frame)if cv.waitKey(20) 0xFFord(q):breakelse:break video.release() cv.destroyAllWindows()由于运行结果是视频所以无法展示