Skip to content

OpenCV学习

约 3867 字大约 13 分钟

opencv

2024-03-01

需要的库和工具

  • python3 numpy 库

  • cmake:转换脚本,编译 opencv

  • VS

  • namedWindow()创建显示窗口 窗口大小默认为显示的元素大小

  • imshow()显示图片

  • destroyAllWindows() 销毁所有窗口

  • resizeWindow() 设定大小

  • waitekey(int time) 等待;time 毫秒

  • imread() 读取图片 返回 mat

  • imwrite()保存图片 保存 mat

  • cvtColor():颜色空间转换

  • copy() 深拷贝

#从摄像头采集数据对象;一直不停的取 显示就是视频的感觉;可以从多种不同的设备采集
var cap = VideoCapture()
ret,frame = cat.read()

# 读取视频的帧;控制构造函数的参数
var cap = VideoCapture(0)




#视频录制
VideoWrite()#视频录制
  • setMouseCallback(winname,callback,para) 鼠标回调函数

HSV

一个圆柱体模型

  • H:色彩值
  • S:明亮度
  • V:饱和度 hsv

使用 numpy 创建矩阵

矩阵二维数组

ROI

Range Of Image:图片中的区域

  • roi 的取值为[高度 宽度] rio=img[10:100,20:200]:x 轴 10 开始取 100 长度,y 轴从 20 开始取 200 img[:]:全图

Mat

矩阵,可表示多通道

实例分割算法

目标识别算法

分类算法

语义分割算法

滤波

低通滤波

一般用于去噪点,平滑性

import cv2
import numpy as np

# 卷积 平滑处理
cv2.namedWindow("img",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img", 800, 600)

img = cv2.imread('img/bopian.jpg')

# 均值滤波
kernal = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel=kernal)



cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

均值滤波

blur()

中值滤波

medianBlur(),对于类似胡椒噪音的图,可以做到滤波去噪

双边滤波

在保留边缘的同时,进行平滑处理;美颜效果

高通滤波

一般用于边缘检测

Sobel(索贝尔)

求边缘,但是一次只能一个 检查每个小点(像素)周围的亮度。如果某个地方亮度变化很大,比如从很亮一下子变成很暗,这里可能是个边缘!” 这样,它就能把图片里重要的轮廓标记出来。

# Sobel 索贝尔
sobelx= cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) #x轴的边缘
sobely = cv2.Sobel(img,cv2.CV_64F,0,1)#y轴边缘


dst = cv2.add(sobelx,sobely) #相加

Scharr(沙尔)

功能被 sobel 覆盖了,一般不用

Laplacian(拉普拉斯)

相比 sobel 可以同时计算 xy 轴的边缘,一般需要先建造在用

Canny

集合前面几种算法

距离变换

distanceTransform():分离粘连

分水岭

connectedcomponents:区域联通 watershed():分水岭

形态学

  • 基于图像形态进行处理的基本方法
  • 基本是对二进制图像进行处理
  • 卷积核决定图像处理后的效果

二值化

  • 将图像的每个像素转化成两种值
  • 全局二值化 threshold(img,thresh,maxval,type)
  • 局部二值化
img = cv2.imread('img/bopian.jpg')

#灰度
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)


# 二值化
eerr,b = cv2.threshold(gray,90,255,cv2.THRESH_BINARY_INV)
print(b.shape)



# 自适应阈值二值化
dst = cv2.adaptiveThreshold(gray,233,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,3,0)

腐蚀膨胀

  • 腐蚀
import cv2
import numpy as np


