基于目标检测评判采集行车片段质量

任务背景:若干个文件夹中存放着采集到的行车图片,这些图片由行车视频按时间逐帧抽出,相当于一个行车场景。每个场景都有六个摄像头和激光雷达采集到的图片,现以对主视角的评判代表整个片段。这些场景中存在停车或是某些路段目标较少的情况,不利于后续处理,打分标准则是目标多,停车少的分数高。满分为100,低于60分的为不合格片段。将输出及格片段的文件夹名称与相应得分,以此挑选质量更好的数据。

实现方案

1.采用相似度对比算法来检测前后帧的相似性以判别停车或缓行片段

2. 相似度对比+目标检测,根据目标数量以及重复帧数选出优秀片段

1.遍历文件夹方法

参考文章【python遍历文件夹中的所有图像(按名称顺序读取)、将生成的新图像存入本地文件夹】

Python文件路径操作汇总,获取文件夹下的所有文件路径

文件夹结构:

路径/采集日期/before_sample/cam_front/jpg格式图片

 所以此处只需获得采集日期即可补全路径

测试代码如下:

import os
import cv2


folder_path = r'F:/video/result'
save_path = r'F:/result'

if __name__ == "__main__":
    img_folder = folder_path
    img_list = [os.path.join(nm) for nm in os.listdir(img_folder) if nm[-3:] in ['jpg', 'png', 'gif']]
    ## print(img_list) 将所有图像遍历并存入一个列表
    ## ['test_14.jpg', 'test_15.jpg', 'test_9.jpg', 'test_17.jpg', 'test_16.jpg']
    for img_name in img_list:
        path = img_folder + '/' + img_name
        print(path)
        image = cv2.imread(path)  ## 逐个读取
        #############################################################
        #对图片进行操作
        
        
        ##############################################################
        cv2.imwrite(save_path + '/ ' + str(img_name) + '.jpg', image)

在本地图片文件夹做测试,将会得到图片文件夹内所有图片的地址,将图片存放在新地址当中,要对图片做的操作直接插入到for循环中即可

2.相似度对比

采用差值哈希算法,计算相似度,生成的值n1含义为差异度,若n1大于10,则可认为是两张不同的图像。评分标准可自行拟定,此处将小于10 的值直接不计入,认定为重复图片,累加n1得到的值再除以所有图像的数量,如果小于10,则认为图像集相似度较高,为不及格图像,反之,输出及格图像的分数。

在本地做测试代码如下:

import os
import cv2
import numpy as np

"""
测试给文件夹打分任务
读取文件夹,遍历其中主视角图片,计算差异度,给出分数
在本地文件夹测试
"""


def dHash(img):
    # 差值哈希算法
    # 缩放8*8
    img = cv2.resize(img, (9, 8))
    # 转换灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    hash_str = ''
    # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        for j in range(8):
            if gray[i, j] > gray[i, j + 1]:
                hash_str = hash_str + '1'
            else:
                hash_str = hash_str + '0'
    return hash_str


def cmpHash(hash1, hash2):
    # Hash值对比
    # 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定,但是比较的时候必须是相同的顺序。
    # 对比两幅图的指纹,计算汉明距离,即两个64位的hash值有多少是不一样的,不同的位数越小,图片越相似
    # 汉明距离:一组二进制数据变成另一组数据所需要的步骤,可以衡量两图的差异,汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样
    n = 0
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 不相等则n计数+1,n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return n


folder_path = r'F:/video/result'
save_path = r'F:/result'

if __name__ == "__main__":
    img_folder = folder_path
    img_list = [os.path.join(nm) for nm in os.listdir(img_folder) if nm[-3:] in ['jpg', 'png', 'gif']]

    # 初始化
    image0 = np.zeros((10, 10, 3), np.uint8)
    image = np.zeros((10, 10, 3), np.uint8)
    count = 0  # 计数器
    score = 0  # 计分器

    for img_name in img_list:
        path = img_folder + '/' + img_name
        print(path)
        image = cv2.imread(path)
        #############################################################
        # 对图片进行操作
        # 计算两图相似度
        hash1 = dHash(image0)
        hash2 = dHash(image)
        n1 = cmpHash(hash1, hash2)
        if n1 <= 10:
            image = image0
            # print('两图片相似,舍去后图')
        else:
            image0 = image
            score = score + n1
            # print('两图片不相似')
        count = count + 1
        ##############################################################
        cv2.imwrite(save_path + '/ ' + str(img_name) + '.jpg', image)
    # 评分标准:如果均分小于10则存在大量重复图像,为不及格
    score = score / count
    if score <= 10:
        print("不及格")
    else:
        print("及格,分数为:",score)

遇到的问题有读取中文路径时报错

cv2.error: OpenCV(4.8.1) D:\a\opencv-python\opencv-
python\opencv\modules\imgproc\src\resize.cpp:4062: error: (-215:Assertion failed) 
!ssize.empty() in function 'cv::resize'

解决参考这篇Python读取路径下所有文件名

#做出如下修改
#原代码
image = cv2.imread(path)
#修改后
image = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)

3.相似度对比+目标检测

增加了计算片段总标注框数量的代码

 检测结果如下:

输出的为采集数据日期,片段名称,片段内目标总数,重复帧数,可以自行修改。

4.片段评分

采集到的数据存在txt文件夹中,评分就是基于最后两列,一个是片段内目标总数,另一个是重复帧数。目标数越多越好,因此为正相关,同理重复帧数为负相关。二者之间又有关联,如果一个片段重复帧数较多,但目标数也不低,这也是有意义的片段,因此目标数为更加重要的判断指标。而且在目标数较少时,差别越大对分数影响更大,这样能够更加精确的筛选出好的片段,此处采用了简单的分段函数的方式处理,代码如下:

