【python】opencv总结

学习资源

链接:链接,提取码:3vt7

简介

安装pip install opencv-python==3.4.2.17
测试

import cv2
# 读一个图片并进行显示(图片路径需自己指定)
lena=cv2.imread("1.jpg")
cv2.imshow("image",lena)
cv2.waitKey(0)

利用SIFT和SURF进行特征提取的话,还需要pip install opencv-contrib-python==3.4.2.17

基础模块:core、highgui、imgproc

  1. core模块实现了最核心的数据结构及其基本运算,如绘图函数、数组操作相关函数等。
  2. highgui模块实现了视频与图像的读取、显示、存储等接口。
  3. imgproc模块实现了图像处理的基础方法,包括图像滤波、图像的几何变换、平滑、阈值分割、形态学处理、边缘检测、目标检测、运动分析和对象跟踪等。

其余模块:

features2d模块用于提取图像特征以及特征匹配,nonfree模块实现了一些专利算法,如sift特征。
stitching模块实现了图像拼接功能。
FLANN模块(Fast Library for Approximate Nearest Neighbors),包含快速近似最近邻搜索FLANN 和聚类Clustering算法。
ml模块机器学习模块(SVM,决策树,Boosting等等)。
photo模块包含图像修复和图像去噪两部分。
video模块针对视频处理,如背景分离,前景检测、对象跟踪等。
G-API模块包含超高效的图像处理pipeline引擎

常用操作

基本操作

读取图像
API:cv.imread()
参数:

  • 读取的图像
  • 读取方式的标志

    cv.IMREADCOLOR:以彩色模式加载图像,任何图像的透明度都将被忽略。这是默认参数。
    cv.IMREAD
    GRAYSCALE:以灰度模式加载图像
    cv.IMREAD_UNCHANGED:包括alpha通道的加载图像模式。
    可以使用1、0或者-1来替代上面三个标志

参考代码:

import numpy as np
import cv2 as cv
# 以灰度图的形式读取图像
img = cv.imread('messi5.jpg',0)

显示图像
API:cv.imshow()
参数:

  • 显示图像的窗口名称,以字符串类型表示
  • 要加载的图像

    注意:在调用显示图像的API后,要调用cv.waitKey()给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来。

参考代码:

# opencv中显示
cv.imshow('image',img)
cv.waitKey(0)
# matplotlib中展示 因为opencv读取的是BGR格式的 plt中用的是RGB格式的
# 怎么理解img[:,:,::-1] 首先是前两个维度全选,第三个维度是层上的。
# 也就是从层的角度来看,从后往前数,就完成了B通道和个R通道的转换
plt.imshow(img[:,:,::-1])

保存图像
API:cv.imwrite()
参数:

  • 文件名,要保存在哪里
  • 要保存的图像

窗口销毁函数

  • cv2.destroyAllWindows() ,销毁全部窗口,无参数
  • cv2.destroyWindow(windows_name) ,销毁单个特定窗口,参数: 将要销毁的窗口的名字
  • cv2.waitKey(time_of_milliseconds),time_of_milliseconds>0表示等待时间,time_of_milliseconds<=0表示等待键盘按键

图像色彩空间变换函数:cv2.cvtColor(input_image, flag),input_image表示将要变换色彩的图像ndarray对象;flag表示图像色彩空间变换的类型。

flag的常用取值:
cv2.COLOR_BGR2GRAY: 表示将图像从BGR空间转化成灰度图cv2.COLOR_BGR2HSV: 表示将图像从RGB空间转换到HSV空间

将原图像的像素值均转化成类型为np.uint8dst = cv2.convertScaleAbs(src)

图像归一化操作
API:cv2.normalize(src, dst, alpha, beta, norm_type, dtype, mask)

  • src: 原图像对象
  • dst: 经过转化后的图像对象
  • alpha: 归一化后灰度像素最小值,一般为0
  • beta: 归一化后灰度像素最大值,一般为255
  • norm_type: 归一化的类型,可以取以下值

