import cv2 #图像BGR
import numpy as np
import matplotlib.pyplot as plt #Matplotlib是RGB
腐蚀操作
kernel = np.ones((3,3), np.uint8) #选择3*3卷积核,3*3括起来,(3,3)
erosion = cv2.erode(img, kernel, iterations = 1) #erode腐蚀函数, iterations迭代次数
膨胀操作
dige_dilate = cv2.dilate(dig_erosion, kernel, iterations = 1) #dilate膨胀函数
开运算,先腐蚀后膨胀 ,调用函数morphologyEx,使用参数cv2.MORPH_OPEN
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
闭运算,先膨胀后腐蚀,调用函数morphologyEx,使用参数cv2.MORPH_CLOSE
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
梯度运算:膨胀-腐蚀,调用函数morphologyEx,使用参数MORPH_GRADIENT
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
礼帽 = 原始输入-开运算 #开运算是先腐蚀后膨胀,去掉了毛刺,原始输入有毛刺减去开运算,结果为毛刺。使用MORPH_TOPHAT参数
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽 = 闭运算 - 原始输入 #闭运算是先膨胀后腐蚀,毛刺加大加粗了,减去原始输入,结果为加大加粗的毛刺轮廓。使用MORPH_BLACKHAT参数
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
Sobel算子,读入灰度图进行计算,计算法则:右-左,下-上
读入灰度图img = cv2.imread('pie.png', cv2.IMREAD_GRAYSCALE)
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
ddepth:图像的深度;dx和dy分别表示水平和竖直方向;ksize是Sobel算子的大小
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) # 水平方向,Ssobel算子为3
#sobelx是右减左,原图形内部是白色,外部是黑色,右减左法则,左半圆白色减黑色数值为正显示白色,右半圆黑色减白色数值为负,保留为0显示黑色
白到黑数值为正,显示白色,黑到白数值为负,截为0,所以需要取绝对值
sobelx = cv2.convertScaleAbs(sobelx)
分别计算x和y再求和
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
不建议一起计算sobelxy,会颜色变浅有重影,效果不好
sobelxy = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3)
梯度计算-scharr算子
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
梯度计算-Laplacian算子
laplacian = cv2.Laplacian(img, cv2.CV_64F)
图像平滑(均值滤波,高斯滤波,中值滤波)
#均值滤波,简单的平均卷积操作,3*3的核
blur = cv2.blur(img, (3,3))
#高斯滤波,更注重中间的。
#遵从高斯分布,靠近x的点数值大,重要程度高,权重高,离x远的点重要程度低,权重低
aussian = cv2.GaussianBlur(img, (5,5), 1)
#中值滤波。
#用中值代替,从小到大或从大到小排列,用中间值代替当前点亮度值
median = cv2.medianBlur(img, 5)
读入图像转为灰度图,调用cvtColor函数,使用 cv2.COLOR_BGR2GRAY参数
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
Canny边缘检测
- 1)使用高斯滤波器,平滑图像,滤除噪音
- 2)计算图像中每个像素点的梯度强度和方向
- 3)应用非极大值抑制(None-Maximum Suppression),以消除边缘检测带来的杂散响应
- 4)应用双阈值检测(Double-Threshold),确定真实地和潜在的边缘
- 5)通过抑制孤立的弱边缘最终完成边缘检测
调用Canny函数,cv2.Canny(src, threshold_bottom, threshold_top)
src:源图像
threshold_bottom: 阈值下限
threshold_top: 阈值上限
阈值下限越低,包含信息越丰富,边界值越丰富;阈值上限越高,符合要求的信息越少,边界值越严格。
v1 = cv2.Canny(img, 80, 150)
v2 = cv2.Canny(img, 50, 100)
左图为V1,右图为V2,可以看出右图边界值更加清晰丰富
图像轮廓分三步,
第一步预处理,对图像转换成灰度图,进行二值化操作,生成thresh文件算出轮廓,
第二步找到轮廓,cv2.findContours (img, mode, method)
第三步画出轮廓, cv2.drawContours(img, contours, index,mode, width)
1、预处理
img = cv2.imread('contours.png') # opencv读入图片'contours.png',格式为BGR
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将读入的图片BGR格式转换为灰度图gray
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) #对图片进行二值化操作,超过127置为255,低于127置为0
cv_show('thresh', thresh)
2、找到轮廓
cv2.findContours (img, mode, method)
img: 源图像
mode: 轮廓检索模式,常用RETR_TREE
- RETR_EXTERNAL:只检测最外面的轮廓;
- RETR_LIST: 检测所以轮廓,并将其保存在一条链表当中
- RETR_CCOMP:检测所有的轮廓,并将它们组织为两层;顶层是各部分的外部边界,第二层是空洞的边界;
- RETR_TREE: 检测所有轮廓,并重新嵌套轮廓的整个层次
method: 轮廓逼近方法
- CHAIN_APPROX_NONE: 以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
- CHAIN_APPROX_SIMPLE: 压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分
# 将二值化处理的图像thresh传入findContours参数,生成轮廓contours
binary, contours, hierarch = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
3、绘制轮廓
cv2.drawContours(img, contours, index,mode, width)
- img: 要绘制轮廓的源图像,默认在原图上绘制轮廓,一般先对原图进行copy操作生成副本,在副本上绘制轮廓
- contours: 轮廓信息
- index: 轮廓索引,‘-1’代表绘制所有轮廓,‘2’代表绘制第二个轮廓,‘3’代表绘制第三个轮廓
- mode: 颜色模式,(0, 0, 255)是红色,(0, 255, 0)是绿色,(255, 0, 0)是蓝色
- width: 轮廓线条宽度,一般为2,太宽了内外轮廓不好分辨,太细了不容易看到轮廓
# 默认在原图上绘制轮廓,将原图img进行copy,生成一个副本draw_img,将图像draw_img和轮廓contours传入drawContours,显示所有轮廓,使用B通道蓝色绘制,线宽为2
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (255, 0, 0), 2)
cv_show('res', res)
轮廓特征
cnt = contours[0]
cv2.contoursArea(cnt) # 面积
cv2.arcLength(cnt, True) # 周长
轮廓近似
cv2.approxPolyDP(contours, epsilon, bool)
contours: 输入轮廓
epsilon: 阈值,进行轮廓近似的阈值,原始曲线与近似曲线之间的最大距离。
bool: 如果为True近似轮廓闭合,False近似轮廓断开
epsilon = 0.01*cv2.arcLength(cnt, True) # 精度为周长的0.01倍
approx = cv2.approxPolyDP(cnt, epsilon, True) # 生成封闭近似轮廓epsilon
外接矩形
x,y,w,h = cv2.boundingRect(cnt) #求出外接矩形坐标
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0),2) #做出外界矩形
外接圆
(x,y), radius = cv2.minEnclosingCircle(cnt) #求出外接圆中心点坐标和半径
python语法:
range()创建左闭右开的区间,range(6)创建一个长度为6的空间,内部数字是0,1,2,3,4,5.
xticks()返回了两个对象,一个是刻标(locs),另外一个是刻度标签
locs, labels = xticks()
xticks([]),yticks([]),传入空的参数,不显示坐标和坐标标签
plt.title()设置图像标题,plt.title(‘img’),设置图像标题为img
plt.imshow()负责接受和对图像进行处理,并显示其格式,但是不正常展示图像.
plt.show()负责展示图像,展示imshow接受处理的图像。两个要结合一起使用。
np.hstack横着合成多张图
np.vstack竖着合成多张图
强制类型转换:类型( 变量),int(x),x转换为int类型
Markdown语法
“#”个数代表标题等级,等级越高字体越大,“#”是一级标题,“##”是二级标题,“#”要和字体空一格
“ - 1)”代表1)序号排列
“- ”代表一行,“-空格”
通过Markdown格式插入图片
插入图片的格式为:![图片标签](图片源 src)
英文输入法输入,![title](sobel_1.png),插入sobel_png图片