# 腐蚀
cv2.namedWindow("img",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img", 800, 600)

cv2.namedWindow("img1",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img1", 800, 600)


img = cv2.imread('img/bopian.jpg')
kernel = np.ones((5,5),np.uint8)
erode = cv2.erode(img,kernel,iterations=2) # 卷积核可设置1,3,5,7;iterations 腐蚀次数


# 获取卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7)) # 卷积核形状;大小
erode = cv2.erode(img,kernel,iterations=2) # 卷积核可设置1,3,5,7;iterations 腐蚀次数

cv2.imshow("img",img)
cv2.imshow("img1",erode)

cv2.waitKey(0)
cv2.destroyAllWindows()
  • 膨胀
import cv2
import numpy as np


# 膨胀 腐蚀可逆,但是卷积核不能太大 否则损失元素过多时 无法还原
cv2.namedWindow("img",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img", 800, 600)


cv2.namedWindow("img1",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img1", 800, 600)


img = cv2.imread('img/bopian.jpg')
kernel = np.ones((7,7),np.uint8
erode = cv2.dilate(img,kernel,iterations=2) # 卷积核可设置1,3,5,7;iterations 腐蚀次数

cv2.imshow("img",img)
cv2.imshow("img1",erode)


cv2.waitKey(0)
cv2.destroyAllWindows()

开运算

先腐蚀再膨胀 可以去掉一些噪点,通过卷积核把一些独立的点 腐蚀掉变成边上的颜色,再膨胀回去 噪点就没了

MORPH_OPEN

闭运算

先膨胀再腐蚀

MORPH_CLOSE

import cv2
import numpy as np

# 开闭运算

cv2.namedWindow("img",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img", 800, 600)


cv2.namedWindow("open",cv2.WINDOW_NORMAL)
cv2.resizeWindow("open", 800, 600)


cv2.namedWindow("close",cv2.WINDOW_NORMAL)
cv2.resizeWindow("close", 800, 600)

img = cv2.imread('img/bopian.jpg')

#核的大小决定降噪点的大小
kernel = np.ones((5,5),np.uint8)

# 开运算 对元素外进行降噪
open = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)



# 闭运算 对元素内进行降噪
#colse = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)

# 把开运算的结果再进行一次闭运算就可以对内外的进行降噪
colse = cv2.morphologyEx(open,cv2.MORPH_CLOSE,kernel)



cv2.imshow("img",img)
cv2.imshow("open",open)
cv2.imshow("close",colse)


cv2.waitKey(0)
cv2.destroyAllWindows()

形态学梯度(边缘)

原图-腐蚀图=梯度;就是边缘

MORPH_GRADIENT `# 梯度 原图-梯度   就是获取边缘

GRADIENT = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel)`

顶帽

原图-开运算=噪点; 开运算 用于去掉元素外的小元素;一般用于去掉大的图,留下小的元素 大块外的小东西

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(77,77)) # 卷积核形状;大小

# 顶帽运算 原图-开运算  保留图中的小元素
GRADIENT = cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)

MORPH_TOPHAT

黑帽

原图-闭运算=元素内的噪点;类似顶帽 保留的是元素内的 大块中的小东西

MORPH_BLACKHAT

#黑帽 原图-闭运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

BLACKHAT = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)

图像轮廓

具有相同颜色或强度的连续点的曲线 具有相同颜色说明彩色的也可以;相同强度的说明是针对二值化的图

  • 用于图像分析
  • 一般需要先对图像进行二值化或者 Canny

寻找轮廓

(轮廓,..) = findContours(erzhiimg,Mode,ApproximationMode)

  • Mode
    • RETR_EXTERNAL=0 只检测外轮廓
    • RETR_LIST=1 检测的轮廓不建立等级关系
    • RETR_CCOMP=2 每层最多两级
    • RETR_TREE=3 按照树形存储
  • ApproximationMode
    • CHAIN_APPROX_NONE 保存所有轮廓的点
    • .._SIMPLE 保存角点

绘制轮廓(描点)

drawContours(img,contours,contourIdx,color,thickness ...)

  • contourIdx -1 绘制所有轮廓
  • color 颜色(0,0,255)
  • thickness 线宽 -1 填充

多边形逼近

approxPolyDP()

凸包

存放的轮廓

convexHull()

外接矩阵

判断是否旋转

RotatedRect=minAreaRect(point) #最小外接矩阵
(x,y,w,h) = boundingRect(array) #最大外接矩阵

匹配

特征匹配

暴力匹配

FLANN 匹配

适用于多张图的快速特征匹配

单元性矩阵

图像查找

findHomorgraphy(srcPts,sst)

图像替换

图像拼接

  • 读取文件并重置尺寸
  • 根据特征点核计算描述子,得到单元矩阵
  • 图像变换
  • 图形拼接输出

ider

  • 霍夫变换 检测直线

OpenCV API

图形绘制

line() 绘制直线

#输入图像;起点坐标;终点坐标;线颜色;线宽 如果是- 1则在图案内生成闭合图案并填充颜色。这个参数的默认厚度为1。 - lineType:用于设置线条的类型,有8型连接,抗锯齿等。默认情况是8型连接。cv2.LINE_AA为抗锯齿,这样看起来会非常平滑。
cv2.line(img,(begin_x,begin_y),(end_x,end_y),(255,0,0),5)

rectangle() 绘制矩形

cv2.rectangle(img,(起点坐标),(结束坐标),(0,255,0),3)

circle() 绘制圆形

cv2.circle(img,(447,63), 63, (0,0,255), -1)

ellipse() 绘制椭圆

cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

polylines() 绘制多边形

# 第三个参数为False,则绘制所有点的相连图形而不是闭合图形
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))

putText() 绘制文字

font = cv.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)

cvtColor() 图像颜色空间转换

将图像从一个颜色空间转换为另一个颜色空间,例如将彩色图像转换为灰度图像或将图像从 BGR 颜色空间转换为 HSV 颜色空间。

