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

Python OpenCV精讲系列 - 高级图像处理技术(六)

在这里插入图片描述

💖💖⚡️⚡️专栏:Python OpenCV精讲⚡️⚡️💖💖
本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计,从基础概念入手,逐步深入到图像处理、特征检测、物体识别等多个领域。适合希望在计算机视觉方向上建立坚实基础的技术人员及研究者。每一课不仅包含理论讲解,更有实战代码示例,助力读者快速将所学应用于实际项目中,提升解决复杂视觉问题的能力。无论是入门者还是寻求技能进阶的开发者,都将在此收获满满的知识与实践经验。

1. 目标检测

目标检测是指在图像或视频中定位并识别特定类别的物体。

1.1 Haar Cascades

Haar cascades 是一种用于检测图像中特定类型对象的机器学习方法。

cascade = cv2.CascadeClassifier(cascade_path)
rects = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
  • 参数

    • cascade_path:Haar cascade 文件路径。
    • gray:灰度图像。
    • scaleFactor:图像缩放比例。
    • minNeighbors:检测到的矩形框必须至少有多少个邻居才能被视为有效。
    • minSize:检测到的目标最小尺寸。
  • 返回值

    • rects:检测到的目标矩形框列表。
  • 详细解释

    • 原理

      • Haar cascades 通过训练得到的级联分类器来检测图像中的特定对象。
      • 分类器通过一系列弱分类器级联而成,每个弱分类器都负责检测图像中的特定特征。
    • 应用

      • Haar cascades 常用于人脸检测、行人检测等任务。
      • Haar cascades 适用于实时应用,因为它们计算速度快。
    • 注意事项

      • Haar cascades 的准确性取决于训练数据集的质量。
      • Haar cascades 可能无法很好地处理遮挡或角度变化。
    • 实现细节

      • 使用cv2.CascadeClassifier加载训练好的级联分类器。
      • 使用detectMultiScale函数在图像中检测多个尺度的目标。
    • 局限性

      • Haar cascades 可能在复杂背景或目标变形的情况下表现不佳。
      • Haar cascades 可能无法很好地处理不同尺度的目标。
1.2 Deep Learning Based Detection

基于深度学习的目标检测方法,如 YOLO (You Only Look Once) 和 SSD (Single Shot MultiBox Detector)。

