图像读写与基础属性查看
import cv2
# 读取图片:第二个参数 1=彩色图,0=灰度图
img = cv2.imread("test.jpg", 1)
# 获取图像基本信息:高、宽、通道数(彩色3通道,灰度无通道)
h, w = img.shape[:2]
print(f"图片尺寸:宽{w},高{h}")
# 弹窗显示图片,窗口名是"image"
cv2.imshow("image", img)
cv2.waitKey(0) # 按任意键关闭窗口
cv2.destroyAllWindows()
# 保存处理后的图片
cv2.imwrite("result.jpg", img)
图像预处理三件套:灰度化 + 降噪 + 对比度增强
import cv2
img = cv2.imread("test.jpg", 1)
# 1. 灰度化:三通道转单通道黑白图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 高斯模糊:抹平噪点,(5,5)是模糊核大小,必须是奇数
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# 3. 直方图均衡化:拉大明暗对比,暗处细节更清晰
equal = cv2.equalizeHist(blur)
import cv2
import numpy as np
# 1. 读取图片(路径不能有中文,否则读不出来)
img = cv2.imread("test.jpg")
# img 是一个三维数组:[高度, 宽度, 3个颜色通道(BGR)]
h, w = img.shape[:2] # 拿到图片的高和宽
# 2. 常用基础操作
# 缩放:把图片缩放到 640x480
img_resized = cv2.resize(img, (640, 480))
# 裁剪:抠出图片中间区域 [行起始:行结束, 列起始:列结束]
img_crop = img[h//4 : 3*h//4, w//4 : 3*w//4]
# 转灰度图:3通道变1通道,减少计算量
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊:给图片磨皮去噪,消除小杂点
img_blur = cv2.GaussianBlur(img, (5, 5), 0)
# 边缘检测:提取物体轮廓,Canny是最经典的算法
img_edge = cv2.Canny(img_gray, 50, 150)
# 3. 画框写字(检测结果可视化必用)
cv2.rectangle(img, (100, 100), (300, 300), (0, 0, 255), 2) # 画红色矩形框,线宽2
cv2.putText(img, "person", (100, 90), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2) # 写标签
# 4. 保存和显示
cv2.imwrite("result.jpg", img_edge)
cv2.imshow("result", img)
cv2.waitKey(0) # 按任意键关闭窗口
cv2.destroyAllWindows()
Canny 边缘检测
import cv2
img = cv2.imread("test.jpg", 0)
blur = cv2.GaussianBlur(img, (3, 3), 0)
# 双阈值边缘检测:低阈值50,高阈值150
edges = cv2.Canny(blur, 50, 150)
霍夫直线检测
import cv2
import numpy as np
img = cv2.imread("test.jpg", 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
# 概率霍夫直线检测
lines = cv2.HoughLinesP(
edges,
rho=1, # 距离精度,1像素
theta=np.pi/180,# 角度精度,1度
threshold=100, # 阈值:至少多少个点共线才算直线
minLineLength=50, # 最短线长,太短的不算
maxLineGap=10 # 线中间最大断口,断口小于这个数算一条线
)
# 把检测到的直线画在原图上
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
形态学操作(腐蚀 / 膨胀 / 开闭运算)
import cv2
import numpy as np
img = cv2.imread("test.jpg", 0)
# 定义卷积核,越大效果越强
kernel = np.ones((3, 3), np.uint8)
# 腐蚀:白色区域变瘦,去掉细小噪点
erode = cv2.erode(img, kernel, iterations=1)
# 膨胀:白色区域变胖,连接断裂的线条
dilate = cv2.dilate(img, kernel, iterations=1)
# 开运算:先腐蚀再膨胀,去小噪点,保留大物体形状
open_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# 闭运算:先膨胀再腐蚀,填充物体内部的小洞
close_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
YOLOv8 目标检测推理(深度学习通用)
from ultralytics import YOLO
# 加载预训练模型,n/s/m/l/x 对应不同速度精度
model = YOLO("yolov8n.pt")
# 推理:图片/视频/文件夹都支持
results = model.predict(
source="test.jpg",
conf=0.5, # 置信度阈值,低于0.5的结果过滤掉
iou=0.45, # 非极大值抑制阈值,去重复框
device="0" # 用GPU,cpu就写"cpu"
)
# 可视化结果并保存
result_img = results[0].plot() # 自动画框、标类别和置信度
cv2.imwrite("det_result.jpg", result_img)
视频逐帧处理模板(改逻辑直接复用)
import cv2
# 1. 打开视频文件/摄像头(填0就是调用电脑摄像头)
cap = cv2.VideoCapture("input.mp4")
# 2. 获取视频原始参数:帧率、宽高
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 3. 创建视频写入器(输出新视频)
# 编码格式mp4v兼容最好,尺寸必须和输出帧的宽高严格一致
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter("output.mp4", fourcc, fps, (width, height))
# 4. 循环读帧处理
while True:
ret, frame = cap.read() # 读一帧,ret表示有没有读到
if not ret:
break # 视频读完就退出
# ====== 在这里写你的处理逻辑 ======
# 示例:把每一帧转灰度再转回3通道(否则存不了视频)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame_processed = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
# =================================
out.write(frame_processed) # 把处理后的帧写入新视频
cv2.imshow("video", frame_processed)
# 按q键中途退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 5. 释放资源(必须写,否则视频会损坏)
cap.release()
out.release()
cv2.destroyAllWindows()
批量图片处理脚本(数据集整理神器)
import os
import cv2
def batch_process_images(input_dir, output_dir, target_size=(640, 640)):
# 输出文件夹不存在就创建
os.makedirs(output_dir, exist_ok=True)
# 遍历文件夹里所有文件
for idx, filename in enumerate(os.listdir(input_dir)):
# 只处理图片格式
if filename.lower().endswith(('.jpg', '.png', '.jpeg', '.bmp')):
input_path = os.path.join(input_dir, filename)
try:
img = cv2.imread(input_path)
if img is None:
continue # 跳过损坏的图片
# 统一缩放到目标尺寸
img_resized = cv2.resize(img, target_size)
# 重命名保存:0001.jpg、0002.jpg...
new_name = f"{idx+1:04d}.jpg"
output_path = os.path.join(output_dir, new_name)
cv2.imwrite(output_path, img_resized)
print(f"处理完成: {filename} -> {new_name}")
except Exception as e:
print(f"处理失败 {filename}: {e}")
# 调用
if __name__ == "__main__":
batch_process_images("./raw_images", "./processed_images", target_size=(640, 640))