output_image = cv2.cvtColor(input_image, code, dstCn)
'''
参数:
- input_image:输入的图像,可以是一个 NumPy 数组。
- code:颜色空间转换代码,指定转换的类型。可以使用预定义的常量,例如 cv2.COLOR_BGR2GRAY 表示从 BGR 转换为灰度,也可以使用数值表示,例如 0 表示从 BGR 转换为灰度。
		- cv2.COLOR_BGR2GRAY:将 BGR 彩色图像转换为灰度图像。
		- cv2.COLOR_BGR2RGB:将 BGR 彩色图像转换为 RGB 彩色图像。
		- cv2.COLOR_BGR2HSV:将 BGR 彩色图像转换为 HSV 颜色空间。
		- cv2.COLOR_BGR2LAB:将 BGR 彩色图像转换为 LAB 颜色空间。
		- cv2.COLOR_RGB2GRAY:将 RGB 彩色图像转换为灰度图像。
		- cv2.COLOR_RGB2BGR:将 RGB 彩色图像转换为 BGR 彩色图像。
		- cv2.COLOR_HSV2BGR:将 HSV 颜色空间图像转换为 BGR 彩色图像。
		- cv2.COLOR_LAB2BGR:将 LAB 颜色空间图像转换为 BGR 彩色图像。
- dstCn:可选参数,指定输出图像的通道数。默认值为 `0`,表示与输入图像的通道数相同。

返回值
- output_image`:转换后的输出图像。
'''

erode() 腐蚀

减小图像中的白色(前景)区域,同时增强黑色(背景)区域的尺寸。它可以用于去除图像中的噪声、分离相连的物体等

dst = cv2.erode(src, kernel, anchor, iterations, borderType, borderValue)
fs = cv2.erode(roi,kernel= np.ones((3,3),np.uint8),iterations=2)
'''
参数:
	src:输入图像,可以是单通道灰度图像或多通道彩色图像。
	kernel:用于腐蚀操作的结构元素(或内核),可以通过cv2.getStructuringElement()函数创建或自定义。
	anchor:结构元素的锚点位置,默认值为 `(-1, -1)`,表示结构元素的中心点。
	iterations:腐蚀操作的迭代次数,默认值为 `1`。
	borderType:边界扩充的类型,默认值为 cv2.BORDER_CONSTANT。
	borderValue:边界扩充的像素值,当 borderType` 为 `cv2.BORDER_CONSTANT` 时使用,默认值为 `0`。

返回值:
	dst:处理后的图像
'''

dilate() 膨胀

增强图像中的前景(白)的区域,减少背景(黑)的尺寸。用于填充图像中的空洞、断开的连接边缘、膨胀物体

dst = cv2.dilate(src, kernel, anchor, iterations, borderType, borderValue)
pz = cv2.dilate(roi,kernel= np.ones((3,3),np.uint8),iterations=2)
'''
参数:
	src:输入图像,可以是单通道灰度图像或多通道彩色图像。
	kernel:用于膨胀操作的结构元素(或内核),可以通过cv2.getStructuringElement()函数创建或自定义。
	anchor:结构元素的锚点位置,默认值为 `(-1, -1)`,表示结构元素的中心点。
	iterations:膨胀操作的迭代次数,默认值为 `1`。
	borderType:边界扩充的类型,默认值为 `cv2.BORDER_CONSTANT`。
	borderValue:边界扩充的像素值,当 `borderType` 为 `cv2.BORDER_CONSTANT` 时使用,默认值为 `0`。

返回值:
	dst:处理后的图像
'''

threshold() 二值化

通过将图像像素的灰度值与预先指定的阈值进行比较,并将像素分为两个类别:低于阈值的像素被设为一个值,高于或等于阈值的像素被设为另一个值。

retval, threshold = cv2.threshold(src, thresh, maxval, type)
'''
参数:
- thresh:阈值,用于将图像进行分割的像素灰度值。
- maxval:当像素值高于或等于阈值时,要设置的像素值。
- type:阈值化操作的类型:
	cv2.THRESH_BINARY:对于高于阈值的像素,将其设置为`maxval`,对于低于阈值的像素,将其设置为0。
	cv2.THRESH_BINARY_INV:对于高于阈值的像素,将其设置为0,对于低于阈值的像素,将其设置为maxval。
	cv2.THRESH_TRUNC: 对于高于阈值的像素,将其设置为阈值,对于低于阈值的像素,保留原始像素值。
	cv2.THRESH_TOZERO: 对于高于阈值的像素,保留原始像素值,对于低于阈值的像素,将其设置为0。
	cv2.THRESH_TOZERO_INV: 对于高于阈值的像素,将其设置为0,对于低于阈值的像素,保留原始像素值。

返回值,元组:
	retval:计算得到的阈值。
	threshold:阈值化后的图像。
'''