(1) cv2.NORM_MINMAX: 数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用
(2) cv2.NORM_INF:此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
(3) cv2.NORM_L1 : 归一化数组的L1-范数(绝对值的和)
(4) cv2.NORM_L2: 归一化数组的(欧几里德)L2-范数

  • dtype: 为负数时,输出图像像素值的type与输入相同,一般使用默认
  • mask: 操作掩膜,用于指示函数是否仅仅对指定的元素进行操作,一般使用默认

绘制

绘制直线
API:cv.line(img,start,end,color,thickness)
参数:

  • img:要绘制直线的图像
  • Start,end: 直线的起点和终点
  • color: 线条的颜色
  • Thickness: 线条宽度

绘制圆形
API:cv.circle(img,centerpoint, r, color, thickness)
参数:

  • img:要绘制圆形的图像
  • Centerpoint, r: 圆心和半径

绘制矩形
API:cv.rectangle(img,leftupper,rightdown,color,thickness)
参数:

  • img:要绘制矩形的图像
  • Leftupper, rightdown: 矩形的左上角和右下角坐标

添加文字
API:cv.putText(img,text,station, font, fontsize,color,thickness,cv.LINE_AA)
参数:

  • img: 图像
  • text:要写入的文本数据
  • station:文本的放置位置
  • font:字体
  • Fontsize :字体大小

获取并修改图像中的像素点:我们可以通过行和列的坐标值获取该像素点的像素值。对于BGR图像,它返回一个蓝,绿,红值的数组。对于灰度图像,仅返回相应的强度值。使用相同的方法对像素值进行修改。

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
# 获取某个像素点的值
px = img[100,100]
# 仅获取蓝色通道的强度值
blue = img[100,100,0]
# 修改某个位置的像素值
img[100,100] = [255,255,255]

获取图像的属性img.shape、img.size、img.dtype
图像通道的拆分与合并:有时需要在B,G,R通道图像上单独工作。在这种情况下,需要将BGR图像分割为单个通道。或者在其他情况下,可能需要将这些单独的通道合并到BGR图像。

# 通道拆分
b,g,r = cv.split(img)
# 通道合并
img = cv.merge((b,g,r))

图像加法cv.add(img1,img2),不推荐使用numpy数组直接相加,而是用cv的add方法
图像混合cv.addweight(img1,x1,img2,x2),相当于按权相加, i m g 1 ∗ x 1 + i m g 2 ∗ x 2 img_1*x_1+img_2*x_2 img1x1+img2x2
:这里都要求两幅图像是相同大小的。

图像处理

几何变换

图像缩放:缩放是对图像的大小进行调整,即使图像放大或缩小。
API:cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
参数:

  • src : 输入图像
  • dsize: 绝对尺寸,直接指定调整后图像的大小
  • fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可
  • interpolation:插值方法,

    在这里插入图片描述

参考代码:

import cv2 as cv
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")
# 2.图像缩放
# 2.1 绝对尺寸
rows,cols = img1.shape[:2]
res = cv.resize(img1,(2*cols,2*rows),interpolation=cv.INTER_CUBIC)

# 2.2 相对尺寸
res1 = cv.resize(img1,None,fx=0.5,fy=0.5)

# 3 图像显示
# 3.1 使用matplotlib显示图像
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100)
axes[0].imshow(res[:,:,::-1])
axes[0].set_title("boost")
axes[1].imshow(img1[:,:,::-1])
axes[1].set_title("origin")
axes[2].imshow(res1[:,:,::-1])
axes[2].set_title("shrink")
plt.show()

在这里插入图片描述

图像平移:图像平移将图像按照指定方向和距离,移动到相应的位置。
API:cv.warpAffine(img,M,dsize)
参数:

  • img: 输入图像
  • M: 2*∗3移动矩阵
  • dsize: 输出图像的大小

    注意:1、输出图像的大小,它应该是(宽度,高度)的形式;2、对于(x,y)处的像素点,要把它移动到 ( x + t x , y + t y ) (x+t_x , y+t_y) (x+tx,y+ty)处时,M矩阵应如下设置,并且将M设置为np.float32类型的Numpy数组。
    在这里插入图片描述

参考代码:需求是将图像的像素点移动(50,100)的距离:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")