# coding=gbk
import os
import numpy as np
import numpy
"""
给文件夹评分:按照目标数量和重复帧数给文件夹评分
输入:txt文件,每行包括日期,片段名,目标数量,重复帧数
思路:两个重要参数分别命名为NUM,RFR,一个正相关一个负相关,而且NUM权重更高
输出:日期,片段名,百分制分数
"""



# 输入目标数与重复帧数,返回分值
def score(n1, n2):
    # 输入目标数与重复帧数,进行处理
    # num占60% rfr占20% 二者比例占20%
    if n1 <= 1500:
        if 700 <= n1:
            fen1 = 40 + 20 * n1 / 1500
        else:  # 较少,需拉开分值
            fen1 = 40 * n1 / 700
    else:
        fen1 = 60
    # rfr占20%
    if n2 > 0:
        if n2 <= 10:
            fen2 = 10 + 10 * (1 - n2 / 60)
        else:
            fen2 = 10 * (1 - n2 / 60)
    else:
        fen2 = 20

    if n2 != 0:
        n3 = n1/n2
        if n3 <= 163:
                fen3 = 10 * n3 / 163 + 5 * (1 - n2 / 60)
        else:
            fen3 = 10 + 5 * (1 - n2 / 60) + 5 * (n3 - 163) / n3
    else:
        fen3 = 5 * fen1/60 + 15

    fen = fen1 + fen2 + fen3
    # print(fen1,fen2,fen3)
    return int(fen)


# 计算均值,最大目标数
def mean(all_path):
    n1 = 0
    n2 = 0
    n3 = 0
    count = 1
    for path in all_path:
        date, ming, NUM, RFR = path.strip().split(" ")
        # print(NUM, RFR)  # 仅仅是为了测试
        # 不为零时算出均值
        if int(NUM) + int(RFR) != 0:
            if n3 < int(NUM):
                n3 = int(NUM)
            n1 += int(NUM)
            n2 += int(RFR)
            count += 1

    n1 = n1 / count
    n2 = n2 / count
    print(n1, n2, n3)
    # 712.8321479374112 4.3584637268847795 1982  163

def key_function(x):
    return int(x[0])

#读取打分后的文件,为其排序
def sort(filename,save):
    s2 = 0
    a = []
    s = open(filename, "r")
    count = 0
    # 逐行读取
    lines = s.readlines()
    for i in lines:
        s1, date, ming, NUM, RFR = i.strip().split(" ")
        a.append([s1, date, ming, NUM, RFR])

    a.sort(key=key_function)
    #打印数组
    """
    获取数组行列
    print(len(X))       #行
    print(len(X[0]))    #列
    """
    h = int(len(a))
    for i in range(0,h):
        print(a[i])


def main():
    f = open(dir_txt, "r")
    w = open(txt_path, "w")
    all_path = f.readlines()
    # mean(all_path)
    for path in all_path:
        date, ming, NUM, RFR = path.strip().split(" ")
        # print(NUM, RFR)  # 仅仅是为了测试
        # 不为零时算出均值
        n1 = int(NUM)
        n2 = int(RFR)
        # 计算分数
        fen = score(n1, n2)
        print(fen,date, ming, NUM, RFR)

dir_txt = r'D:\pythonproject\frequency\cs.txt'  # \\10.128.3.137\算法\原始视频\全地形\videos_20231108'D:\pythonproject\frequency\video'
txt_path = r'D:/pythonproject/frequency/name/name1.txt'  # 生成的图片列表清单txt文件名
filename = r'D:/pythonproject/frequency/name/name2.txt'
save = r'D:/pythonproject/frequency/name/name3.txt'
if __name__ == '__main__':
    """第一步,获取均值与最值,为计分调整权重
    f = open(dir_txt, "r")
    w = open(txt_path, "w")
    all_path = f.readlines()
    mean(all_path)
    """
    """第二步,计算分值
    main()
    """
    """第三步,分值排序"""
    sort(filename, save)

 按照步骤运行后,评分输出的结果如下:

可以看到分数由低到高排列,分数高的片段就是目标多且重复帧少的。

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评判目标检测算法的准确性通常可以从以下几个方面进行考量: 1. 精确度(Precision):精确度是指检测出的目标中真正属于目标类别的比例。可以通过计算检测框与真实标注框的重叠度(如IoU)来判断是否正确检测出目标。 2. 召回率(Recall):召回率是指真实目标中被正确检测出的比例。同样可以通过计算检测框与真实标注框的重叠度来判断。 3. 平均精确度(Average Precision,AP):平均精确度是综合考虑了精确度和召回率的指标。通过在不同的置信度阈值下计算精确度和召回率,并绘制精确度-召回率曲线,可以计算出AP值。 4. mAP(mean Average Precision):mAP是对多个类别的平均精确度进行求平均得到的指标。通常用于评估多类别目标检测算法的整体性能。 5. 漏检率(Miss Rate):漏检率是指未能正确检测出目标的比例,即1-召回率。 6. 误检率(False Positive Rate):误检率是指将非目标错误地检测为目标的比例。 7. F1值:F1值是精确度和召回率的调和平均值,可以综合考虑两者的表现。 8. 平均定位误差(Average Localization Error):平均定位误差是指检测框与真实标注框之间的平均距离,用于评估目标检测算法的定位准确性。 以上是一些常用的评判目标检测算法准确性的指标和方法,可以根据具体需求选择适合的指标进行评估。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值