目录[-]

目录

  • 情景:为什么要做这个?
  • 任务:测试人员需要做什么?
  • 行动:如何设计测试方案?
  • 报告:测试报告分析

————————————————

一、情景:为什么要做这个?

 

公司设计了一个业务,类似于大厦内部停车场,需判断车牌号是否满足抬杆要求,整体规则如下:

  1. 内部车辆:无条件开放
  2. 预约车辆:指定时间段开放
  3. 非内部非预约车辆:不开放

公司采购了几套识别设备, 但是部署之后,用户投诉其识别不准确,导致车辆无法进入,更棘手的是:

  1. 每次尝试新的物联网设备,都要重新和业务对接
  2. 测试人员,只会用一两个车牌实物进行功能验证,无法覆盖更多场景
  3. 公司希望挑选一款性价比最高的设备,既稳定又可靠

————————————————

二、任务:测试人员需要做什么?

 

梳理业务流程

  1. 公司APP,上传内部车辆的车牌号如:辽A 1234Y
  2. 使用物联网硬件摄像头,识别车牌号
  3. 抬杆

但是上述的流程有个致命的问题,只测了一个车牌号,并且还是个蓝牌的车牌号。 

测试的第一步,分析车牌号组成和颜色:

  1. 蓝底白字(蓝牌车):最常见的民用车
    • 格式:辽A · 1234Y(5位字符,数字+字母组合)
  2. 黄底黑字(黄牌):大型/特殊车辆
    • 格式:辽A · 12345(5位)、教练车—辽A·1234(学)
  3. 绿底黑字(绿牌):新能源专用
    • 格式:辽 A・D12345(6 位,比蓝牌多 1 位),D=纯电动,F=非纯电(插混/增程)
  4. 白底黑字/红字(白牌):政法、军队等
    • 警车:辽A · 1234警(最后一位警为红色)
    • 军车:军A · 12345(白底黑字,军队专用)
    • 武警:WJ · 辽 12345(白底黑字,WJ为红色)
    • 应急救援:辽 · X1234 应急(消防/森林消防)
  5. 黑底白字(黑牌):涉外、港澳车辆
    • 领事馆:辽A · 1234 使(红字),驻华使馆、领事馆等
    • 港澳入境:粤Z · 123 港,港澳入内地车辆
  6. 其他专用/临时号牌
    • 临时车牌(纸质)
    • 挂车号牌:黄底黑字,如 辽A · 挂 1234

大厦内部停车场,最常见的,也就是1、2 两种类型,我们以这两个举例。

测试第二步,既然已经分析出我们需要什么数据,那我们如何设计更多的测试数据?

解决方案:

  1. CCPD:github上有项目,可以查看多个真实的车牌号
  2. 手动拍照:测试人员在各式各样的停车场或是路边拍照
  3. 数据模拟:通过代码模拟生成车牌号

本文三种方法都采用了,从代码角度说明一下方法3:

    # 1. 画"辽A"
    draw.text((x, y), first_part, fill=config["text"], font=font)

    # 2. 画点(在"辽A"后面)
    dot_x = x + w1 + dot_offset_x
    dot_y = y + 0
    draw.text((dot_x, dot_y), "·", fill=config["text"], font=font)

    # 3. 画"12345"
    x2 = x + w1 + dot_space
    draw.text((x2, y), second_part, fill=config["text"], font=font)

生成效果如下

测试第三步,车牌号做好了,这次作为DEMO,手动收集一下车牌号,并作为车牌号图片的图片名称,再用下面代码读取,就可以得到如:京A12345

            #       blue_京A12345.jpg   -> 期望文字 = "京A12345"
            expected = filename.split('_', 1)[1].replace('.jpg', '').replace('.png', '')

            # 生成关键词(每个字符作为关键词)
            keywords = list(expected)

————————————————