net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layerNames = net.getLayerNames()
outputLayers = [layerNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]
outputs = net.forward(outputLayers)# 解析输出
boxes = []
confidences = []
classIDs = []for output in outputs:for detection in output:scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]if confidence > 0.5:box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")x = int(centerX - (width / 2))y = int(centerY - (height / 2))boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)# 应用非极大值抑制
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)# 绘制边界框
if len(idxs) > 0:for i in idxs.flatten():(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
  • 参数

    • configPath:模型配置文件路径。
    • weightsPath:模型权重文件路径。
    • image:输入图像。
  • 返回值

    • image:带有检测边界框的图像。
  • 详细解释

    • 原理

      • 基于深度学习的目标检测方法通过卷积神经网络(CNN)来检测图像中的目标。
      • CNN 通过特征提取和分类两个阶段来检测图像中的目标。
      • YOLO 和 SSD 等方法可以在单次前向传播中同时完成检测和分类。
    • 应用

      • 基于深度学习的目标检测广泛应用于自动驾驶、安防监控等领域。
      • 这些方法能够处理多种尺度的目标,并且具有较高的准确性。
    • 注意事项

      • 深度学习模型的训练需要大量的标注数据。
      • 模型的推理速度取决于硬件平台。
    • 实现细节

      • 使用cv2.dnn.readNetFromDarknetcv2.dnn.readNet加载训练好的模型。
      • 使用cv2.dnn.blobFromImage准备输入图像。
      • 使用cv2.dnn.NMSBoxes进行非极大值抑制,以减少冗余的边界框。
    • 局限性

      • 深度学习模型可能需要大量的计算资源。
      • 模型的准确性依赖于训练数据集的质量和多样性。

在这里插入图片描述

2. 语义分割

语义分割是指为图像中的每个像素分配一个类别标签。

2.1 U-Net

U-Net 是一种用于语义分割的卷积神经网络架构。

# 加载预训练的U-Net模型
model = torch.hub.load('milesial/Pytorch-UNet', 'unet_carvana', pretrained=True)# 准备输入图像
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])input_image = transform(image).unsqueeze(0)# 进行预测
with torch.no_grad():output = model(input_image)# 处理输出
output = torch.sigmoid(output).squeeze().numpy() > 0.5
output = (output * 255).astype(np.uint8)# 显示结果
cv2.imshow('Segmentation Result', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 参数

    • image:输入图像。
  • 返回值

    • output:分割结果图像。
  • 详细解释

    • 原理

      • U-Net 架构通过编码器-解码器结构来实现语义分割。
      • 编码器捕获图像的上下文信息,解码器则恢复详细的像素级信息。
    • 应用

      • U-Net 广泛应用于医学图像分割、遥感图像分析等领域。
      • U-Net 能够处理各种尺度的细节,并且在小数据集上表现良好。
    • 注意事项

      • U-Net 的训练需要高质量的像素级标注数据。
      • 模型的推理速度取决于硬件平台。
    • 实现细节

      • 使用 PyTorch 加载预训练的 U-Net 模型。
      • 使用适当的图像预处理方法准备输入图像。
      • 使用torch.sigmoid函数对输出进行二值化处理。
    • 局限性

      • U-Net 在处理大规模图像时可能需要较大的内存。
      • U-Net 可能在处理复杂背景或目标变形的情况下表现不佳。

在这里插入图片描述

3. 实例分割

实例分割是指不仅为图像中的每个像素分配一个类别标签,还为每个目标实例分配一个唯一的标识符。

3.1 Mask R-CNN

Mask R-CNN 是一种用于实例分割的卷积神经网络架构。

# 加载预训练的Mask R-CNN模型
model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)# 准备输入图像
transform = transforms.Compose([transforms.ToTensor(),
])input_image = transform(image).unsqueeze(0)# 进行预测
with torch.no_grad():predictions = model(input_image)# 处理输出
masks = predictions[0]['masks'].cpu().numpy()
scores = predictions[0]['scores'].cpu().numpy()
labels = predictions[0]['labels'].cpu().numpy()# 绘制结果
for i in range(len(masks)):if scores[i] > 0.5:mask = masks[i][0] > 0.5color = np.random.rand(3) * 255image[mask] = image[mask] * 0.5 + color * 0.5# 显示结果
cv2.imshow('Instance Segmentation Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 参数

    • image:输入图像。
  • 返回值

    • image:带有分割结果的图像。
  • 详细解释

    • 原理

      • Mask R-CNN 是基于 Faster R-CNN 的扩展,增加了用于预测分割掩码的分支。
      • Mask R-CNN 能够为每个检测到的目标生成精确的分割掩码。
    • 应用

      • Mask R-CNN 广泛应用于自动驾驶、医疗影像分析等领域。
      • Mask R-CNN 能够处理各种尺度的目标,并且提供精确的分割结果。
    • 注意事项

      • Mask R-CNN 的训练需要高质量的像素级标注数据。
      • 模型的推理速度取决于硬件平台。
    • 实现细节

      • 使用 PyTorch 加载预训练的 Mask R-CNN 模型。
      • 使用适当的图像预处理方法准备输入图像。
      • 使用阈值处理预测的分割掩码。
    • 局限性

      • Mask R-CNN 在处理大规模图像时可能需要较大的内存。
      • Mask R-CNN 可能在处理复杂背景或目标变形的情况下表现不佳。

在这里插入图片描述

4. 综合示例

接下来,我们将结合上述几种技术,创建一个综合示例。在这个示例中,我们将读取一张图像,使用基于深度学习的目标检测方法进行目标检测,使用 U-Net 进行语义分割,最后使用 Mask R-CNN 进行实例分割。

import cv2
import numpy as np
import torch
from torchvision import models
from PIL import Image
from torchvision.transforms import ToTensor, Normalize, Composedef detect_objects(image_path):# 读取图像image = cv2.imread(image_path)if image is None:print("Error: File not found!")return# 准备输入图像transform = Compose([ToTensor(),Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),])input_image = transform(image).unsqueeze(0)# 加载预训练的YOLOv3模型net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")# 目标检测blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)layerNames = net.getLayerNames()outputLayers = [layerNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]outputs = net.forward(outputLayers)# 解析输出boxes = []confidences = []classIDs = []for output in outputs:for detection in output:scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]if confidence > 0.5:box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")x = int(centerX - (width / 2))y = int(centerY - (height / 2))boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)# 应用非极大值抑制idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)# 绘制边界框if len(idxs) > 0:for i in idxs.flatten():(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# 语义分割# 加载预训练的U-Net模型unet_model = torch.hub.load('milesial/Pytorch-UNet', 'unet_carvana', pretrained=True)# 进行预测with torch.no_grad():output = unet_model(input_image)# 处理输出output = torch.sigmoid(output).squeeze().numpy() > 0.5output = (output * 255).astype(np.uint8)# 显示结果cv2.imshow('Segmentation Result', output)cv2.waitKey(0)cv2.destroyAllWindows()# 实例分割# 加载预训练的Mask R-CNN模型maskrcnn_model = models.detection.maskrcnn_resnet50_fpn(pretrained=True)# 进行预测with torch.no_grad():predictions = maskrcnn_model(input_image)# 处理输出masks = predictions[0]['masks'].cpu().numpy()scores = predictions[0]['scores'].cpu().numpy()labels = predictions[0]['labels'].cpu().numpy()# 绘制结果for i in range(len(masks)):if scores[i] > 0.5:mask = masks[i][0] > 0.5color = np.random.rand(3) * 255image[mask] = image[mask] * 0.5 + color * 0.5# 显示结果cv2.imshow('Instance Segmentation Result', image)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == "__main__":image_path = 'path/to/your/image.jpg'detect_objects(image_path)
5. 小结

在本篇文章中,我们详细介绍了如何使用OpenCV进行目标检测、语义分割以及实例分割。这些技术在计算机视觉领域非常重要,并且是许多高级应用的基础。接下来的文章将涉及更复杂的图像处理技术,如深度学习模型训练、视频分析等。


http://www.mrgr.cn/news/26540.html

相关文章:

  • PHP一键寄送尽在掌中快递寄件小程序
  • Prompt最佳实践|善用分隔符,让你的Prompt更清晰
  • 深兰科技董事长陈海波应出席“香港大学国际科创大赛”
  • 使用开源框架HandyControl
  • C++学习笔记(23)
  • SoapShell 更新 | 新增调用cmd执行系统命令
  • JavaScript和jQuery的区别
  • 基于Netty实现TCP客户端:封装断线重连、连接保持
  • 安全建设当中的冷门知识
  • 开源链动 2+1 模式、AI 智能名片与 S2B2C 商城小程序:重塑私域微商新生态
  • 一文读懂C语言动静态库
  • 软件测试工程师面试整理-编程与自动化
  • 医疗报销|基于springboot的医疗报销系统设计与实现(附项目源码+论文+数据库)
  • 基于YOLO V8的学生上课行为检测系统【python源码+Pyqt5界面+数据集+训练代码】有报告
  • 机器学习第五十六周周报 HA-GNN
  • 什么是 PHP? 为什么用 PHP? 有谁在用 PHP?
  • JavaEE:网络初识
  • memcmp函数的使用
  • RedisTemplate操作ZSet的API
  • “Fast-forward“ in git-pull result