OpenCV 基础操作代码合集
下面是一个完整的OpenCV基础操作代码合集,涵盖了图像处理中最常用的操作:
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def show_images(images, titles, rows=1, cols=None):
"""显示多张图像"""
if cols is None:
cols = len(images)
fig, axes = plt.subplots(rows, cols, figsize=(15, 5*rows))
if rows == 1 and cols == 1:
axes = [axes]
elif rows == 1 or cols == 1:
axes = axes.flat
else:
axes = axes.flat
for ax, img, title in zip(axes, images, titles):
if len(img.shape) == 3 and img.shape[2] == 3: # RGB图像
ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
else: # 灰度图
ax.imshow(img, cmap='gray')
ax.set_title(title)
ax.axis('off')
plt.tight_layout()
plt.show()
def main():
# ========== 1. 读取和显示图像 ==========
print("1. 读取和显示图像")
# 读取图像
image = cv2.imread('example.jpg') # 替换为你的图像路径
if image is None:
# 如果没有找到图像,创建一个示例图像
print("未找到图像,创建示例图像...")
image = np.zeros((300, 400, 3), dtype=np.uint8)
cv2.rectangle(image, (50, 50), (350, 250), (0, 255, 0), -1)
cv2.circle(image, (200, 150), 80, (255, 0, 0), -1)
cv2.putText(image, 'OpenCV', (120, 160),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
# 显示原始图像
show_images([image], ['原始图像'])
# ========== 2. 图像基本信息 ==========
print("2. 图像基本信息")
print(f"图像形状: {image.shape}")
print(f"图像尺寸: {image.shape[:2]}")
print(f"图像深度: {image.dtype}")
print(f"图像大小: {image.size} 像素")
# ========== 3. 颜色空间转换 ==========
print("3. 颜色空间转换")
# BGR转灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# BGR转HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# BGR转RGB(用于matplotlib显示)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
show_images([gray, hsv[:,:,0], rgb],
['灰度图像', 'HSV-H通道', 'RGB图像'])
# ========== 4. 图像缩放 ==========
print("4. 图像缩放")
# 指定尺寸缩放
resized = cv2.resize(image, (200, 150))
# 按比例缩放
scale_percent = 50 # 缩放50%
width = int(image.shape[1] * scale_percent / 100)
height = int(image.shape[0] * scale_percent / 100)
resized_percent = cv2.resize(image, (width, height))
show_images([image, resized, resized_percent],
['原始图像', '缩放至200x150', f'缩放{scale_percent}%'])
# ========== 5. 图像旋转 ==========
print("5. 图像旋转")
# 获取图像中心
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
# 旋转45度
M = cv2.getRotationMatrix2D(center, 45, 1.0)
rotated = cv2.warpAffine(image, M, (w, h))
# 旋转90度
rotated_90 = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
show_images([image, rotated, rotated_90],
['原始图像', '旋转45度', '旋转90度'])
# ========== 6. 图像裁剪 ==========
print("6. 图像裁剪")
# 指定区域裁剪
crop = image[50:200, 100:300] # y1:y2, x1:x2
show_images([image, crop],
['原始图像', '裁剪区域(50:200, 100:300)'])
# ========== 7. 图像滤波 ==========
print("7. 图像滤波")
# 高斯滤波
gaussian = cv2.GaussianBlur(image, (5, 5), 0)
# 中值滤波
median = cv2.medianBlur(image, 5)
# 均值滤波
blur = cv2.blur(image, (5, 5))
show_images([image, gaussian, median, blur],
['原始图像', '高斯滤波', '中值滤波', '均值滤波'])
# ========== 8. 边缘检测 ==========
print("8. 边缘检测")
# Canny边缘检测
edges = cv2.Canny(gray, 100, 200)
# Sobel边缘检测
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)
sobel = cv2.magnitude(sobel_x, sobel_y)
sobel = np.uint8(np.absolute(sobel))
show_images([gray, edges, sobel],
['灰度图像', 'Canny边缘检测', 'Sobel边缘检测'])
# ========== 9. 阈值处理 ==========
print("9. 阈值处理")
# 二值化阈值
_, thresh_binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 自适应阈值
thresh_adaptive = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# Otsu阈值
_, thresh_otsu = cv2.threshold(gray, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
show_images([gray, thresh_binary, thresh_adaptive, thresh_otsu],
['灰度图像', '二值化阈值', '自适应阈值', 'Otsu阈值'])
# ========== 10. 形态学操作 ==========
print("10. 形态学操作")
# 创建核
kernel = np.ones((5, 5), np.uint8)
# 腐蚀
erosion = cv2.erode(thresh_binary, kernel, iterations=1)
# 膨胀
dilation = cv2.dilate(thresh_binary, kernel, iterations=1)
# 开运算(先腐蚀后膨胀)
opening = cv2.morphologyEx(thresh_binary, cv2.MORPH_OPEN, kernel)
# 闭运算(先膨胀后腐蚀)
closing = cv2.morphologyEx(thresh_binary, cv2.MORPH_CLOSE, kernel)
show_images([thresh_binary, erosion, dilation, opening, closing],
['原二值图', '腐蚀', '膨胀', '开运算', '闭运算'])
# ========== 11. 轮廓检测 ==========
print("11. 轮廓检测")
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh_binary,
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
contour_img = image.copy()
cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)
print(f"找到 {len(contours)} 个轮廓")
# 计算轮廓特征
for i, contour in enumerate(contours[:3]): # 只显示前3个
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)
print(f"轮廓 {i}: 面积={area:.2f}, 周长={perimeter:.2f}")
show_images([image, contour_img],
['原始图像', f'检测到{len(contours)}个轮廓'])
# ========== 12. 直方图 ==========
print("12. 直方图")
# 计算直方图
color = ('b', 'g', 'r')
plt.figure(figsize=(15, 5))
# 显示原图
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('原始图像')
plt.axis('off')
# 显示直方图
plt.subplot(1, 2, 2)
for i, col in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=col, label=f'{col}通道')
plt.xlim([0, 256])
plt.title('颜色直方图')
plt.xlabel('像素值')
plt.ylabel('频数')
plt.legend()
plt.tight_layout()
plt.show()
# ========== 13. 图像融合 ==========
print("13. 图像融合")
# 创建两个图像用于融合
img1 = image.copy()
img2 = cv2.rotate(image, cv2.ROTATE_180)
# 图像融合
blended = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
show_images([img1, img2, blended],
['图像1', '图像2(旋转180°)', '融合图像(0.7:0.3)'])
# ========== 14. 绘制图形 ==========
print("14. 绘制图形")
draw_img = np.zeros((300, 400, 3), dtype=np.uint8)
# 绘制矩形
cv2.rectangle(draw_img, (50, 50), (150, 150), (0, 255, 0), 2)
# 绘制圆形
cv2.circle(draw_img, (200, 100), 50, (255, 0, 0), -1) # -1表示填充
# 绘制直线
cv2.line(draw_img, (250, 50), (350, 200), (0, 0, 255), 3)
# 添加文字
cv2.putText(draw_img, 'OpenCV', (100, 250),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
show_images([draw_img], ['绘制图形示例'])
# ========== 15. 保存图像 ==========
print("15. 保存图像")
cv2.imwrite('output_gray.jpg', gray)
cv2.imwrite('output_edges.jpg', edges)
cv2.imwrite('output_contours.jpg', contour_img)
print("已保存处理后的图像: output_gray.jpg, output_edges.jpg, output_contours.jpg")
# ========== 16. 视频处理基础 ==========
print("16. 视频处理基础")
# 摄像头捕获
def camera_capture():
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
return
print("按 'q' 键退出视频捕获")
while True:
ret, frame = cap.read()
if not ret:
print("无法读取帧")
break
# 转换为灰度
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 显示原图和灰度图
cv2.imshow('原视频', frame)
cv2.imshow('灰度视频', gray_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# 注释掉摄像头捕获,避免在脚本中自动运行
# camera_capture()
# ========== 17. 模板匹配 ==========
print("17. 模板匹配")
# 创建模板
template = image[50:100, 50:100] if image.shape[0] > 100 and image.shape[1] > 100 else image[10:50, 10:50]
# 进行模板匹配
result = cv2.matchTemplate(gray, cv2.cvtColor(template, cv2.COLOR_BGR2GRAY), cv2.TM_CCOEFF_NORMED)
# 找到最佳匹配位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
bottom_right = (top_left[0] + template.shape[1], top_left[1] + template.shape[0])
# 在图像上标记匹配区域
matched_img = image.copy()
cv2.rectangle(matched_img, top_left, bottom_right, (0, 255, 0), 2)
show_images([image, template, matched_img],
['原始图像', '模板', '匹配结果'])
if __name__ == "__main__":
main()
print("\n所有OpenCV基础操作演示完成!")
安装OpenCV
在运行上述代码前,需要先安装OpenCV:
bash
# 安装OpenCV
pip install opencv-python
pip install opencv-contrib-python # 包含额外功能
# 安装matplotlib用于显示图像
pip install matplotlib
# 安装numpy
pip install numpy
代码说明
这个代码合集包含了以下OpenCV基础操作:
-
图像读取与显示 - 读取图像并显示基本信息
-
颜色空间转换 - BGR、灰度、HSV等颜色空间转换
-
图像缩放 - 调整图像尺寸
-
图像旋转 - 旋转图像
-
图像裁剪 - 裁剪感兴趣区域
-
图像滤波 - 高斯滤波、中值滤波、均值滤波
-
边缘检测 - Canny和Sobel边缘检测
-
阈值处理 - 二值化、自适应阈值、Otsu阈值
-
形态学操作 - 腐蚀、膨胀、开运算、闭运算
-
轮廓检测 - 查找和绘制轮廓
-
直方图 - 计算和显示颜色直方图
-
图像融合 - 融合两幅图像
-
绘制图形 - 绘制矩形、圆形、直线和文字
-
保存图像 - 保存处理后的图像
-
视频处理 - 摄像头捕获和实时处理
-
模板匹配 - 在图像中查找模板
使用建议
-
测试图像 :将代码中的
'example.jpg'替换为你自己的图像路径 -
逐步学习:可以注释掉部分代码,逐个功能学习和测试
-
参数调整:尝试修改各个函数的参数,观察效果变化
-
扩展功能:在掌握基础后,可以探索更高级的OpenCV功能
这个代码合集涵盖了OpenCV最常用的基础操作,是学习计算机视觉和图像处理的良好起点。