# 2. 图像平移
rows,cols = img1.shape[:2]
M = np.float32([[1,0,100],[0,1,50]])# 平移矩阵
dst = cv.warpAffine(img1,M,(cols,rows))

# 3. 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("origin")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("move")
plt.show()

在这里插入图片描述

图像旋转:图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸。在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。

API:cv2.getRotationMatrix2D(center, angle, scale)cv.warpAffine
参数:

  • center:旋转中心
  • angle:旋转角度
  • scale:缩放比例

    注意:前者用于生成旋转矩阵,后者用于旋转

参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")

# 2 图像旋转
rows,cols = img1.shape[:2]
# 2.1 生成旋转矩阵 以为原点为中心,旋转90度
M = cv.getRotationMatrix2D((cols/2,rows/2),90,1)
# 2.2 进行旋转变换
dst = cv.warpAffine(img1,M,(cols,rows))

# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("origin")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("move")
plt.show()

在这里插入图片描述

仿射变换:图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。
什么是仿射变换:如下图所示,图1中的点1, 2 和 3 与图二中三个点一一映射, 仍然形成三角形, 但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。
在这里插入图片描述

API:cv2.getAffineTransform(src, dst)cv.warpAffine
参数:

  • src表示原图中的三个点
  • dst表示输出图像中的三个点

    注意:前者用于生成仿射矩阵,后者用于变换

参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")

# 2 仿射变换
rows,cols = img1.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
# 2.2 完成仿射变换
dst = cv.warpAffine(img1,M,(cols,rows))

# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("origin")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("move")
plt.show()

在这里插入图片描述

透射变换:透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
API:cv.getPerspectiveTransform(src,dst)cv.warpAffine
参数:

  • src表示原图中的四个点,其中任意三个不共线
  • dst表示输出图像中的四个点,其中任意三个不共线

    注意:前者用于生成透射矩阵,后者用于变换

参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")

# 2 透射变换
rows,cols = img1.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])

T = cv.getPerspectiveTransform(pts1,pts2)
# 2.2 进行变换
dst = cv.warpPerspective(img1,T,(cols,rows))

# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("origin")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("move")
plt.show()

在这里插入图片描述

图像金字塔:图像金字塔是图像多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似,层级越高,图像越小,分辨率越低。
API:上采样cv.pyrUp(img) ,下采样:cv.pyrDown(img)
参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img1 = cv.imread(r"./img/1.jpg")

# 2 进行图像采样
up_img = cv.pyrUp(img1)  # 上采样操作
down_img = cv.pyrDown(img1)  # 下采样操作

# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100)
axes[0].imshow(up_img[:,:,::-1])
axes[0].set_title("up")
axes[1].imshow(img1[:,:,::-1])
axes[1].set_title("origin")
axes[2].imshow(down_img[:,:,::-1])
axes[2].set_title("down")
plt.show()

在这里插入图片描述

形态学操作

图像平滑

概述:图像平滑从信号处理的角度看就是去除其中的高频信息,保留低频信息。因此我们可以对图像实施低通滤波。低通滤波可以去除图像中的噪声,对图像进行平滑。根据滤波器的不同可分为均值滤波,高斯滤波,中值滤波, 双边滤波。
噪声:椒盐噪声:图像中随机出现的白点或者黑点;高斯噪声:噪声的概率密度分布是正态分布

均值滤波:均值滤波的优点是算法简单,计算速度较快,缺点是在去噪的同时去除了很多细节部分,将图像变得模糊。
API:cv.blur(src, ksize, anchor, borderType)
参数:

  • src:输入图像
  • ksize:卷积核的大小
  • anchor:默认值 (-1,-1) ,表示核中心
  • borderType:边界类型

参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img = cv.imread(r"./img/3.jpeg")

# 2 均值滤波
blur = cv.blur(img,(5,5))
# 3 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('origin')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('after')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

高斯滤波:高斯平滑在从图像中去除高斯噪声方面非常有效。
API:cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
参数:

  • src: 输入图像
  • ksize:高斯卷积核的大小,注意 : 卷积核的宽度和高度都应为奇数,且可以不同
  • sigmaX: 水平方向的标准差
  • sigmaY: 垂直方向的标准差,默认值为0,表示与sigmaX相同
  • borderType:填充边界类型