三、行动:如何设计测试方案?

 

    def run_test(self, image_dir: str, answer_file: str = None, generate_html=True):
        """运行车牌测试"""
        print("🚀 开始车牌识别测试")
        print("=" * 60)

        start_time = time.time()

        # 获取测试用例
        test_cases = get_plate_test_cases(image_dir, answer_file)
        print(f"📸 加载了 {len(test_cases)} 张测试图片")

        results = []
        for case_id, image_path, reference, keywords in test_cases:
            try:
                # 1.调用API识别
                translation = self.translator.translate(image_path)

                # 2.创建评估器实例
                evaluator = SimpleEvaluator()

                # 3.处理识别结果(去掉点再比对)
                clean_translation = translation.replace('·', '')

                # 4.评估
                eval_result = evaluator.evaluate_case(
                    clean_translation,  # 去掉点的结果
                    reference,  # 正确答案
                    keywords,  # 关键词
                    source=image_path  # 图片路径
                )

                # 5.记录原始结果(带点)
                result = {
                    'case_id': case_id,
                    'source': str(image_path),
                    'reference': reference,  # 添加这一行,方便后面使用
                    'translation': translation,  # 原始结果(带点)
                    'clean_translation': clean_translation,  # 去点后的结果
                    'keywords': keywords,
                    'scores': eval_result['scores'],
                    'final_score': eval_result['final_score'],
                    'passed': eval_result['passed'],
                    'llm_explanation': eval_result.get('llm_explanation', '无说明')
                }
                results.append(result)

                # 6.打印结果
                status = "✅" if result['passed'] else "❌"
                print(f"{status} 用例{case_id}: {Path(image_path).name}")
                print(f"   原始车牌: {reference}")
                print(f"   识别结果: {translation} (去点后: {clean_translation})")
                print(f"   关键词命中: {eval_result['scores']['keyword_pos']:.2f}")
                print(f"   BLEU分数: {eval_result['scores']['bleu']:.2f}")
                print(f"   综合得分: {result['final_score']:.2f}")
                print()

            except Exception as e:
                print(f"❌ 用例{case_id} 处理异常:{e}")
                continue

        # 如果没有成功处理的用例,直接返回
        if not results:
            print("❌ 没有成功处理的用例")
            return []

        # 计算汇总
        summary = calculate_summary(results)

        # 7.打印汇总报告
        print("=" * 60)
        print(f"📊 测试汇总:{summary['passed']}/{summary['total']} 通过")
        print(f"   通过率: {summary['pass_rate'] * 100:.1f}%")
        print(f"   综合得分: {summary['avg_final']:.2f}")
        print(f"   平均关键词得分: {summary['avg_scores'].get('keyword', 0):.2f}")
        print(f"   平均BLEU得分: {summary['avg_scores'].get('bleu', 0):.2f}")
        print("=" * 60)

        # 8.生成HTML报告
        if generate_html:
            model_name = self.translator.get_name()
            html_path = HTMLReportGenerator.generate_html_report(results, summary, model_name)
            print(f"📁 HTML报告已保存: {html_path}")

        # 9.保存详细结果到Excel
        self._save_to_excel(results, summary)

        elapsed = time.time() - start_time
        print(f"⏱️ 测试耗时: {elapsed:.2f} 秒")

        return results

————————————————

四、测试报告分析

 

在分析之前,先把测试报告贴出来

1.整体情况

类型 数量 占比
成功识别 7 36.8%
失败识别 12 63.2%
总数 19 100%

2.成功案例分析

成功识别的7个车牌号,都是使用Python代码模拟生成的车牌,它们都是标准字体、无干扰,100%成功率。但是最大的问题在于,这7个是假数据。

3.失败案例分析

类型1:省份识别错误

原始车牌 识别结果 问题
皖A37X93 峯A·37X93 皖 → 峯(完全错误)
苏AA0G87 5A-A0687 苏 → 5A(完全错误)
辽A22NN4 一盏-六众 辽A → 一盏(完全乱码)
鄂A07012 MA07012 鄂 → MA(字母替代汉字)
辽AD75582 1A·D75592 辽 → 1A(数字替代汉字)

结论:省份识别是最大问题,以上5例,全部都是省份识别错误。

类型2:乱码

原始车牌 识别车牌
皖A3E388 225204
皖AAV951 版1 5 百 3 百 3 百 3
皖ABG382 中国工商银行
辽AF46066 255155 R20 H 长安深蓝 LAF46066

这些属于完全识别失败,模型把车牌号当成了文字识别,最大的问题就在于此。

类型3:部分正确但省份错误

原始车牌 识别结果 正确部分
苏K751F8 第K-751F8 K-751F8正确
辽A9MQ03 LIA·9MQ03 9MQ03正确
苏AA0G87 5A-A0687 A0687部分正确

这些结果,如果只看后面字符,识别的不错,但是前面两位只要错了,那就是0分,后面识别再准确也没用。

后续优化推荐

  1. 放弃假数据:删除 Python 生成的假图,只使用真图
  2. 省份样本:收集更多省份样本,连最简单的“辽”、“苏”字都能识别错误,更何况复杂一些的“冀”、“赣”,每个省份收集50张照片
  3. 倾斜角度:寻找倾斜30°、45°等照片
  4. 暗光环境:夜间、地库场景图片
  5. 不同颜色:增加绿牌、黄牌等真实图片(尤其是绿牌,有6个字符)

4.给公司带来的价值

这套车辆识别测试框架,帮助公司避免了一次采购失误。它的优点有:

  1. 有明确的标准,验证采购商的识别效果
    • 用同一套数据,跑通所有设备
    • 哪家设备对绿牌支持好,哪家设备夜间识别高,一目了然
  2. 问题定位更加精准
    • 测试报告直接指出:省份识别率低
  3. 测试资产沉淀
    • 后续的测试可慢慢优化,但这套体系成功的保留下来
  4. 提升测试效率
    • 提升回归测试效率,并且可以很好的验证其稳定性

 

 

 

 

 

to be continued。。。