openCV功能函数

news/2024/11/8 16:59:07/

形态学-腐蚀操作

cv2.erode(img, kernel, iterations=1)
img: 被处理图像
kernel: 处理图像用的盒子nxn大小
iterations: 函数运行次数

形态学-膨胀操作

cv2.dilate(img, kernel, iterations=1)

开运算和闭运算

开: 先腐蚀,再膨胀
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.MORPH_OPEN: 开运算
闭: 先膨胀,再腐蚀
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.MORPH_CLOSE: 闭运算

梯度运算

梯度 = 膨胀 - 腐蚀
cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

礼帽和黑帽

礼帽 = 原始输入 - 开运算结果
cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽 = 闭运算 - 原始输入
cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

图像梯度-Sobel算子

计算图像中像素点的梯度
cv2.Sobel(sec, ddepth, dx, dy, ksize)
ddepth: 图像的深度
dx和dy: 分别表示水平和竖直方向
ksize: 是Sobel算子的大小
白到黑是正数, 黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
sobelx = cv2.Sobel(sec, cv2.CV_64F, ddepth, dx, dy, ksize)
cv2.convertScaleAbs(sobelx)
分别计算x和y,再求和
cv2.addWeigthed(sobely, dx, sobely, dy, 0)
sobelx: 水平方向梯度
sobely: 竖直方向梯度
不建议直接计算x和y

Scharr算子

与Sobel算子的区别就是,计算用的矩阵中的数值比sobel中的要大,计算出来的图像梯度更明显

laplacian算子

梯度变化更敏感,对噪音点会比较敏感

Canny边缘检测

  1. 使用高斯滤波器,以平滑图像,过滤噪音
  2. 计算图像中每个像素点的梯度强度和方向
  3. 应用非极大值抑制,以消除边缘检测带来的杂散响应
  4. 应用双阈值检测,来确定真实的和潜在的边缘
  5. 通过抑制孤立的弱边缘最终完成边缘检测
cv2.Canny(img, minVal, maxVal)
minVal和maxVal: 双阈值检测的参数
高斯滤波器:中间值比较大,边缘值比较小

在Canny检测中对高斯滤波器进行归一化处理

Canny中使用的是sobel算子
非极大值抑制:线性插值法,划分方向法
双阈值检测
  1. 梯度值>maxVal,则处理为边界
  2. minVal<梯度值<maxVal,连有边界点则保留,否则舍弃
  3. 梯度值<minVal,则舍弃

图像金字塔

  1. 高斯金字塔
    做图像特殊提取,
  2. 拉普拉斯金字塔

高斯金字塔

向下采样方法(缩小):从塔底到塔尖

cv2.pyrUp(img)
  1. 将Gi与高斯内核卷积
  2. 将所有偶数行和列去除
    向上采样方法(放大):从塔尖到塔底
cv2.pyrDown(img)
  1. 将图像在每个方向扩大为原来的两倍,新增的行和列以0填充
  2. 使用先前同样的内核(乘以4)与放大后的图像卷积,获得近似值
    注意:若先进行上采样,后进行下采样,得到的结果图像没有原始的图像效果好

拉普拉斯金字塔

Li = Gi - PyrUp(PyrDown(Gi))
拉普拉斯金字塔 = 原始图像 减去 原始图像先做向下采样后做向上采样

down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_1 = img - down_up

图像轮廓检测

cv2.findContours(img, mode, method)
mode: 轮廓检索模式RETR_EXTERNAL: 只检索最外面的轮廓RETR_LIST: 检索所有的轮廓,并将其保存到一条链表当中RETR_CCOMP: 检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界RETR_TREE: 检索所有的轮廓,并重构嵌套轮廓的整个层次(常用)
method: 轮廓逼近方法CHAIN_APPROX_NONE: 以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)CHAIN_APPROX_SIMPLE: 压缩水平的,垂直的和倾斜的部分,也就是,函数只保留他们的终点部分

为了更高i的准确率,使用二值图像

img = cv2.imread('--.png') # 读入图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转为灰度图像
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BLNARY) # 二值转换
cv_show(thresh, 'thresh')
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 边缘检测
binary:二值检测结果
contours: list保存的轮廓信息
hierarchy:层级信息

绘制轮廓

# 传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2) # -1表示所有轮廓绘制, 2是线条的宽度
cv_show(res, 'res')

轮廓特征

# 计算轮廓面积
cnt = contours[0] # 把每个轮廓单独拿出来计算
cv2.contourArea(cnt)
# 计算周长
cv2.arcLength(cnt, True)

轮廓近似

epsilon = 0.1 * cv2.arcLength(cnt, True) # 用轮廓的周长的0.1倍作为阈值,阈值越小,得到的轮廓越接近原先的曲线轮廓
approx = cv2.approxPolyDP(cnt, epsilon, True)

绘制边界矩形

x, y, w, h = cv2.boundingRect(cnt) # 获取边缘矩形
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 在原始图像当中绘制边界矩形
rect_area = w * h # 边界矩形面积
area = cv2.contourArea(cnt) # cnt轮廓面积
extend = float(area) / rect_area # 轮廓面积与边界矩形比

绘制外接圆

(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0, 255, 0), 2)

模板匹配

模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv中有6种,然后将每次计算的结果放入一个矩阵中,作为结果输出。加入原图形是AB大小,而模板是ab大小,则输出结果的矩阵是(A - a + 1)* (B - b + 1)

TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
TM_CCORR:计算相关性,计算出来的值越大,越相关
TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关
建议使用带归一化的方法
# 模板匹配
img = cv2.imread('--.jpg', 0)
template = cv2.imread('--.jpg', 0)
h, w = template.shape[:2]res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF) # 模板匹配
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res) # 获取模板匹配不同匹配方式的结果,当前选择的是TM_SQDIFF, 应该选择minVal和minloc