参考代码:

import cv2 as cv
import numpy as np
import  matplotlib.pyplot as plt


# 1. 读取图片
img = cv.imread(r"./img/3.jpeg")

# 2 高斯滤波
blur = cv.GaussianBlur(img,(3,3),1)
# 3 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('origin')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('after')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

中值滤波:去除椒盐噪声
API:cv.medianBlur(src, ksize )
参数:

  • src:输入图像
  • ksize:卷积核的大小

直方图

原理:直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实现定义好的 bin 当中。其中, bin 为直方图中经常用到的一个概念,可以译为 “直条” 或 “组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。

在这里插入图片描述
术语和细节

  • dims:需要统计的特征数目。在上例中,dims = 1 ,因为仅仅统计了灰度值。
  • bins:每个特征空间子区段的数目,可译为 “直条” 或 “组距”,在上例中, bins = 16。
  • range:要统计特征的取值范围。在上例中,range = [0, 255]。

直方图的意义

  • 直方图是图像中像素强度分布的图形表达方式。
  • 它统计了每一个强度值所具有的像素个数。
  • 不同的图像的直方图可能是相同的

直方图的计算和绘制
API:cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
参数:

  • images: 原图像。当传入函数时应该用中括号 [] 括起来,例如:[img]。
  • channels: 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
  • mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
  • histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
  • ranges: 像素值范围,通常为 [0,256]

参考代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


# 1 直接以灰度图的方式读入
img = cv.imread(r'./img/cat.jpeg',0)
# 2 统计灰度图
histr = cv.calcHist([img],[0],None,[256],[0,256])
# 3 绘制灰度图
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].plot(histr)
axes[0].set_title("up")
axes[1].imshow(img)
axes[1].set_title("origin")
plt.show()

在这里插入图片描述

掩膜的应用:掩膜是用选定的图像、图形或物体,对要处理的图像进行遮挡,来控制图像 处理的区域。在数字图像处理中,我们通常使用二维矩阵数组进行掩膜。掩膜是由0和1组成一个二进制图像,利用该掩膜图像要处理的图像进行掩膜,其中1值的区域被处理,0 值区域被屏蔽,不会处理。概述:创建蒙版,透过mask进行传递,可获取感兴趣区域的直方图

参考代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


# 1 直接以灰度图的方式读入
img = cv.imread(r'./img/cat.jpeg',0)
# 2. 创建蒙版
mask = np.zeros(img.shape[:2], np.uint8)
mask[400:650, 200:500] = 255
# 3.掩模
masked_img = cv.bitwise_and(img,img,mask = mask)
# 4. 统计掩膜后图像的灰度图
mask_histr = cv.calcHist([img],[0],mask,[256],[1,256])
# 5. 图像展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img,cmap=plt.cm.gray)
axes[0,0].set_title("原图")
axes[0,1].imshow(mask,cmap=plt.cm.gray)
axes[0,1].set_title("蒙版数据")
axes[1,0].imshow(masked_img,cmap=plt.cm.gray)
axes[1,0].set_title("掩膜后数据")
axes[1,1].plot(mask_histr)
axes[1,1].grid()
axes[1,1].set_title("灰度直方图")
plt.show()

在这里插入图片描述

直方图均衡化:是把原始图像的灰度直方图从比较集中的某个灰度区间变成在更广泛灰度范围内的分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。这种方法提高图像整体的对比度,特别是有用数据的像素值分布比较接近时,在X光图像中使用广泛,可以提高骨架结构的显示,另外在曝光过度或不足的图像中可以更好的突出细节。概述:增强图像对比度的一种方法

API:dst = cv.equalizeHist(img)
参数:

  • img: 灰度图像

    注意:dst : 均衡化后的结果

参考代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


# 1 直接以灰度图的方式读入
img = cv.imread(r'./img/cat.jpeg',0)
# 2. 均衡化处理
dst = cv.equalizeHist(img)
# 3. 结果展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(dst,cmap=plt.cm.gray)
axes[1].set_title("均衡化后结果")
plt.show()

