当前位置: 首页 > news >正文

OpenCV图片操作100例:从入门到精通指南(4)

OpenCV实战进阶:解锁计算机视觉高级技能

这些示例融合了深度学习、三维视觉和工业级应用,助力你成为OpenCV专家

六、专业级视觉处理

71. 图像配准(高精度对齐)

# 特征提取
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)# 特征匹配
bf = cv2.BFMatcher()
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)[:50]# 计算变换矩阵
src_pts = np.float32([kp1[m.queryIdx].pt for m in matches])
dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches])
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)# 应用变换
registered = cv2.warpPerspective(img1, M, (img2.shape[1], img2.shape[0]))

应用:医学影像序列对齐

72. 去雾算法(暗通道先验)

# 计算暗通道
def dark_channel(img, size=15):b, g, r = cv2.split(img)min_img = cv2.min(cv2.min(r, g), b)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size, size))dark = cv2.erode(min_img, kernel)return dark# 大气光估计
dark = dark_channel(img)
max_dark = np.max(dark)
atmosphere = []
for ch in cv2.split(img):atmosphere.append(np.max(ch[dark >= max_dark * 0.99]))# 透射率估计
transmission = 1 - 0.95 * dark_channel(img / atmosphere)# 图像恢复
result = np.empty_like(img, dtype=np.float32)
for i in range(3):result[:, :, i] = (img[:, :, i].astype(float) - atmosphere[i]) / cv2.max(transmission, 0.1) + atmosphere[i]
dehazed = np.clip(result, 0, 255).astype(np.uint8)

应用:自动驾驶中的场景清晰化

73. 显著性检测

# 谱残差方法
def spectral_residual_saliency(image):fft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)magnitude, phase = cv2.cartToPolar(fft[:, :, 0], fft[:, :, 1])# 计算对数幅度谱log_amplitude = np.log(magnitude)# 计算平均光谱avg_log_amplitude = cv2.blur(log_amplitude, (3, 3))# 计算谱残差spectral_residual = log_amplitude - avg_log_amplitude# 转换回傅里叶域real, imag = cv2.polarToCart(cv2.exp(spectral_residual), phase)back_fft = cv2.merge([real, imag])# 反傅里叶变换saliency_map = cv2.dft(back_fft, flags=cv2.DFT_INVERSE | cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT)return cv2.normalize(saliency_map, None, 0, 255, cv2.NORM_MINMAX)# 应用
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
saliency = spectral_residual_saliency(gray)

应用:智能图像裁剪

74. 稠密光流(Farneback)