findContours() 轮廓检测

contours, hierarchy = cv2.findContours(image, mode, method, offset)
'''
参数:
- image:二值化图像,通常为灰度图像或经过阈值处理后的图像。
- mode:轮廓检索模式,指定轮廓的层次结构。可以是以下值之一:
    - cv2.RETR_EXTERNAL:仅检测外部轮廓。
    - cv2.RETR_LIST:检测所有轮廓,并将它们存储在列表中,无层次结构。
    - cv2.RETR_CCOMP:检测所有轮廓,并将它们组织为两层层次结构。顶层为外部轮廓,次层为内部轮廓。
    - `cv2.RETR_TREE`:检测所有轮廓,并将它们组织为完整的层次结构树。
- method:轮廓逼近方法,指定如何逼近轮廓的方法。可以是以下值之一:
    - cv2.CHAIN_APPROX_NONE:保存所有的轮廓点。
    - cv2.CHAIN_APPROX_SIMPLE:仅保存轮廓的端点。例如,一个矩形只需四个端点来表示。
    - cv2.CHAIN_APPROX_TC89_L1:使用 Teh-Chin 链逼近算法的一种方法。
    - cv2.CHAIN_APPROX_TC89_KCOS:使用 Teh-Chin 链逼近算法的另一种方法。
- offset:可选参数,表示轮廓点坐标的偏移量。
返回值:
- contours: 轮廓含点坐标的NumPy数组
- ierarchy: 层次结构
'''

contourArea() 获取轮廓面积

对于闭合的轮廓,可以直接计算面积。但对于非闭合的轮廓,需要使用其他方法进行面积计算,例如将轮廓闭合或使用 Green's 定理(也称为面积积分定理)。

area = cv2.contourArea(contour)
'''
参数:
- contour:输入的轮廓,可以是一个包含点坐标的 NumPy 数组。
- oriented:可选参数,表示轮廓是否有方向。如果为 `True`,则计算有方向的轮廓面积;如果为 `False`,则计算无方向(绝对值)的轮廓面积。默认值为 `False`。

返回值:
- area:轮廓的面积。
'''

boundingRect() 计算轮廓边界矩形

计算轮廓边界矩形。输出能包含轮廓最小面积的矩形

x, y, width, height = cv2.boundingRect(contour)
'''
参数:
- contour:输入的轮廓,可以是一个包含点坐标的 NumPy 数组。

返回值:
- x:边界矩形的左上角 x 坐标。
- y:边界矩形的左上角 y 坐标。
- width:边界矩形的宽度。
- height:边界矩形的高度。
'''

drawContours() 绘制轮廓

image = cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)

'''
参数:
- image:输入的图像,可以是灰度图像或彩色图像。
- contours:要绘制的轮廓,可以是一个包含多个轮廓的列表。
- contourIdx:要绘制的轮廓索引。如果为负值,则绘制所有的轮廓。
- color:绘制的颜色,可以是一个常数值或一个包含三个通道值的元组。
- thickness:绘制的线条粗细,如果为负值或 cv2.FILLED,则填充轮廓内部。
- lineType:线条类型,指定线条的连接方式,默认为 cv2.LINE_8。
- hierarchy:轮廓的层次结构,如果提供了层次结构,则只绘制指定层次的轮廓。
- maxLevel:要绘制的最大层次,如果为 0,则绘制所有层次的轮廓。
- offset:可选参数,表示轮廓点坐标的偏移量。
返回值:
- image:绘制轮廓后的图像。
'''

Canny() 轮廓检测

contours, hierarchy = cv2.findContours(image, mode, method, offset)
'''
基本思想是通过以下几个步骤实现的:
 1. 使用高斯滤波器对输入图像进行平滑处理,以减少噪声对边缘检测的影响。
 2. 计算图像的梯度,找到图像中的边缘强度和方向。
 3. 应用非极大值抑制,将边缘像素细化为单像素线条。
 4. 通过滞后阈值处理,根据设定的阈值来确定真正的边缘。
参数:
- image:要进行边缘检测的输入图像,通常为灰度图像(单通道图像)。
- threshold1:第一个阈值(低阈值)。较小的梯度值将被认为不是边缘。
- threshold2:第二个阈值(高阈值)。较大的梯度值将被认为是边缘。
- apertureSize(可选):Sobel 算子的孔径大小。默认值为 3。
- L2gradient(可选):一个布尔值,用于指定计算梯度幅值的方法。如果为 True,则使用更精确的 L2 范数计算梯度幅值。默认值为 False,表示使用 L1 范数计算。

返回值:

'''