在这里插入图片描述

自适应的直方图均衡化:上述的直方图均衡,我们考虑的是图像的全局对比度。 的确在进行完直方图均衡化之后,图片背景的对比度被改变了,在猫腿这里太暗,我们丢失了很多信息,所以在许多情况下,这样做的效果并不好。如下图所示,对比下两幅图像中雕像的画面,由于太亮我们丢失了很多信息。为了解决这个问题, 需要使用自适应的直方图均衡化。 此时, 整幅图像会被分成很多小块,这些小块被称为“tiles”(在 OpenCV 中 tiles 的 大小默认是 8x8),然后再对每一个小块分别进行直方图均衡化。 所以在每一个的区域中, 直方图会集中在某一个小的区域中)。如果有噪声的话,噪声会被放大。为了避免这种情况的出现要使用对比度限制。对于每个小块来说,如果直方图中的 bin 超过对比度的上限的话,就把 其中的像素点均匀分散到其他 bins 中,然后在进行直方图均衡化。最后,为了 去除每一个小块之间的边界,再使用双线性差值,对每一小块进行拼接。概述:将整幅图像分成很多小块,然后再对每一个小块分别进行直方图均衡化,最后进行拼接

API:cv.createCLAHE(clipLimit, tileGridSize)
参数:

  • clipLimit: 对比度限制,默认是40
  • tileGridSize: 分块的大小,默认为 8 ∗ 8 8*8 88

参考代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


# 1 直接以灰度图的方式读入
img = cv.imread(r'./img/cat.jpeg',0)
# 2. 创建一个自适应均衡化的对象,并应用于图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
# 3. 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(cl1,cmap=plt.cm.gray)
axes[1].set_title("自适应均衡化后的结果")
plt.show()

在这里插入图片描述

其余API

Canny边缘检测
API:canny = cv2.Canny(image, threshold1, threshold2)
参数:

  • image:灰度图,
  • threshold1: minval,较小的阈值将间断的边缘连接起来
  • threshold2: maxval,较大的阈值检测图像中明显的边缘

参考代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 图像读取
img = cv.imread('./img/horse.jpg',0)
# 2 Canny边缘检测
lowThreshold = 0
max_lowThreshold = 100
canny = cv.Canny(img, lowThreshold, max_lowThreshold)
# 3 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(canny,cmap=plt.cm.gray)
axes[1].set_title("自适应均衡化后的结果")
plt.show()

在这里插入图片描述

模板匹配:在给定的图片中查找和模板最相似的区域
API:利用cv.matchTemplate()进行模板匹配,然后使用cv.minMaxLoc()搜索最匹配的位置。

霍夫线检测
API:cv2.HoughLines()

霍夫圆检测
API:cv.HoughCircles()

傅里叶变换:鸽

角点检测

Harris算法,Shi-Tomasi算法(Harris算法的改进):这两种算法具有旋转不变性,但不具有尺度不变性
Shi-Tomasi
API:corners = cv2.goodFeaturesToTrack ( image, maxcorners, qualityLevel, minDistance )
参数:

  • Image: 输入灰度图像
  • maxCorners : 获取角点数的数目。
  • qualityLevel:该参数指出最低可接受的角点质量水平,在0-1之间。
  • minDistance:角点之间最小的欧式距离,避免得到相邻特征点。

    注意:Corners: 搜索到的角点,在这里所有低于质量水平的角点被排除掉,然后把合格的角点按质量排序,然后将质量较好的角点附近(小于最小欧式距离)的角点删掉,最后找到maxCorners个角点返回。

