OpenCV 是一个功能强大的计算机视觉库,提供了丰富的图像处理方法。以下是一些常见图像处理操作的核心方法总结,涵盖读取、基本操作、变换、滤波、形态学、阈值、边缘检测等。
一、图像读取与保存
1. 读取图片
import cv2
# 读取图片(默认为 BGR 格式)
img = cv2.imread('image.jpg')
# 读取为灰度图
img_gray = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 读取为彩色(带透明度通道)
img_alpha = cv2.imread('image.png', cv2.IMREAD_UNCHANGED)
2. 保存图片
cv2.imwrite('output.jpg', img)
cv2.imwrite('output.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 5])
3. 显示图片
cv2.imshow('Image', img)
cv2.waitKey(0) # 等待按键
cv2.destroyAllWindows() # 关闭所有窗口
二、图像基本操作
1. 获取图像属性
h, w = img.shape[:2] # 高度、宽度
channels = img.shape[2] if len(img.shape) == 3 else 1 # 通道数
dtype = img.dtype # 数据类型
size = img.size # 总像素数
2. 裁剪 ROI (Region of Interest)
roi = img[y1:y2, x1:x2]
3. 调整大小
# 指定宽高
resized = cv2.resize(img, (new_w, new_h))
# 按比例缩放
scale = 0.5
resized = cv2.resize(img, None, fx=scale, fy=scale)
# 使用插值方法(默认 cv2.INTER_LINEAR)
resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_NEAREST)
4. 旋转
# 获取旋转矩阵
h, w = img.shape[:2]
center = (w//2, h//2)
M = cv2.getRotationMatrix2D(center, angle=45, scale=1.0)
# 执行旋转
rotated = cv2.warpAffine(img, M, (w, h))
三、颜色空间转换
# BGR ↔ 灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR ↔ RGB
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# BGR ↔ HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# BGR ↔ LAB
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
四、图像滤波
1. 均值滤波
blur = cv2.blur(img, (5,5))
2. 高斯滤波
blur = cv2.GaussianBlur(img, (5,5), sigmaX=0)
3. 中值滤波(去椒盐噪声)
median = cv2.medianBlur(img, 5)
4. 双边滤波(保边)
bilateral = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
五、形态学操作
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
# 腐蚀
eroded = cv2.erode(img, kernel, iterations=1)
# 膨胀
dilated = cv2.dilate(img, kernel, iterations=1)
# 开运算(先腐蚀后膨胀)
opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# 闭运算(先膨胀后腐蚀)
closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
# 形态学梯度(膨胀-腐蚀)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
# 顶帽(原图-开运算)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
# 黑帽(闭运算-原图)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
六、阈值处理
1. 简单阈值
ret, thresh = cv2.threshold(gray, thresh=127, maxval=255, type=cv2.THRESH_BINARY)
2. 自适应阈值
# 均值自适应
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, blockSize=11, C=2)
# 高斯自适应
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, blockSize=11, C=2)
3. Otsu 阈值(自动确定阈值)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
七、边缘检测
1. Canny 边缘检测
edges = cv2.Canny(img, threshold1=50, threshold2=150)
2. Sobel 算子
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) # x方向
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) # y方向
3. Laplacian 算子
laplacian = cv2.Laplacian(img, cv2.CV_64F)
八、图像增强
1. 直方图均衡化
# 灰度图
equalized = cv2.equalizeHist(gray)
# 彩色图(对每个通道分别处理或转到 YUV 处理 Y 通道)
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
equalized_color = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
2. CLAHE(限制对比度自适应直方图均衡)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(gray)
九、轮廓检测
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
contour_img = cv2.drawContours(img.copy(), contours, -1, (0,255,0), 2)
# 轮廓特征
for cnt in contours:
area = cv2.contourArea(cnt) # 面积
perimeter = cv2.arcLength(cnt, True) # 周长
approx = cv2.approxPolyDP(cnt, 0.02*perimeter, True) # 多边形近似
x, y, w, h = cv2.boundingRect(cnt) # 外接矩形
rect = cv2.minAreaRect(cnt) # 最小外接矩形
box = cv2.boxPoints(rect) # 获取矩形四个点
(x, y), radius = cv2.minEnclosingCircle(cnt) # 最小外接圆
十、几何变换
1. 仿射变换
pts1 = np.float32([[50,50], [200,50], [50,200]])
pts2 = np.float32([[10,100], [200,50], [100,250]])
M = cv2.getAffineTransform(pts1, pts2)
warped = cv2.warpAffine(img, M, (w, h))
2. 透视变换
pts1 = np.float32([[56,65], [368,52], [28,387], [389,390]])
pts2 = np.float32([[0,0], [300,0], [0,300], [300,300]])
M = cv2.getPerspectiveTransform(pts1, pts2)
warped = cv2.warpPerspective(img, M, (300,300))
十一、绘图操作
# 画线
cv2.line(img, (x1,y1), (x2,y2), (0,255,0), thickness=2)
# 画矩形
cv2.rectangle(img, (x1,y1), (x2,y2), (255,0,0), thickness=2)
# 画圆
cv2.circle(img, (x,y), radius=10, (0,0,255), thickness=-1) # -1为填充
# 画椭圆
cv2.ellipse(img, (x,y), (100,50), angle=0, startAngle=0, endAngle=180, color=(0,255,255), thickness=2)
# 添加文字
cv2.putText(img, 'OpenCV', (x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)
十二、模板匹配
result = cv2.matchTemplate(img, template, method=cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# 根据方法获取最佳匹配位置
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + tw, top_left[1] + th)
cv2.rectangle(img, top_left, bottom_right, (0,255,0), 2)
十三、图像金字塔
# 高斯金字塔
lower = cv2.pyrDown(img) # 缩小
higher = cv2.pyrUp(img) # 放大
# 拉普拉斯金字塔
layer = img.copy()
gp = [layer]
for i in range(6):
layer = cv2.pyrDown(layer)
gp.append(layer)
# 重建
layer = gp[-1]
lp = [layer]
for i in range(5,0,-1):
size = (gp[i-1].shape[1], gp[i-1].shape[0])
gaussian_expanded = cv2.pyrUp(gp[i], dstsize=size)
laplacian = cv2.subtract(gp[i-1], gaussian_expanded)
lp.append(laplacian)
十四、图像融合
# 简单叠加
blended = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
# 使用掩码
mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1]
mask_inv = cv2.bitwise_not(mask)
# ROI 替换
roi = img1[y:y+h, x:x+w]
roi_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
roi_fg = cv2.bitwise_and(img2, img2, mask=mask)
dst = cv2.add(roi_bg, roi_fg)
img1[y:y+h, x:x+w] = dst
注意事项
颜色通道顺序:OpenCV 默认使用 BGR 格式,其他库(如 Matplotlib)常用 RGB
数据类型:注意图像数据类型的转换(
img.astype(np.uint8))
内存管理:处理大图像时注意内存使用
性能优化:批量操作时使用 NumPy 向量化操作,避免循环
这些是 OpenCV 图像处理的常见操作,掌握了这些基础方法后,可以组合使用解决复杂的计算机视觉任务。建议在实际使用中参考 OpenCV 官方文档获取更详细的参数说明和示例。