18.形态学处理函数
腐蚀:
erode(src,kernel,dst,anchor,iterations,borderType,bordervalue)
膨胀
dilate(src,kernel,dst,anchor,iterations,borderType,bordervalue)
开运算&闭运算
morphologyEx(img,cv2.MORPH_OPEN,kernel)
morphologyEx(img,cv2.MORPH_CLOSE,kernel)
梯度运算(边界提取) =膨胀-腐蚀
morphologyEx(img,cv2.MORPH_GRADIENT,kernel)
礼帽(顶帽)= 原图-开运算结果
morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
黑帽(底帽)=闭运算结果-原图
morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)
img = cv.imread('000.png')#读取图像 kernel = np.ones((5, 5), np.uint8) #定义核 img2 = cv.erode(img, kernel, 3) #腐蚀 img3 = cv.dilate(img, kernel, 3)#膨胀 opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel) #开运算 closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel) #闭运算 gradient = cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel) #梯度运算 tophat = cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel) #礼帽 blackhat = cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel) #黑帽
19.边界填充
cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType)
参数:
BORDER_REPLICATE: 复制法
BORDER_REFILECT: 反射法:fedcba | abcdefgh | hgfedcb
BORDER_REFLECT_101: 反射法,从最边缘的像素为轴,对称 gfedcb | abcdefgh | ghedcba
BORDER_WRAP: 外包装法 cdefgh | abcdefgh |abcdefg
BORDER_CONSTANT: 常量法,常数值填充
20.图像轮廓
image,contours,hierarchy=findContours(img,mode,method)
image代表的是修改之后的原图,contours代表的是轮廓,hierarchy代表的是轮廓的层次结构
参数:
mode:轮廓检索模式
RETR_EXTERNAL:只检索最外面的轮廓
RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中
RETR_CCOMP:检索所有的轮廓,并肩他们组织为两层:顶层为各部分外部边界,第二层是空洞的边界
RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次
method:轮廓逼近方法
CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其它方法输出多边形
CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜着的部分,也就是函数只保留他们终点部分
21.仿射变换&透射变换
仿射变换:调用cv.getAffineTransform(pts1 , pts2)将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()进行变换
pts1 原图像三个点的坐标
pts2 原图像三个点在变换后相应的坐标
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('img/6.jpg') rows, cols, ch = img.shape pts1 = np.float32([[50, 50], [200, 50], [50, 200]]) pts2 = np.float32([[10, 100], [200, 50], [100, 250]]) M = cv2.getAffineTransform(pts1, pts2) dst = cv2.warpAffine(img, M, (cols, rows)) plt.subplot(121), plt.imshow(img), plt.title('Input') plt.subplot(122), plt.imshow(dst), plt.title('output') plt.show()
投射变换:通过cv.getPerspectiveTransform()找到变换矩阵,将cv.warpPerspective()进行透射变换
import numpy as np import cv2 as cv import matplotlib.pyplot as plt # 1 读取图像 img = cv.imread("img/6.jpg") # 2 透射变换 rows, cols = img.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(img, T, (cols, rows)) # 3 图像显示 fig, axes=plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100) axes[0].imshow(img[:, :, ::-1]) axes[0].set_title("in") axes[1].imshow(dst[:, :, ::-1]) axes[1].set_title("out") plt.show()
22.绘制直线,圆形,矩形,添加文字
cv.line(img, start, end, color, thickness)
参数:
img:要绘制直线的图像
Start,end: 直线的起点和终点
color: 线条的颜色
Thickness: 线条宽度
cv.circle(img, centerpoint, r, color, thickness)
参数:
img:要绘制圆形的图像
Centerpoint, r: 圆心和半径
color: 线条的颜色
Thickness: 线条宽度,为-1时生成闭合图案并填充颜色
cv.rectangle(img, leftupper, rightdown, color, thickness)
参数:
img:要绘制矩形的图像
Leftupper, rightdown: 矩形的左上角和右下角坐标
color: 线条的颜色
Thickness: 线条宽度
cv.putText(img, text, station, font, fontsize, color, thickness, cv.LINE_AA)
参数:
img: 图像
text:要写入的文本数据
station:文本的放置位置
font:字体
Fontsize :字体大小
#我们生成一个全黑的图像,然后在里面绘制图像并添加文字 # 1 创建一个空白的图像 img = np.zeros((512,512,3), np.uint8) # 2 绘制图形 cv.line(img,(0,0),(511,511),(255,0,0),5) #线 cv.rectangle(img,(384,0),(510,128),(0,255,0),3) #矩形 cv.circle(img,(447,63), 63, (0,0,255), -1)#圆 font = cv.FONT_HERSHEY_SIMPLEX cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA) #文字 # 3 图像展示 plt.imshow(img[:,:,::-1]) plt.title('匹配结果'), plt.xticks([]), plt.yticks([]) plt.show()
23.缩放,平移,旋转
cv2.resize(InputArray src, OutputArray dst, Size dsize,
double fx=0, double fy=0, int interpolation=INTER_LINEAR )
参数:
src : 输入图像
dsize: 绝对尺寸,直接指定调整后图像的大小
fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可
interpolation:插值方法,
import cv2 as cv import matplotlib.pyplot as plt # 1. 读取图片 img = cv.imread("img/2.jpg") # 2.图像缩放 # 2.1 绝对尺寸 rows, cols = img.shape[:2] # 获取图像行或列 res = cv.resize(img, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC) # 2.2 相对尺寸 res1 = cv.resize(img, None, fx=0.5, fy=0.5) # 3.2 使用matplotlib显示图像 plt.subplot(131) plt.imshow(img[:, :, ::-1]) plt.subplot(132) plt.imshow(res[:, :, ::-1]) plt.subplot(133) plt.imshow(res1[:, :, ::-1]) plt.show()
平移cv.warpAffine(img,M,dsize)
import cv2 as cv import matplotlib.pyplot as plt # 1. 读取图像 img1 = cv.imread("img/6.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("after") plt.show()
旋转cv2.getRotationMatrix2D(center, angle, scale)
参数:
center:旋转中心
angle:旋转角度
scale:缩放比例
返回:
M:旋转矩阵
调用cv.warpAffine完成图像的旋转
import cv2 import matplotlib.pyplot as plt img = cv2.imread('img/6.jpg') rows, cols = img.shape[:2] # 第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例 M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1) # 第三个参数:变换后的图像大小 res = cv2.warpAffine(img, M, (rows, cols)) plt.subplot(121) plt.imshow(img[:, :, ::-1]) plt.subplot(122) plt.imshow(res[:, :, ::-1]) plt.show()
24.霍夫变换
24.1霍夫线检测
cv.HoughLines(img, rho, theta, threshold)
参数:
img: 检测的图像,要求是二值化的图像,所以在调用霍夫变换之前首先要进行二值化,或者进行Canny边缘检测
rho、theta: \rhoρ 和\thetaθ的精确度
threshold: 阈值,只有累加器中的值高于该阈值时才被认为是直线
注意:该方法输入是的二值化图像,在进行检测前要将图像进行二值化处理
import numpy as np import random import cv2 as cv import matplotlib.pyplot as plt # 1.加载图片,转为二值图 img = cv.imread('./image/rili.jpg') gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) edges = cv.Canny(gray, 50, 150) # 2.霍夫直线变换 lines = cv.HoughLines(edges, 0.8, np.pi / 180, 150) # 3.将检测的线绘制在图像上(注意是极坐标噢) for line in lines: rho, theta = line[0] a = np.cos(theta) b = np.sin(theta) x0 = a * rho y0 = b * rho x1 = int(x0 + 1000 * (-b)) y1 = int(y0 + 1000 * (a)) x2 = int(x0 - 1000 * (-b)) y2 = int(y0 - 1000 * (a)) cv.line(img, (x1, y1), (x2, y2), (0, 255, 0)) # 4. 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.imshow(img[:,:,::-1]),plt.title('霍夫变换线检测') plt.xticks([]), plt.yticks([]) plt.show()
24.2霍夫圆检测
circles = cv.HoughCircles(image, method, dp, minDist, param1=100,param2=100,minRadius=0,maxRadius=0 )
参数:
image:输入图像,应输入灰度图像
method:使用霍夫变换圆检测的算法,它的参数是CV_HOUGH_GRADIENT
dp:霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推
minDist为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心
param1:边缘检测时使用Canny算子的高阈值,低阈值是高阈值的一半。
param2:检测圆心和确定半径时所共有的阈值
minRadius和maxRadius为所检测到的圆半径的最小值和最大值
返回:
circles:输出圆向量,包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆半径
由于霍夫圆检测对噪声比较敏感,所以首先对图像进行中值滤波。
import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 1 读取图像,并转换为灰度图 planets = cv.imread("./image/star.jpeg") gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY) # 2 进行中值模糊,去噪点 img = cv.medianBlur(gay_img, 7) # 3 霍夫圆检测 circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 200, param1=100, param2=30, minRadius=0, maxRadius=100) # 4 将检测结果绘制在图像上 for i in circles[0, :]: # 遍历矩阵每一行的数据 # 绘制圆形 cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2) # 绘制圆心 cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3) # 5 图像显示 plt.figure(figsize=(10,8),dpi=100) plt.imshow(planets[:,:,::-1]),plt.title('霍夫变换圆检测') plt.xticks([]), plt.yticks([]) plt.show()
持续更新中!