参考代码:

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread('./img/tv.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 2 角点检测
corners = cv.goodFeaturesToTrack(gray,1000,0.01,10)
# 3 绘制角点
for i in corners:
    x,y = i.ravel()
    cv.circle(img,(x,y),2,(0,0,255),-1)
# 4 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('shi-tomasi')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述
SIFT算法,SURF算法(对SIFT算法的改进):尺度不变特征转换

SURF算法
API:surf= cv.xfeatures2d.SURF_create() 实例化surf

API:kp,des = surf.detectAndCompute(gray,None),检测关键点并计算
参数:

  • gray: 进行关键点检测的图像,注意是灰度图像

返回:kp: 关键点信息,包括位置,尺度,方向信息;des: 关键点描述符,每个关键点对应128个梯度信息的特征向量

API:cv.drawKeypoints(image, keypoints, outputimage, color, flags),将关键点检测结果绘制在图像上
参数:

  • image: 原始图像
  • keypoints:关键点信息,将其绘制在图像上
  • outputimage:输出图片,可以是原始图像
  • color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
  • flags:绘图功能的标识设置

cv2.DRAW_MATCHES_FLAGS_DEFAULT:创建输出图像矩阵,使用现存的输出图像绘制匹配对和特征点,对每一个关键点只绘制中间点
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:不创建输出图像矩阵,而是在输出图像上绘制匹配对
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:对每一个特征点绘制带大小和方向的关键点图形
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制

参考代码:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread('./img/tv.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 2 surf关键点检测
# 2.1 实例化surf对象
surf = cv.xfeatures2d.SURF_create(400)

# 2.2 关键点检测:kp关键点信息包括方向,尺度,位置信息,des是关键点的描述符
kp,des=surf.detectAndCompute(gray,None)
# 2.3 在图像上绘制关键点的检测结果
cv.drawKeypoints(img,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 3 图像显示
plt.figure(figsize=(8,6),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('surf')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

视频操作

从文件中读取视频并播放

创建读取视频的对象:cap = cv.VideoCapture(filepath)
获取视频的某些属性:retval = cap.get(propId)

propId: 从0到18的数字,每个数字表示视频的属性
常用属性:
在这里插入图片描述

修改视频的属性信息:cap.set(propId,value)
判断图像是否读取成功:isornot = cap.isOpened()
获取视频的一帧图像:ret, frame = cap.read()

ret: 若获取成功返回True,获取失败,返回False
Frame: 获取到的某一帧的图像

调用cv.imshow()显示图像,在显示图像时使用cv.waitkey()设置适当的持续时间,如果太低视频会播放的非常快,如果太高就会播放的非常慢,通常情况下我们设置25ms就可以了。

最后,调用cap.realease()将视频释放掉

import numpy as np
import cv2 as cv
# 1.获取视频对象
cap = cv.VideoCapture('./img/2.mp4')
# 2.判断是否读取成功
while(cap.isOpened()):
    # 3.获取每一帧图像
    ret, frame = cap.read()
    # 4. 获取成功显示图像
    if ret == True:
        cv.imshow('frame',frame)
    # 5.每一帧间隔为25ms
    if cv.waitKey(25) & 0xFF == ord('q'):
        break
# 6.释放视频对象
cap.release()
cv.destoryAllwindows()

保存视频
创建视频写入的对象:out = cv2.VideoWriter(filename,fourcc, fps, frameSize)

filename:视频保存的位置
fourcc:指定视频编解码器的4字节代码
fps:帧率
frameSize:帧大小

设置视频的编解码器,如下所示:retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 )

c1,c2,c3,c4: 是视频编解码器的4字节代码,在fourcc.org中找到可用代码列表,与平台紧密相关,常用的有:
在Windows中:DIVX(.avi)
在OS中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

利用cap.read()获取视频中的每一帧图像,并使用out.write()将某一帧图像写入视频中。
使用cap.release()和out.release()释放资源。

import cv2 as cv
import numpy as np

# 1. 读取视频
cap = cv.VideoCapture('./img/2.mp4')

# 2. 获取图像的属性(宽和高,),并将其转换为整数
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# 3. 创建保存视频的对象,设置编码格式,帧率,图像的宽高等
out = cv.VideoWriter('outpy.avi',cv.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
while(True):
    # 4.获取视频中的每一帧图像
    ret, frame = cap.read()
    if ret == True: 
        # 5.将每一帧图像写入到输出文件中
        out.write(frame)
    else:
        break 

# 6.释放资源
cap.release()
out.release()
cv.destroyAllWindows()
  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值