Python:NMS简单实现

import numpy as np
# 每个类别都有很多重叠的候选框。
# 最后,可以通过NMS算法进行筛选,最终得到了分类器认为置信度最高的框作为最后的预测框。


boxes = np.array([[100, 100, 210, 210, 0.72],
                  [250, 250, 420, 420, 0.8],
                  [220, 220, 320, 330, 0.92],
                  [100, 100, 210, 210, 0.72],
                  [230, 240, 325, 330, 0.81],
                  [220, 230, 315, 340, 0.9]])
def NMS(dects,threshhold):
    #dects 二维数组(n_samples, 5) 即 x1,y1,x2,y2,score
    #threshhold IOU阈值
    x1 = dects[:, 0]  # pred bbox top_x #[100. 250. 220. 100. 230. 220.]
    y1 = dects[:, 1]  # pred bbox top_y #[100. 250. 220. 100. 240. 230.] 
    x2 = dects[:, 2]  # pred bbox bottom_x #[210. 420. 320. 210. 325. 315.]
    y2 = dects[:, 3]  # pred bbox bottom_y #[210. 420. 330. 210. 330. 340.]
    scores = dects[:, 4]  # pred bbox cls score #[0.72 0.8  0.92 0.72 0.81 0.9 ]

    areas = (x2 - x1 + 1) * (y2 - y1 + 1) #各个框的面积
    index = scores.argsort()[::-1] #[2 5 4 1 3 0]#分数从大到小排列的index,[::-1]是列表头和尾颠倒一下。
    #argsort()用法,表示对数据进行从小到大进行排序,返回数据的索引值。scores.argsort()--> [0 3 1 4 5 2]
    #即 分数从小到大排列为(scores[0] scores[3] scores[1] scores[4] scores[5] scores[2])及(.72 .72 .8 .81 .9 .91)
    # 对应从大到小的索引  index[  2   5    4     1    3   0  ]记住是取出索引,scores列表没变。

    keep = []#符合条件索引的index,keep用于存放NMS后剩余的方框, # keep保留的是索引值,不是具体的分数。

    # index会剔除遍历过的方框,和合并过的方框。
    while index.size > 0:
        i = index[0]# 取出第一个索引号
        keep.append(i)

        # 计算交集的左上角和右下角
        #np.maximum(X, Y) 用于逐元素比较两个array的大小。就是分数最大的x1值与剩下的按序排列分数对应X1值的挨个对比,较大者。
        #x1[i]为取出分数最大的索引位置对应的x1值,x1[index[1:]]为后续从大到小分数索引位置对应的x1值
        xx1 = np.maximum(x1[i], x1[index[1:]]) #[220. 230. 250. 220. 220.]
        yy1 = np.maximum(y1[i], y1[index[1:]]) #[230. 240. 250. 220. 220.]
        xx2 = np.minimum(x2[i], x2[index[1:]]) #[315. 320. 320. 210. 210.]
        yy2 = np.minimum(y2[i], y2[index[1:]]) #[330. 330. 330. 210. 210.]
        # 如果两个方框相交,X22-X11和Y22-Y11是正的。
        # 如果两个方框不相交,X22-X11和Y22-Y11是负的,不相交的W和H设为0


        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)

        # 计算重叠面积就是上面说的交集面积。
        inter = w * h    #[9696. 8281. 5751.    0.    0.]  #不相交因为W和H都是0 ,不相交面积为0

        # IOU公式(交并比)。
        # 得出来的ious是一个列表,里面拥有当前方框和其他所有方框的IOU结果。
        ious = inter / (areas[i] + areas[index[1:]] - inter) #[0.79664777 0.70984056 0.16573009 0.         0.        ]


        # 合并重叠度最大的方框,也是合并ious中值大于thresh的方框
        # 合并的操作就是把他们去掉,合并这些方框只保留下分数最高的。
        # 经过排序当前操作的方框就是分数最高的,所以剔除其他和当前重叠度最高的方框
        # 这里np.where(ious<=thresh)[0]是一个固定写法。
        inds = np.where(ious <= threshhold)[0]  #[2 3 4] #ious中第2、3、4位置的小于IOU阈值(不包含分数最高的,ious中5个数),也就是index中的第3、4、5位置(包含最高的,index中6个数)

        # 把留下来框在进行NMS操作
        # 这边留下的框是去除当前操作的框,和当前操作的框重叠度大于thresh的框
        # 每一次都会先去除当前操作框,所以索引的列表就会向前移动移位,要还原就+1,向后移动一位
        index = index[inds + 1]  #[1 3 0]  ##index=[2 5 4 1 3 0],对应index第3、4、5位置  变为-->index=[1 3 0]

    return keep

keep = NMS(boxes,0.7)
print(keep)

输出:

[2, 1, 3]
Python实现车牌识别通常涉及到计算机视觉技术,特别是图像处理和机器学习算法。一种常见的方法是结合OpenCV库和深度学习模型,如YOLO(You Only Look Once)、SSD(Single Shot MultiBox Detector)或更先进的Mask R-CNN。 以下是一个简单的步骤概述: 1. **数据预处理**:收集包含车牌的图片,并对它们进行归一化、大小调整等预处理操作。 2. **安装依赖库**:你需要`opencv-python`, `tensorflow` 或 `pytorch`等深度学习框架,以及用于加载预训练模型的`keras`, ` Detectron2`等。 3. **模型选择**:选择适合车牌识别的预训练模型,例如基于TensorFlow的`tf.keras.models.load_model()` 或 PyTorch的`torch.hub.load()`。 4. **模型预测**:将图像输入到模型中,模型会返回一组包含车牌位置和可能性的结果。 5. **结果解析**:从模型输出中挑选出最有可能是车牌的部分,并进行后处理,比如非极大值抑制(NMS),确定最终的车牌区域。 6. **字符分割与识别**:对车牌区域提取字符,这一步可以采用OCR(Optical Character Recognition)技术,使用如`tesseract`这样的开源工具。 下面是一个简化的代码片段示例,注意这只是一个基本框架,实际应用需要更详细的配置和优化: ```python import cv2 from keras.models import load_model # 加载模型 model = load_model('path_to_your_trained_model.h5') # 预测函数 def detect_plate(image_path): img = cv2.imread(image_path) # 对图像进行预处理 processed_img = preprocess_image(img) # 进行预测 predictions = model.predict(processed_img) # 解析和识别车牌 plate_text = recognize_chars(predictions) return plate_text # ... 其他辅助函数 ... # 使用例子 plate_text = detect_plate('image_with_license_plate.jpg') print(f"Detected license plate: {plate_text}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值