opencv-API
基本操作
-
图像IO操作的API:
-
cv.imread(): 读取图像
-
cv.imshow():显示图像
-
cv.imwrite(): 保存图像
-
-
在图像上绘制几何图像
-
cv.line(): 绘制直线
-
cv.circle(): 绘制圆形
-
cv.rectangle(): 绘制矩形
-
cv.putText(): 在图像上添加文字
-
-
直接使用行列索引获取图像中的像素并进行修改
-
图像的属性
属性 | API |
---|---|
形状 | img.shape |
图像大小 | img.size |
数据类型 | img.dtype |
-
拆分通道: cv.split()
-
通道合并:cv.merge()
-
色彩空间的改变
- cv.cvtColor(input_image,flag)
-
图像加法:将两幅图像加载一起
- cv.add()
-
图像的混合:将两幅图像按照不同的比例进行混合
- cv.addweight()
图像处理
几何变换
-
图像缩放:对图像进行放大或缩小
cv.resize(img,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
interpolation插值 | 含义 |
---|---|
cv2.INTER_LINEAR | 双线性插值法 |
cv2.INTER_NEAREST | 最近邻插法 |
cv2.INTER_AREA | 像素区域重采样(默认) |
cv2.INTER_CUBIC | 双三次插值 |
-
图像平移:
指定平移矩阵后,调用
cv.warpAffine(img,M,(cols,rows))
平移图像 -
图像旋转:
调用
cv.getRotationMatrix2D(center, angle, scale)
获取旋转矩阵,然后调用cv.warpAffine()
进行旋转 -
仿射变换:
调用
cv.getAffineTransform
将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()
进行变换 -
透射变换:
通过函数
cv.getPerspectiveTransform()
找到变换矩阵,将cv.warpPerspective()
进行投射变换 -
金字塔
图像金字塔是图像多尺度表达的一种,使用的API:
-
cv.pyrUp(): 向上采样
-
cv.pyrDown(): 向下采样
-
形态学操作
- 连通性
- 邻接关系:4邻接,8邻接和D邻接
- 连通性:4连通,8连通和m连通
-
形态学操作
-
腐蚀和膨胀:
-
腐蚀:求局部最大值 cv.erode(img,kernel,iterations)
-
膨胀:求局部最小值 cv.dilate(img,kernel,iterations)
-
-
开闭运算:
-
开:先腐蚀后膨胀 cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
-
闭:先膨胀后腐蚀 cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
- 礼帽和黑帽:
-
礼帽:原图像与开运算之差 cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
-
黑帽:闭运算与原图像之差 cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
-
图像平滑
1. 图像噪声
- 椒盐噪声:图像中随机出现的白点或者黑点
- 高斯噪声:噪声的概率密度分布是正态分布
2. 图像平滑
- 均值滤波:算法简单,计算速度快,在去噪的同时去除了很多细节部分,将图像变得模糊
cv.blur(src, ksize, anchor, borderType)
- 高斯滤波: 去除高斯噪声
cv.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
- 中值滤波: 去除椒盐噪声
cv.medianBlur(src, ksize)
直方图
- 灰度直方图:
- 直方图是图像中像素强度分布的图形表达方式。
- 它统计了每一个强度值所具有的像素个数。
- 不同的图像的直方图可能是相同的
cv.calcHist (images,channels,mask,histSize,ranges[,hist[,accumulate]])
- 掩膜
创建蒙版,透过mask进行传递,可获取感兴趣区域的直方图
cv.bitwise_and(input_img,out_img,mask = mask)
- 直方图均衡化:增强图像对比度的一种方法
cv.equalizeHist()
:输入是灰度图像,输出是直方图均衡图像
4.自适应的直方图均衡
将整幅图像分成很多小块,然后再对每一个小块分别进行直方图均衡化,最后进行拼接
clahe cv.createCLAHE(clipLimit,tileGridSize)
边缘检测
-
边缘检测的原理
基于搜索:利用一阶导数的最大值获取边界
基于零穿越:利用二阶导数为0获取边界 -
Sobel算子
基于搜索的方法获取边界
-
cv.sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
-
cv.convertScaleAbs()
-
cv.addweights()
-
-
Laplacian算子
基于零穿越获取边界
cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
-
Canny算法
canny = cv2.Canny(image, threshold1, threshold2)
流程:
噪声去除:高斯滤波
计算图像梯度:sobel算子,计算梯度大小和方向
非极大值抑制:利用梯度方向像素来判断当前像素是否为边界点
滞后阈值:设置两个阈值,确定最终的边界
5 算子比较
算子 | 优缺点比较 |
---|---|
Roberts | 对具有陡峭的低噪声的图像处理效果较好,但利用Roberts算子提取边缘的结果是边缘比较粗,因此边缘定位不是很准确。 |
Sobel | 对灰度渐变和噪声较多的图像处理效果比较好,Sobl算子对边缘定位比较准确。 |
Kirsch | 对灰度渐变和噪声较多的图像处理效果较好。 |
Prewitt | 对灰度渐变和噪声较多的图像处理效果较好。 |
Laplacian | 对图像中的阶跃性边缘点定位准确,对噪声非常敏感,丢失一部分边缘的方向信息,造成一些不连续的检测边缘。 |
LoG | L0G算子经常出现双边缘像素边界,而且该检测方法对噪声比较敏感,所以很少用L0G算子检测边缘,而是用来判断边缘像素是位于图像的明区还是暗区。 |
Canny | 此方法不容易受噪声的干扰,能够检测到真正的弱边缘。在edge函数中,最有效的边缘检测方法是Canny方法。该方法的优点在于使用两种不同的阅值分别检测强边缘和弱边缘,并且仅当弱边缘与强边缘相连时,才将弱边缘包含在输出图像中。因此,这种方法不容易被噪声“填充”,跟容易检测出真正的弱边缘。 |
模版匹配和霍夫变换
- 模板匹配
-
原理:在给定的图片中查找和模板最相似的区域
-
API:利用
cv.matchTemplate()
进行模板匹配,然后使用cv.minMaxLoc()
搜索最匹配的位置。
- 霍夫线检测
-
原理:将要检测的内容转换到霍夫空间中,利用累加器统计最优解,将检测结果表示处理
-
API:cv2.HoughLines(img, rho, theta, threshold)
-
注意:该方法输入是的二值化图像,在进行检测前要将图像进行二值化处理
- 霍夫圆检测
-
方法:霍夫梯度法
-
API:cv.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0,maxRadius=0)
图像特征提取与描述
角点特征
图像特征
图像特征要有区分性,容易被比较。一般认为**角点,斑点**等是较好的图像特征
特征检测:找到图像中的特征
特征描述:对特征及其周围的区域进行描述
Harris和Shi-Tomas算法
1. Harris算法
思想:通过图像的局部的小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化。
**API:** **cv.cornerHarris(src, blockSize, ksize, k)**
2. Shi-Tomasi算法
对Harris算法的改进,能够更好地检测角点
**API:** **cv.goodFeaturesToTrack(image, maxcorners, qualityLevel, minDistance)**
SIFT/SURF算法!!!
-
SIFT原理:
尺度空间极值检测:构建高斯金字塔,高斯差分金字塔,检测极值点。
关键点定位:去除对比度较小和边缘对极值点的影响。
关键点方向确定:利用梯度直方图确定关键点的方向。
关键点描述:对关键点周围图像区域分块,计算块内的梯度直方图,生成具有特征向量,对关键点信息进行描述。
** API:cv.xfeatures2d.SIFT_create()**
kp,des = sift.detectAndCompute(gray,None)
cv.drawKeypoints(image, keypoints, outputimage, color, flags)
- SURF算法Todo
对SIFT算法的改进,在尺度空间极值检测,关键点方向确定,关键点描述方面都有改进,提高效率
视频操作
视频读写
-
读取视频:
读取视频:cap = cv.VideoCapture(filepath) 判断读取成功:cap.isOpened() 读取每一帧图像:ret,frame = cap.read() 获取属性:cap.get(proid) 设置属性:cap.set(proid,value) 资源释放:cap.release()
属性
| 索引 | flags | 意义 |
| ---- | ---- | ---- |
| 0 | cv2.CAP_PROP_POS_MSEC | 视频文件的当前位置(ms) |
| 1 | cv2.CAP_PROP_POS_FRAMES | 从0开始索引帧,帧位置 |
| 2 | cv2.CAP_PROP_POS_AVI_RATIO | 视频文件的相对位置(0表示开始,1表示结束) |
| 3 | cv2.CAP_PROP_FRAME_WIDTH | 视频流的帧宽度 |
| 4 | cv2.CAP_PROP_FRAME_HEIGHT | 视频流的帧高度 |
| 5 | cv2.CAP PROP_FPS | 帧率 |
| 6 | cv2.CAP_PROP_FOURCC | 编解码器四字符代码 |
| 7 | cv2.CAP_PROP_FRAME_COUNT | 视频文件的帧 |
import numpy as np
import cv2 as cv
# 1.获取视频对象
cap = cv.VideoCapture('DOG.wmv')
# 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 = cv.VideoWrite(filename,retval, fps, frameSize)
retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 ) 前置视频写入:out.write() 资源释放:out.release()
视频追踪
-
meanshift
原理:一个迭代的步骤,即先算出当前点的偏移均值,移动该点到其偏移均值,然后以此为新的起始点,继续移动,直到满足一定的条件结束。
API:cv.meanshift(probImage, window, criteria)
优缺点:简单,迭代次数少,但无法解决目标的遮挡问题并且不能适应运动目标的的形状和大小变化
-
camshift
原理:对meanshift算法的改进,首先应用meanshift,一旦meanshift收敛,它就会更新窗口的大小,还计算最佳拟合椭圆的方向,从而根据目标的位置和大小更新搜索窗口。
API:cv.camshift()
优缺点:可适应运动目标的大小形状的改变,具有较好的跟踪效果,但当背景色和目标颜色接近时,容易使目标的区域变大,最终有可能导致目标跟踪丢失
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具