多模板匹配

img_rgb = cv2.imread('---.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('---.jpg', 0)
h, w = template.shape[:2]res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8 # 设置一个阈值,来找出多个符合阈值的目标点
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):bottom_right = (pt[0] + w, pt[1] + h)cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)cv2.imshow('img_rgb', img_rgb)
cv2.waitKey(0)

图像直方图统计

横坐标:0~255,纵坐标:个数

img = cv2.imread('---.jpg')
hist = cv2.calcHist([img], [0], None, [256], [0, 256])plt.hist(img.ravel(), 256)
plt.show()images: 原图像格式为uint8或float32. 当传入函数时应用中括号【】括起来
channels:同样用中括号括起来,如果入图像是灰度图就是[0], 如果是彩色图,传入的参数可以是[0][1][2],分别对应着BGR
mask:掩模图像,统计整幅图像的直方图就设置为None
histSize: BIN的数目
ranges:像素值范围常为[0, 256]
彩色图直方图统计
img = cv2.imread('---.jpg')
color = ('b', 'g', 'r')
for i, col in enumerate(color):hist = cv2.calcHist([img], [i], None, [256], [0, 256])plt.plot(hist, color=col)plt.xlim([0, 256])
创建mask掩码
# 创建mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
# 与操作
mask_img = cv2.bitwise_and(img, img, mask=mask)
直方图均衡化
equ = cv2.equalizeHist(img)
# equ是做完均衡化后的像素点
自适应直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
res_clahe = clahe.apply(img)

傅里叶变换

傅里叶变换的作用

  1. 高频:变化剧烈的灰度分量,例如边界
  2. 低频:变化缓慢的灰度分量,例如一片大海

滤波

  1. 低通滤波器:只保留低频,会使得图像模糊
  2. 高通滤波器:只保留高频,会使得图像细节增强
    opencv中主要就是cv2.dft()和cv2.idft(),输入图像需要先转换成np.float32格式
    得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,可以通过shift变换来实现
    cv2.dft()返回的结果是双通道的(实部和虚部),通常还需要转换成图像格式才能展示
低通滤波
img = cv2.imread('---.jpg')
img_float = np.float(img)
# dft
dft = cv2.dft(img_float, flags=cv2.DFT_COMPLEX_OUTPUT)
# shift变换,将结果移动到中心
dft_shift = np.fft.fftshift(dft)rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)# 低通滤波
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1# 高通滤波
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0# idft
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])

http://www.ppmy.cn/news/53070.html

相关文章

《Left ventricular hypertrophy detection using electrocardiographic signal》阅读笔记

论文的摘要 Left ventricular hypertrophy (LVH) indicates subclinical organ damage, associating with the incidence of cardiovascular diseases. From the medical perspective, electrocardiogram (ECG) is a low-cost, non-invasive, and easily reproducible tool th…

java定时任务schedule

在 Java中&#xff0c;可以使用定时任务&#xff08;schedule&#xff09;来实现定时任务。这种定时任务能够根据用户的需求进行时间的控制&#xff0c;让用户可以自由设定每一个任务的开始时间和结束时间。 下面来介绍如何使用 java中的定时任务来实现定时任务。 首先需要在配…

R—读取数据(导入csv,txt,excel文件)

导入CSV、TXT文件 read.table函数&#xff1a;read.table函数以数据框的格式读入数据&#xff0c;所以适合读取混合模式的数据&#xff0c;但是要求每列的数据数据类型相同。read.table读取数据非常方便&#xff0c;通常只需要文件路径、URL或连接对象就可以了&#xff0c;也接…

业界内源码学习第一节

技术主题 业界内的技术研究 技术原理 HashMap是Java中最常用的数据结构之一,它使用键-值对的方式存储和管理数据。下面是Java 11中HashMap的简化版本源代码: java Copy code public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>,…

《站在巨人的肩膀上学习Java》

Java从诞生距今已经有28年了&#xff0c;在这段时间里&#xff0c;随着Java版本的不断迭代&#xff0c;Java新特性的不断出现&#xff0c;使得Java被使用的越来越广泛。在工程界Java语言一直是大家最喜欢的语言之一&#xff0c;Java一直排行在编程语言热门程度的前3名。 可想而…

用户的权限

Linux基础 提示&#xff1a;个人学习总结&#xff0c;仅供参考。 一、Linux系统部署 二、服务器初始化 三、文件和用户管理 四、用户的权限 提示&#xff1a;文档陆续更新整理 用户的权限 Linux基础一、基本权限UGO1. 权限对象&#xff1a;2. 权限类型3. 设置权限&#xff0…

AD9208的4通道 14-bit、2.4GSPS采样率之中文版资料

板卡概述 FMC137 是一款基于 VITA57.4 标准规范的 JESD204B 接口FMC 子 卡 模 块 &#xff0c; 该 模 块 可 以 实 现 4 路 14-bit 、 2GSPS/2.6GSPS/3GSPSADC 采集功能。该板卡 ADC 器件采用 ADI 公司的 AD9208 芯片&#xff0c;&#xff0c;与 ADI 公司的 AD9689 可以实现…

Docker 在Linux-CentOS上的安装使用

Linux CentOS 虚拟机安装及与windows远程登录_XiaoGuaiSs的博客-CSDN博客 一、如果安装过程有兼容问题&#xff0c;执行更新 yum 包&#xff08;生产环境中此步操作需慎重&#xff09; 注意​ yum -y update&#xff1a;升级所有包同时也升级软件和系统内核&#xff1b;​ …