# 初始化
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)# 计算稠密光流
flow = cv2.calcOpticalFlowFarneback(prev_gray, curr_gray, None, pyr_scale=0.5, levels=3, winsize=15, iterations=3, poly_n=5, poly_sigma=1.2, flags=0
)# 可视化
hsv = np.zeros_like(prev_frame)
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2
hsv[...,1] = 255
hsv[...,2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
flow_rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

应用:视频动作分析

75. 深度学习语义分割

# 加载模型
net = cv2.dnn.readNetFromTensorflow("deeplabv3_cityscapes.pb", "deeplabv3_cityscapes.pbtxt"
)# 输入处理
blob = cv2.dnn.blobFromImage(img, scalefactor=1/127.5, size=(512, 512),mean=(127.5, 127.5, 127.5), swapRB=True, crop=False
)
net.setInput(blob)# 推理
output = net.forward()# 后处理
output = output.squeeze().transpose(1, 2, 0)
class_map = np.argmax(output, axis=2)# 上色
colors = np.random.randint(0, 255, (256, 3), dtype=np.uint8)
result = colors[class_map]
result = cv2.resize(result, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_NEAREST)

应用:无人驾驶场景理解

七、工业级应用(86-100)

86. 目标计数(分水岭优化)

# 预处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (11, 11), 0)
thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]# 距离变换
dist_transform = cv2.distanceTransform(thresh, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * np.max(dist_transform), 255, 0)
sure_fg = np.uint8(sure_fg)# 分水岭分割
unknown = cv2.subtract(thresh, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers += 1
markers[unknown == 255] = 0
markers = cv2.watershed(img, markers)# 计数
num_objects = np.max(markers) - 1  # 减去背景标记
print(f"检测到 {num_objects} 个物体")

应用:仓库货物自动盘点

87. 手势识别

def detect_gesture(hand_contour):# 凸包检测hull = cv2.convexHull(hand_contour, returnPoints=False)defects = cv2.convexityDefects(hand_contour, hull)# 手指计数finger_count = 0for i in range(defects.shape[0]):s, e, f, d = defects[i, 0]far = tuple(hand_contour[f][0])if d > 10000:  # 阈值过滤finger_count += 1# 确定手势gestures = ["拳", "剪刀", "布", "三指", "四指", "五指"]return gestures[min(finger_count, len(gestures)-1)]

88. 车道线检测系统

# 透视变换
src = np.float32([[frame_w//2-30, frame_h*0.65], [frame_w//2+30, frame_h*0.65],[frame_w-50, frame_h], [50, frame_h]])
dst = np.float32([[0,0], [frame_w,0], [frame_w, frame_h], [0,frame_h]])
M = cv2.getPerspectiveTransform(src, dst)
warped = cv2.warpPerspective(frame, M, (frame_w, frame_h))# 车道线检测
gray = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=30, minLineLength=20, maxLineGap=300)# 车道拟合
left_lines, right_lines = [], []
for line in lines:for x1,y1,x2,y2 in line:slope = (y2-y1)/(x2-x1) if x2!=x1 else 9999if slope < -0.5: left_lines.append((x1,y1,x2,y2))elif slope > 0.5: right_lines.append((x1,y1,x2,y2))# 计算平均线
def average_line(lines):if not lines: return Noneavg_line = np.mean(np.array(lines), axis=0)return avg_line.astype(int)left_avg = average_line(left_lines)
right_avg = average_line(right_lines)# 绘制车道
road = warped.copy()
if left_avg is not None:cv2.line(road, (left_avg[0], left_avg[1]), (left_avg[2], left_avg[3]), (0,0,255), 5)
if right_avg is not None:cv2.line(road, (right_avg[0], right_avg[1]), (right_avg[2], right_avg[3]), (0,0,255), 5)

应用:自动驾驶核心功能

89. 三维重建(多视角)

# 特征匹配
matcher = cv2.BFMatcher(cv2.NORM_HAMMING)
matches = matcher.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)[:100]# 相机标定参数
K = np.array([[focal, 0, w/2], [0, focal, h/2], [0,0,1]])# 本质矩阵计算
points1 = np.float32([kp1[m.queryIdx].pt for m in matches])
points2 = np.float32([kp2[m.trainIdx].pt for m in matches])
E, mask = cv2.findEssentialMat(points1, points2, K, cv2.RANSAC, 0.999, 1.0)# 恢复姿态
_, R, t, mask = cv2.recoverPose(E, points1, points2, K, mask=mask)# 三角测量
points4D = cv2.triangulatePoints(np.hstack([np.eye(3), np.zeros((3,1))]), np.hstack([R, t]), points1.T, points2.T
)
points3D = points4D[:3] / points4D[3]

应用:文物数字化重建

90. 异常检测(深度学习)

# 加载自编码器
net = cv2.dnn.readNetFromONNX("autoencoder.onnx")# 特征提取
input_blob = cv2.dnn.blobFromImage(img, scalefactor=1/255., size=(256,256),mean=(0.485, 0.456, 0.406), swapRB=True
)
net.setInput(input_blob)
output_blob = net.forward()# 异常分数计算
reconstruction = output_blob.squeeze().transpose(1,2,0)
reconstruction = cv2.resize(reconstruction, (img.shape[1], img.shape[0]))
original = cv2.resize(input_blob.squeeze().transpose(1,2,0), (img.shape[1], img.shape[0]))anomaly_map = np.mean(np.abs(original - reconstruction), axis=2)
anomaly_score = np.max(anomaly_map)# 异常区域标注
if anomaly_score > 0.2:contours = cv2.findContours((anomaly_map > 0.2).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]for cnt in contours:x,y,w,h = cv2.boundingRect(cnt)cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2)cv2.putText(img, f"异常检测! 分数: {anomaly_score:.3f}", (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)

应用:工业质检

八、前沿应用(91-100)

91. 实时虚拟试穿

# 身体姿态估计
net = cv2.dnn.readNetFromTensorflow("pose_net.pb")
blob = cv2.dnn.blobFromImage(img, 1.0, (368,368), (127.5,127.5,127.5), swapRB=True)
net.setInput(blob)
output = net.forward()# 关键点提取
keypoints = []
for i in range(output.shape[1]):heatMap = output[0, i, :, :]_, conf, _, point = cv2.minMaxLoc(heatMap)if conf > 0.1:keypoints.append((point[0], point[1]))# 三角网格变形
def TPS_transform(src, dst, points):tps = cv2.createThinPlateSplineShapeTransformer()matches = [cv2.DMatch(i, i, 0) for i in range(len(src))]tps.estimateTransformation(np.array([src]), np.array([dst]), matches)return tps.applyTransformation(np.array([points]))[1]# 应用变形
garment = cv2.imread("garment.png", cv2.IMREAD_UNCHANGED)
mesh_points = get_garment_mesh(garment)
transformed_mesh = TPS_transform(garment_points, keypoints, mesh_points)# 融合渲染
result = warp_image(garment, transformed_mesh)
final = blend_images(img, result)

应用:虚拟时尚

92. 神经风格迁移(实时)

# 加载FastStyleTransfer模型
net = cv2.dnn.readNetFromTorch("style_model.t7")# 视频流处理
while True:ret, frame = cap.read()blob = cv2.dnn.blobFromImage(frame, 1.0, (400,400), (103.939, 116.779, 123.680), swapRB=False, crop=False)net.setInput(blob)output = net.forward()# 后处理output = output.reshape((3, output.shape[2], output.shape[3]))output[0] += 103.939output[1] += 116.779output[2] += 123.680output = output.transpose(1, 2, 0)output = np.clip(output, 0, 255)output = output.astype(np.uint8)cv2.imshow("Artistic Style", output)

应用:实时视频特效

93. 聚焦堆栈融合

# 多焦点图像序列
images = [cv2.imread(f"focus{i}.jpg") for i in range(10)]
focus_maps = []
laplacian = cv2.Laplacian(cv2.cvtColor(images[0], cv2.COLOR_BGR2GRAY), cv2.CV_64F)# 锐度图计算
sharpness_maps = []
for img in images:gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)lap = cv2.Laplacian(gray, cv2.CV_64F)sharpness = cv2.GaussianBlur(np.abs(lap), (5,5), 0)sharpness_maps.append(sharpness)# 焦点堆栈融合
fused = np.zeros_like(images[0], dtype=np.float32)
for ch in range(3):channel_stack = np.array([img[:,:,ch] for img in images])weight_stack = np.array(sharpness_maps)weight_stack = np.expand_dims(weight_stack, axis=3)weight_sum = np.sum(weight_stack, axis=0)weight_sum[weight_sum < 1e-5] = 1e-5  # 避免除零fused_ch = np.sum(channel_stack * weight_stack, axis=0) / weight_sumfused[:,:,ch] = fused_chfused_img = np.clip(fused, 0, 255).astype(np.uint8)

应用:显微摄影

94. 水下图像增强

# 颜色校正
lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
lab[:,:,0] = clahe.apply(lab[:,:,0])
enhanced_lab = cv2.cvtColor(lab, cv2.COLOR_Lab2BGR)# 蓝光修正
hsv = cv2.cvtColor(enhanced_lab, cv2.COLOR_BGR2HSV)
blue_range = cv2.inRange(hsv, (90, 50, 50), (130, 255, 255))
enhanced_lab = cv2.inpaint(enhanced_lab, blue_range, 3, cv2.INPAINT_TELEA)# 对比度增强
ycrcb = cv2.cvtColor(enhanced_lab, cv2.COLOR_BGR2YCrCb)
ycrcb[:,:,0] = cv2.equalizeHist(ycrcb[:,:,0])
final = cv2.cvtColor(ycrcb, cv2.COLOR_YCrCb2BGR)

应用:海洋探索

95. 皮肤分析系统

def analyze_skin(image):# 人脸检测face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')faces = face_cascade.detectMultiScale(image, 1.3, 5)if len(faces) == 0: return None# 提取ROI(x,y,w,h) = faces[0]face_roi = image[y:y+h, x:x+w]# 皮肤分割lab = cv2.cvtColor(face_roi, cv2.COLOR_BGR2Lab)low_thresh = np.array([0, 120, 140]) high_thresh = np.array([255, 140, 165])mask = cv2.inRange(lab, low_thresh, high_thresh)mask = cv2.medianBlur(mask, 5)# 分析指标smoothness = cv2.Laplacian(face_roi, cv2.CV_64F).var()redness = np.mean(face_roi[mask == 255][:,2])pores = np.count_nonzero(cv2.morphologyEx(mask, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))))return {"光滑度": smoothness,"泛红指数": redness,"毛孔密度": pores / np.count_nonzero(mask) * 1000}

96. 植物健康分析

def plant_health_analysis(image):# 叶脉提取lab = cv2.cvtColor(image, cv2.COLOR_BGR2Lab)l, a, b = cv2.split(lab)clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))enhanced_l = clahe.apply(l)# 叶脉分割vein_mask = cv2.adaptiveThreshold(enhanced_l, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)vein_mask = cv2.morphologyEx(vein_mask, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)))# 计算参数vein_length = np.sum(vein_mask > 0) / image.size[0] * 1000  # 标准化脉长health_score = 0.6 * np.mean(b) + 0.4 * (255 - np.mean(a))  # 健康指数(越高越好)return vein_mask, {"叶脉密度": vein_length,"健康指数": health_score,"缺素症状": "有" if np.mean(a) > 140 else "无"}

97. 人群密度估计

def crowd_density_estimation(image):# 加载密度图模型net = cv2.dnn.readNetFromCaffe("MCNN.prototxt", "MCNN.caffemodel")# 预处理blob = cv2.dnn.blobFromImage(image, 1, (800, 600), (0,0,0), False, False)net.setInput(blob)# 密度图生成density_map = net.forward()# 人数估计count = np.sum(density_map)# 可视化norm_density = cv2.normalize(density_map, None, 0, 255, cv2.NORM_MINMAX)norm_density = cv2.applyColorMap(np.uint8(norm_density), cv2.COLORMAP_JET)norm_density = cv2.resize(norm_density, (image.shape[1], image.shape[0]))blended = cv2.addWeighted(image, 0.7, norm_density, 0.3, 0)cv2.putText(blended, f"人数: {int(count)}", (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)return blended

98. 动态全息显示

def generate_hologram(image, wavelength=532e-9, z=0.1):"""模拟菲涅尔全息图生成"""# 生成空间坐标h, w = image.shape[:2]x = np.linspace(-w//2, w//2, w)y = np.linspace(-h//2, h//2, h)xx, yy = np.meshgrid(x, y)# 计算全息图hologram = np.zeros((h, w), dtype=np.complex128)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY).astype(float)/255for i in range(h):for j in range(w):if gray[i,j] > 0.1:  # 忽略暗区# 菲涅尔衍射计算r = np.sqrt((xx - j)**2 + (yy - i)**2 + z**2)hologram += gray[i,j] * np.exp(1j * 2 * np.pi * r / wavelength) / r# 提取相位信息phase = np.angle(hologram)phase_normalized = (phase + np.pi) / (2 * np.pi) * 255return phase_normalized.astype(np.uint8)

99. 工业尺寸测量

def industrial_measurement(image, reference_width):# 预处理gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)blur = cv2.GaussianBlur(gray, (5,5), 0)edges = cv2.Canny(blur, 50, 150)# 寻找轮廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 测量结果results = []for cnt in contours:# 筛选合理大小轮廓area = cv2.contourArea(cnt)if area < 500: continue# 最小外接矩形rect = cv2.minAreaRect(cnt)width, height = rect[1]box = cv2.boxPoints(rect)box = np.int0(box)# 像素到实际尺寸转换actual_width = min(width, height) * reference_widthactual_height = max(width, height) * reference_widthresults.append({"box": box,"width": actual_width,"height": actual_height,"area": area * (reference_width ** 2)})return results

100. 实时手势交互系统

def gesture_control_system():# 初始化cap = cv2.VideoCapture(0)hands = mp.solutions.hands.Hands(max_num_hands=1)while True:ret, frame = cap.read()if not ret: break# 手势识别rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)results = hands.process(rgb)if results.multi_hand_landmarks:landmarks = results.multi_hand_landmarks[0].landmark# 关键点提取fingertips = [(int(landmarks[4].x * w), int(landmarks[4].y * h)),  # 拇指(int(landmarks[8].x * w), int(landmarks[8].y * h)),  # 食指(int(landmarks[12].x * w), int(landmarks[12].y * h)),  # 中指(int(landmarks[16].x * w), int(landmarks[16].y * h)),  # 无名指(int(landmarks[20].x * w), int(landmarks[20].y * h)),  # 小指]# 手势识别extended_fingers = 0for fingertip in fingertips:# 计算与掌心距离center_x = int(landmarks[0].x * w)center_y = int(landmarks[0].y * h)distance = np.sqrt((fingertip[0]-center_x)**2 + (fingertip[1]-center_y)**2)if distance > 100:  # 阈值判断extended_fingers += 1# 指令映射commands = {0: "握拳",1: "食指",2: "剪刀手",3: "三指",4: "四指",5: "手掌"}command = commands.get(extended_fingers, "未知")# 绘制界面cv2.circle(frame, (center_x, center_y), 8, (0,255,0), -1)for tip in fingertips:cv2.circle(frame, tip, 6, (0,0,255), -1)cv2.putText(frame, f"命令: {command}", (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)cap.release()

学习路径与资源推荐

OpenCV能力矩阵图


学习资源推荐

  1. 官方资源​:

    • OpenCV官方文档
    • OpenCV Wiki
  2. 图书推荐​:

    • 《Learning OpenCV 4》Adrian Kaehler著
    • 《OpenCV 4.x with Python By Example》Prateek Joshi著
  3. 在线课程​:

    • Coursera: Deep Learning for Computer Vision
    • Udemy: OpenCV Bootcamp
  4. 实战项目​:

    • Kaggle竞赛:图像分类、物体检测
    • GitHub仓库:open-smartcamera

关注我们并继续了解更多干货!OpenCv与人工智能!


开启你的计算机视觉专家之旅

#OpenCV #计算机视觉 #人工智能 #工业视觉 #深度学习

http://www.dtcms.com/a/270857.html

相关文章:

  • [C#/.NET] 内网开发中如何使用 System.Text.Json 实现 JSON 解析(无需 NuGet)
  • 树莓派vsftpd文件传输服务器的配置方法
  • Java 大视界 -- 基于 Java 的大数据分布式计算在生物信息学蛋白质 - 蛋白质相互作用预测中的应用(340)
  • 【算法深练】DFS题型拆解:沿着路径“深挖到底”、递归深入、回溯回探的算法解题思路
  • 【数据分析】多数据集网络分析:探索健康与退休研究中的变量关系
  • ESOP系统电子作业指导汽车零部件车间的数字化革命
  • 玛哈特网板矫平机:精密矫平金属开平板的利器
  • 钉钉企业应用开发技巧:查询表单实例数据新版SDK指南
  • 2023年华为杯研究生数学建模竞赛A题WLAN组网分析
  • 结构体指针:使用结构体指针访问和修改结构体成员。
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_ecn_fallback
  • softmax
  • GitHub 趋势日报 (2025年07月08日)
  • SQLZoo 练习与测试答案汇总(复杂题有最优解与其他解法分析、解题技巧)
  • 分类预测 | Matlab基于KPCA-ISSA-SVM和ISSA-SVM和SSA-SVM和SVM多模型分类预测对比
  • 打造自己的组件库(二)CSS工程化方案
  • Tensorflow的安装记录
  • 一天一道Sql题(day04)
  • 开源链动2+1模式与AI智能名片融合下的S2B2C商城小程序源码:重构大零售时代新生态
  • 华为静态路由配置
  • linux正向配置dns解析
  • 事件驱动架构
  • 汽车工业制造领域与数字孪生技术的关联性研究​
  • UI前端大数据处理性能评估与优化:基于负载测试的数据处理能力分析
  • 利用Wisdom SSH高效搭建CI/CD工作流
  • python Gui界面小白入门学习
  • # Shell 编程:从入门到实践
  • Android 系统默认代码,如何屏蔽相册分享功能
  • Android 组件内核
  • Go语言高级面试必考:切片(slice)你真的掌握了吗?