- 默认
- 基础变换
- 模糊 锐化
- 色彩分层
- 傅里叶变换 高通低通
- 图像序列转换为视频
- 人脸识别
import opencv as cv2
img = cv2.imread('test.jpg') # imwrite('test.jpg',img)
cv2.imshow('test',img) # cv2 默认 BGR,plt 默认 RGB
# 同理 plt.imshow(img) # 可翻转 pltimg = img[:, :, ::-1],灰图 cmap = plt.cm.gray,去坐标 plt.axis('off')
# 等待输入 waitKey(0),destroyAllWindows(),destroyWindows()
rows, cols, chn = img.shape # 行列通道
b, g, r = cv2.split(img) # 拆分通道,或b = img[:, :, 0]
cv2.merge([b, g, r]) # 合并通道
canvas = np.zeros((rows, cols, chn), dtype = img.dtype) # chn 略为单通道可做 mask,dtype 默认 uint8
cv2.line(canvas, (0, 0), (10, 10), (255, 255, 255), 3) # 粗细 -1 为填充
# circle(img, pcenter, r, col)
# polylines(img, [pts], isClosed, col)
# putText(img, text, p, font, size, col)
cv2.copyMakeBorder(img, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value = (255, 255, 255))
cv2.bitwise_and(img1, img2, mask = mask) # 位运算,掩码为零矩阵,bitwise_or(),bitwise_not()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 色彩空间转换
# 可选:COLOR_BGR2RGB、COLOR_GRAY2BGR、CV_BGR2HSV、CV_BGR2XYZ、CV_BGR2HLS
cv2.calcHist([img], [chn], mask, [256], [0,255]) # x 轴等级 256,像素级 0 到 255,accumulate 默认不累计,直方图均衡 cv2.equalizeHist([img])
# 同理 plt.hist(img.ravel(), 256)
基础变换
cv2.resize(img, (10, 10)) # 缩放,或 resize(img, None, fx=.3, fy=.6)
cv2.flip(img, 0) # 翻转,0 垂直 1 水平 -1 垂直水平
m = np.float32([[1, 0, 0], [0, 1, 100]]) # 平移矩阵,参数 [[1,0,x], [0,1,y]]
m = cv2.getRotationMatrix2D(pcenter, angle, scale) # 旋转矩阵
cv2.warpAffine(img, m, (cols, rows)) # 仿射,应用平移旋转等
pos1 = np.float32([[50, 50], [200, 50], [50, 200]]) # 仿射映射位置
pos2 = np.float32([[10, 100], [200, 50], [100, 250]])
m = cv2.getAffineTransform(pos1, pos2) # 仿射矩阵,warpAffine() 应用
m = cv2.getPerspectiveTransform(pos1, pos2) # 透视矩阵,warpPerspective() 应用
模糊 锐化
# 加盐
for i in range(5000):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
img[x, y, :] = 255
kernel = cv2.ones((5, 5), np.uint8) # 卷积核
cv2.erode(img, kernel, iterations = 9) # 腐蚀去噪:压缩,迭代数默认 1
cv2.dilate(img, kernel) # 膨胀去噪:还原为逆腐蚀
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # 开运算(腐蚀后膨胀)去噪
# 可选:
# MORPH_CLOSE 闭运算(膨胀后腐蚀)去散点
# MORPH_GRADIENT 梯度(膨胀减腐蚀)检边
# MORPH_TOPHAT 顶帽(原图减开)或礼帽取白点均光
# MORPH_BLACKHAT 黑帽(闭减原图)取黑点均光
gaussian = cv2.GaussianBlur(gray, (3, 3), 0) # 高斯滤波加权计算,标准差 0
# 均值滤波 blur(img,(3,3))
# 中值滤波非线性 medianBlur(img,3)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 二值返回阈值127和处理后图像
# 可选:
# THRESH_BINARY_INV 反二进制阈值
# THRESH_TRUNC 截断阈值
# THRESH_TOZERO_INV 反阈值 0
# THRESH_TOZERO 阈值 0
# Scharr 检边为增强 Sobel,深度 CV_16S 或 CV_32F,10 为 x 一阶导,01 为 y 一阶导
x = cv2.Scharr(gray, cv2.CV_16S, 1, 0)
y = cv2.Scharr(gray, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x) # 转uint8
absY = cv2.convertScaleAbs(y)
scharr = cv2.addWeighted(absX, .5, absY, .5, 0) # 融合
# Canny 检边
canny = cv2.Canny(gaussian, 50, 150)
# Laplacian 检边分四邻域和八邻域,LOG(Laplacian of Gaussian) 为增强 Laplacian,最优滤波器
dst = cv2.Laplacian(binary, cv2.CV_16S, ksize = 3)
Laplacian = cv2.convertScaleAbs(dst)
色彩分层
# 图 K 聚类即色彩分层,聚成n类即色彩分 n 层
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
compactness, label, center = cv2.kmeans(data, 4, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
dst_gray = label.reshape((img.shape[0], img.shape[1]))
center = np.uint8(center) # 彩图需转换为 uint8
res = center[label.flatten()]
dst_color = cv2.cvtColor(res.reshape((img.shape)), cv2.COLOR_BGR2RGB)
cv2.pyrDown(img) # 向下取样,缩小
cv2.pyrUp(img) # 向上取样,放大
# 局部采样即马赛克
def drawMask(x, y, size = 10):
m = x / size * size
n = y / size * size
for i in range(size):
for j in range(size):
im[m + i][n + j] = im[m][n]
# 滤镜色卡
def getBGR(img, table, i, j):
b, g, r = img[i][j] # 原图色
x = int(g / 4 + int(b / 32) * 64) # 计算颜色坐标
y = int(r / 4 + int((b % 32) / 4) * 64)
return lj_map[x][y] # 返回滤镜色
# 读取滤镜色卡 lj_map = cv2.imread('table.png')
傅里叶变换 高通低通
import numpy as np
f = np.fft.fft2(a) # 傅变返回频率分布复数数组
# nD 傅变 fftn()
# nD 实数傅变 rfftn()
# 傅变采样频率 fftfreq()
fc = np.fft.fftshift(f) # 分布波形移到数组中心,默认数组起始
# 绝对值振幅图即频谱图 np.log(np.abs(fc))
crow, ccol = int(r / 2), int(c / 2) # 中心
fc[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0 # 高通滤波检边
mask = np.zeros((r, c, 2), np.uint8) # 低通滤波模糊
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
fc = fc * mask
f = np.fft.ifftshift(fc) # 分布波形移到数组起始
a = np.fft.ifft2(f) # 傅逆变
a = np.abs(a) # 复数转换为实数
# 灰图改形 np.float32(a.reshape((r*c,1)))
# 彩图改形 np.float32(a.reshape((r*c,1)).reshape((-1,3)))
图像序列转换为视频
img_root = 'z:/test/' # 序列文件夹
fps = 24 # 视频帧率
fourcc = cv2.VideoWriter_fourcc(*'XVID') # *'DVIX' 或 *'X264' 需 ffmepg
vw = cv2.VideoWriter('TestVideo.avi', fourcc, fps, (1920, 980), True) # 是否保存图片尺寸
for i in range(900):
frame = cv2.imread(img_root + str(i + 1) + '.jpg')
cv2.imshow('frame', frame)
vw.write(frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
vw.release()
cv2.destroyAllWindows()
人脸识别
import cv2 # pip install opencv-python
cascade_path = './models/haarcascade_frontalface_default.xml' # 脸部模型
# cascade_path = './models/haarcascade_frontalface_alt.xml'
# cascade_path = './models/haarcascade_frontalface_alt2.xml'
# cascade_path = './models/haarcascade_frontalface_alt_tree.xml'
eye_cascade_path = './models/haarcascade_eye.xml' # 眼睛模型
# eye_cascade_path = './models/haarcascade_eye_tree_eyeglasses.xml'
def run(imgPath=''):
outputPath = './output.jpg'
image = cv2.imread(imgPath) # 图片文件读取
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 灰度化
cascade = cv2.CascadeClassifier(cascade_path) # 分类器取得
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) # 脸型检测
if len(facerect) > 0: # 找到脸了
for rect in facerect: # 画出脸的位置
cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), (0, 255, 0), thickness=3)
eye_cascade = cv2.CascadeClassifier(eye_cascade_path) # 眼睛检测
eyes = eye_cascade.detectMultiScale(image_gray)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(image, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
cv2.imwrite(outputPath, image) # 结果保存
print('找到脸了!')
else:
print('对不起,没有脸!')
run(imgPath='./face0.jpg')
网友评论