简 介: 对于全国大学生智能车竞赛竞赛室内视觉AI组用于识别Apriltag,数字,动物以及水果任务,本文提出了基于图片像素的HSV空间的统计值,建立了一个简单的大类分类器。利用这个分类器可以非常精确的在第一时间吧图片分成Apriltag,数字以及彩色图片(动物和水果),然后在利用不同的识别模型进一步识别。
由于这个过程应用了对于图片库的先验知识,一方面可以继续应用原来已经建立好的Apriltag、数字、动物以及水果识别模型,另一方面也可以提高整个识别的效率。
关键词
: 智能车竞赛,室内视觉AI,分类器,机器视觉
#mermaid-svg-aCAt8EdPm0fzyaZf .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .label text{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .node rect,#mermaid-svg-aCAt8EdPm0fzyaZf .node circle,#mermaid-svg-aCAt8EdPm0fzyaZf .node ellipse,#mermaid-svg-aCAt8EdPm0fzyaZf .node polygon,#mermaid-svg-aCAt8EdPm0fzyaZf .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-aCAt8EdPm0fzyaZf .node .label{text-align:center;fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .node.clickable{cursor:pointer}#mermaid-svg-aCAt8EdPm0fzyaZf .arrowheadPath{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-aCAt8EdPm0fzyaZf .flowchart-link{stroke:#333;fill:none}#mermaid-svg-aCAt8EdPm0fzyaZf .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-aCAt8EdPm0fzyaZf .edgeLabel rect{opacity:0.9}#mermaid-svg-aCAt8EdPm0fzyaZf .edgeLabel span{color:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-aCAt8EdPm0fzyaZf .cluster text{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-aCAt8EdPm0fzyaZf .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-aCAt8EdPm0fzyaZf text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-aCAt8EdPm0fzyaZf .actor-line{stroke:grey}#mermaid-svg-aCAt8EdPm0fzyaZf .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-aCAt8EdPm0fzyaZf #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .sequenceNumber{fill:#fff}#mermaid-svg-aCAt8EdPm0fzyaZf #sequencenumber{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf #crosshead path{fill:#333;stroke:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .messageText{fill:#333;stroke:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-aCAt8EdPm0fzyaZf .labelText,#mermaid-svg-aCAt8EdPm0fzyaZf .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-aCAt8EdPm0fzyaZf .loopText,#mermaid-svg-aCAt8EdPm0fzyaZf .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-aCAt8EdPm0fzyaZf .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-aCAt8EdPm0fzyaZf .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-aCAt8EdPm0fzyaZf .noteText,#mermaid-svg-aCAt8EdPm0fzyaZf .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-aCAt8EdPm0fzyaZf .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-aCAt8EdPm0fzyaZf .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-aCAt8EdPm0fzyaZf .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-aCAt8EdPm0fzyaZf .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .section{stroke:none;opacity:0.2}#mermaid-svg-aCAt8EdPm0fzyaZf .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-aCAt8EdPm0fzyaZf .section2{fill:#fff400}#mermaid-svg-aCAt8EdPm0fzyaZf .section1,#mermaid-svg-aCAt8EdPm0fzyaZf .section3{fill:#fff;opacity:0.2}#mermaid-svg-aCAt8EdPm0fzyaZf .sectionTitle0{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .sectionTitle1{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .sectionTitle2{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .sectionTitle3{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-aCAt8EdPm0fzyaZf .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .grid path{stroke-width:0}#mermaid-svg-aCAt8EdPm0fzyaZf .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-aCAt8EdPm0fzyaZf .task{stroke-width:2}#mermaid-svg-aCAt8EdPm0fzyaZf .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .taskText:not([font-size]){font-size:11px}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-aCAt8EdPm0fzyaZf .task.clickable{cursor:pointer}#mermaid-svg-aCAt8EdPm0fzyaZf .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-aCAt8EdPm0fzyaZf .taskText0,#mermaid-svg-aCAt8EdPm0fzyaZf .taskText1,#mermaid-svg-aCAt8EdPm0fzyaZf .taskText2,#mermaid-svg-aCAt8EdPm0fzyaZf .taskText3{fill:#fff}#mermaid-svg-aCAt8EdPm0fzyaZf .task0,#mermaid-svg-aCAt8EdPm0fzyaZf .task1,#mermaid-svg-aCAt8EdPm0fzyaZf .task2,#mermaid-svg-aCAt8EdPm0fzyaZf .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutside0,#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutside2{fill:#000}#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutside1,#mermaid-svg-aCAt8EdPm0fzyaZf .taskTextOutside3{fill:#000}#mermaid-svg-aCAt8EdPm0fzyaZf .active0,#mermaid-svg-aCAt8EdPm0fzyaZf .active1,#mermaid-svg-aCAt8EdPm0fzyaZf .active2,#mermaid-svg-aCAt8EdPm0fzyaZf .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-aCAt8EdPm0fzyaZf .activeText0,#mermaid-svg-aCAt8EdPm0fzyaZf .activeText1,#mermaid-svg-aCAt8EdPm0fzyaZf .activeText2,#mermaid-svg-aCAt8EdPm0fzyaZf .activeText3{fill:#000 !important}#mermaid-svg-aCAt8EdPm0fzyaZf .done0,#mermaid-svg-aCAt8EdPm0fzyaZf .done1,#mermaid-svg-aCAt8EdPm0fzyaZf .done2,#mermaid-svg-aCAt8EdPm0fzyaZf .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-aCAt8EdPm0fzyaZf .doneText0,#mermaid-svg-aCAt8EdPm0fzyaZf .doneText1,#mermaid-svg-aCAt8EdPm0fzyaZf .doneText2,#mermaid-svg-aCAt8EdPm0fzyaZf .doneText3{fill:#000 !important}#mermaid-svg-aCAt8EdPm0fzyaZf .crit0,#mermaid-svg-aCAt8EdPm0fzyaZf .crit1,#mermaid-svg-aCAt8EdPm0fzyaZf .crit2,#mermaid-svg-aCAt8EdPm0fzyaZf .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-aCAt8EdPm0fzyaZf .activeCrit0,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCrit1,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCrit2,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-aCAt8EdPm0fzyaZf .doneCrit0,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCrit1,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCrit2,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-aCAt8EdPm0fzyaZf .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-aCAt8EdPm0fzyaZf .milestoneText{font-style:italic}#mermaid-svg-aCAt8EdPm0fzyaZf .doneCritText0,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCritText1,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCritText2,#mermaid-svg-aCAt8EdPm0fzyaZf .doneCritText3{fill:#000 !important}#mermaid-svg-aCAt8EdPm0fzyaZf .activeCritText0,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCritText1,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCritText2,#mermaid-svg-aCAt8EdPm0fzyaZf .activeCritText3{fill:#000 !important}#mermaid-svg-aCAt8EdPm0fzyaZf .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-aCAt8EdPm0fzyaZf g.classGroup text .title{font-weight:bolder}#mermaid-svg-aCAt8EdPm0fzyaZf g.clickable{cursor:pointer}#mermaid-svg-aCAt8EdPm0fzyaZf g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-aCAt8EdPm0fzyaZf g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-aCAt8EdPm0fzyaZf .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-aCAt8EdPm0fzyaZf .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-aCAt8EdPm0fzyaZf .dashed-line{stroke-dasharray:3}#mermaid-svg-aCAt8EdPm0fzyaZf #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf .commit-id,#mermaid-svg-aCAt8EdPm0fzyaZf .commit-msg,#mermaid-svg-aCAt8EdPm0fzyaZf .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-aCAt8EdPm0fzyaZf g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-aCAt8EdPm0fzyaZf g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-aCAt8EdPm0fzyaZf g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-aCAt8EdPm0fzyaZf .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-aCAt8EdPm0fzyaZf .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-aCAt8EdPm0fzyaZf .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-aCAt8EdPm0fzyaZf .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-aCAt8EdPm0fzyaZf .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-aCAt8EdPm0fzyaZf .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-aCAt8EdPm0fzyaZf .edgeLabel text{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-aCAt8EdPm0fzyaZf .node circle.state-start{fill:black;stroke:black}#mermaid-svg-aCAt8EdPm0fzyaZf .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-aCAt8EdPm0fzyaZf #statediagram-barbEnd{fill:#9370db}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-state .divider{stroke:#9370db}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-aCAt8EdPm0fzyaZf .note-edge{stroke-dasharray:5}#mermaid-svg-aCAt8EdPm0fzyaZf .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-aCAt8EdPm0fzyaZf .error-icon{fill:#522}#mermaid-svg-aCAt8EdPm0fzyaZf .error-text{fill:#522;stroke:#522}#mermaid-svg-aCAt8EdPm0fzyaZf .edge-thickness-normal{stroke-width:2px}#mermaid-svg-aCAt8EdPm0fzyaZf .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-aCAt8EdPm0fzyaZf .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-aCAt8EdPm0fzyaZf .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-aCAt8EdPm0fzyaZf .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-aCAt8EdPm0fzyaZf .marker{fill:#333}#mermaid-svg-aCAt8EdPm0fzyaZf .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-aCAt8EdPm0fzyaZf {color: rgba(0, 0, 0, 0.75);font: ;}
简单分类器
文章目录
应用背景
原始数据
图片颜色
图片灰度
利用S,V区分
设置分类器
区分Apriltag
与数字
算法总结
附件程序
微信留言
§01 简单分类器
一、应用背景
在第十六届全国大学生智能车竞赛全国总决赛中,为了适应 线上总决赛 的要求, 室内视觉AI组的比赛采用了 赛道积分与识别积分分离 的比赛形式,这样可以保证比赛过程中更加的紧凑高效。
▲ 图1.1 智能车在识别图片任务
为了避免人工对于识别过程的干预,整个识别过程是由计算机随机给出Apriltag,数字,动物以及水果图片,由参赛车模自动根据拍摄的照片给出识别结果。
由于之前的比赛,Apriltag,数字,动物以及水果分别位于赛道的不同位置,Apriltag位于赛道上,数字位于三岔路口,动物和水果则位于赛道两旁。所以智能车模可以预先根据车模所处在赛道的不同位置,指导摄像头所拍摄的图片中的种类分别属于哪一大类。然后在分别调取不同的识别模型和算法来进一步处理图片。
在新的比赛模式下,所有的图片都是随机出现,因此,需要预先判断图片属于哪一大类,然后才能够调取原来的识别模型。那么改如何设计一个简单的分类算法,将获取的图片先划分到三大类(Apriltag,数字以及动物与水果)呢?
本文下面就讨论一个利用图片的像素颜色来进行分类的简单算法。
二、原始数据
1、数据库来源
在 第十六届智能汽车竞赛AI视觉组分赛区数据集发布 给出了应用在智能车竞赛中的四类图片的数据集合以及下载的方式。
-
智能车竞赛数据集合:
-
AprilTag:25h9 系列 0 ~ 9
数字:0 ~ 9
动物图片:五个子类:牛(93)、狗(101)、猪(88)、猫(99)、马(95)
水果图片: 橙子(86)、榴莲(75)、苹果(88)、葡萄(89)、香蕉(93)
数据库总体数量 927 张图片。
▲ 图1.2.1 Apriltag图片
▲ 图1.2.2 数字图片
▲ 图1.2.3 水果-桔子
▲ 图1.2.4 动物-牛图片
2、数据库存储目录
AprilTtag码Tag25h9_0.pngTag25h9_1.pngTag25h9_2.pngTag25h9_3.pngTag25h9_4.pngTag25h9_5.pngTag25h9_6.pngTag25h9_7.pngTag25h9_8.pngTag25h9_9.png
动物├─牛├─狗├─猪├─猫└─马
数字0.png1.png2.png3.png4.png5.png6.png7.png8.png9.png
水果├─榴莲├─橙子├─苹果├─葡萄└─香蕉
from headm import *alldir = r'D:\Temp\ALL'
subdirstr = ['ApriTtag码', '数字', '动物', '水果']animalstr = '狗,马,猫,牛,猪'
fruitstr = '橙子,榴莲,苹果,葡萄,香蕉'
animalsub = animalstr.split(',')
fruitsub = fruitstr.split(',')def subfile(sub):dirname = os.path.join(alldir, sub)files = [os.path.join(alldir, sub, f) for f in os.listdir(dirname) if f[-3:]=='png']return filesallfile = []
allfile.extend(subfile(subdirstr[0]))
allfile.extend(subfile(subdirstr[1]))for s in animalsub:substr = '动物\\%s'%sallfile.extend(subfile(substr))for s in fruitsub:substr = '水果\\%s'%sallfile.extend(subfile(substr))printf(len(allfile))
三、图片颜色
1、基本识别方案
为了建立一个非常简单的Apriltag,数字、动物和水果的分类器,需要:
- 结合已知先验知识,借助于简化的模式识别的方法建立分类器;
- 抛开对于图片内的形态识别特征,转换使用基于像素的统计规律,这样可以大大提高检测速度;
因此,计划使用图片的颜色空间的统计特性来区分三类。主要利用原则:
- 由于Apriltag,数字都是黑白的图片;利用这一点可以用于区分水果与动物;
- Apriltag与数字在黑白的占空比方面不同,可以利用图片的灰度分布统计来,或者平均灰度来区分这两类。
2、图片的RGB转换HSV
根据黑白图片与参赛图片之间关系,可以把Apriltag,数字分布与动物水果进行区分。为了有效区分彩色图片与黑白图片,则需要将图片从 RGB转换到HSV空间。 在HSV(Hue, Saturation, Value)中, S 分量表示色彩的保护度,也就是颜色距离白色与纯色之间的差异度量。通常取0% ~ 100%, S值越大颜色就越饱和。
▲ 图1.3.2.1 图片的RGB
▲ 图1.3.2.2 Apriltag RGB图片
在 Python Math: Convert RGB color to HSV color 给出了RGB转换到HSV计算公式。
那么,H,S,VH,S,VH,S,V的计算公式如下:
V=CmaxV = C_{\max }V=Cmax
下面给出了数字图片以及动物与水果对应的S分量的分布。可以看到黑白图片的S分量大都分布在0附近,而普通的彩色图片对应的S分量分布具有很多很大的数值。
▲ 图1.3.4 黑白图片 4 对应的S的分布
▲ 图1.3.3 不同的彩色图片对应的S分量的分布
3、利用平均色饱和度区分彩色与黑白图片
计算图片的色保护平均值:
Saverage=∑i,jS(i,j)NS_{average} = {{\sum\limits_{i,j}^{} {S\left( {i,j} \right)} } \over N}Saverage=Ni,j∑S(i,j)
-
其中:
-
S(i,j)
: 图片每个像素的色饱和值
N
:图片的像素个数
对于907张动物与水果的平均色饱和度值得分布如下图所示:
▲ 图1.3.3.1 动物与水果平均S值
如果取一个阈值SminS_{\min }Smin作为区别黑白 与彩色图片的阈值,SminS_{\min }Smin越大,对于黑白图片的误判成彩色图片概率就越低,但对于彩色图片误判成黑白图片的概率就越大。
下图给出了使用S平均值判断彩色图片时,随着阈值的增加,正确率的变化:
▲ 图1.3.3.2 阈值与彩色图片判断正确率
可以看到当阈值取10的时候,判断黑白照片与彩色照片的正确率大约为95%,当阈值取20的时候,正确率已经下降到90%以下了。
由于使用摄像头摄取图片的时候,存在一定的图片白平衡失真,上面色饱和阈值不能够设置太高,否则就会使得黑白图片被误判成彩色图片。
下面是色饱和度小于10的动物与水果图片,共有39张,可以看到它们的确都接近于灰色图片,或者图片中动物的比例较小,大部分为背景白色。
▲ 图1.3.3.4 色饱和度小于10的图片
4、图片灰度
如果仅仅通过色保护度来区分黑白图片(Apriltag, 数字)与彩色照片(动物和水果)会存在比较大的误差。下面还可以通过图片的灰度分布差异来进一步区分黑白图与彩色图片。
下面是对于所有平均色饱和度小于20的图片绘制出他们亮度分布(V值),可以看到他们具有一个很大的特点,就是除了亮度值非常大(对应背景白色)之外,还存着一定数量的灰度值分布。
▲ 图1.3.4.1 色保护度小于20的图片亮度值分布
而对比黑色图片(Apriltag,数字)图片的亮度分布,可以看到它的分布主要集中在最高值与最低值,中间分布很少。因此,可以利用这个差异进一步区分黑白图片与彩色图片。
▲ 图1.3.4.2 黑白图的亮度值分布
对于平均色饱和小于20(总共有41张图片),计算它的次级亮度平均值:
Vaverage=1N1∑V(i,j)<230V(i,j)V_{average} = {1 \over {N_1 }}\sum\limits_{V\left( {i,j} \right) < 230}^{} {V\left( {i,j} \right)}Vaverage=N11V(i,j)<230∑V(i,j)
在上面公式中的230是相对于亮度最高位255时所设定的阈值,把所有不是最高亮度,也就是背景像素之外的像素亮度(V值)相加,再除以这些像素个数N1N_1N1,所得到的次级亮度平均值的分布如下图所示:
▲ 图1.3.4.3 灰度平均值
下面是对20张黑白图(Apriltag,数字)利用计算的次级亮度平均值的分布。可以看到它们的值都小于20。
▲ 图1.3.4.4 所有黑白(Apriltag, 数字)图片的次级亮度平均值分布
如果取35作为阈值,使用次级亮度平均值来区分黑白图与彩色图片,可以达到100%的正确率。
五、利用S,V区分设置分类器
为了提高分类器的适应性,可以考虑联合图片的S,V来区分黑白图与彩色图。计算图片的平均色饱和度值 SaveS_{ave}Save以及次级平均亮度值 VaveV_{ave}Vave。选择两个合适的阈值:STS_TST以及VTV_TVT,对于同时满足:Save<ST,Vave<VTS_{ave} < S_T ,\,\,V_{ave} < V_TSave<ST,Vave<VT
判断为黑白图(AprilTag,数字),否则就是彩色图(动物和水果)。
直接对于数据集合的图片来说,ST=20,VT=60S_T = 20,\,\,\,V_T = 60ST=20,VT=60,就可以获得100%的正确率。
选择ST,VTS_T ,V_TST,VT,以及用于计算次级亮度值的阈值需要根据实际摄像头图片数据进行调整。
六、区分Apriltag与数字
根据图片的平均色保护度以及次级平均亮度可以将黑白图片与动物水果图片区分开来。那么如何区分Apriltag与数字呢?
如果对于前面给出的APriltag 和数字亮度值的分布来看,可以看到Apriltag的黑色背景值比白色背景多,而数字则恰好反过来,它的白色背景像素多余黑色背景像素。利用这一点差异,可以对于黑白图片中的黑色像素(也就是V值低于图片平均灰度的像素)的个数进行统计,如果黑色像素的个数高于所有像素个数的50%,则是Apriltag图片,反之则是数字图片。
※ 算法总结 ※
对于全国大学生智能车竞赛竞赛室内视觉AI组用于识别Apriltag,数字,动物以及水果任务,本文提出了基于图片像素的HSV空间的统计值,建立了一个简单的大类分类器。利用这个分类器可以非常精确的在第一时间吧图片分成Apriltag,数字以及彩色图片(动物和水果),然后在利用不同的识别模型进一步识别。
由于这个过程应用了对于图片库的先验知识,一方面可以继续应用原来已经建立好的Apriltag、数字、动物以及水果识别模型,另一方面也可以提高整个识别的效率。
对于本文前面提到的算法中的阈值,需要根据实际采集到的图片进行进一步优化,使得最终的识别效率达到最高。
▲ 图4.1 我的智能车看到图片识别就像这只鸽子一样
※ 附件程序
from headm import *
from PIL import Image
import cv2alldir = r'D:\Temp\ALL'
subdirstr = ['ApriTtag码', '数字', '动物', '水果']animalstr = '狗,马,猫,牛,猪'
fruitstr = '橙子,榴莲,苹果,葡萄,香蕉'
animalsub = animalstr.split(',')
fruitsub = fruitstr.split(',')def subfile(sub):dirname = os.path.join(alldir, sub)files = [os.path.join(alldir, sub, f) for f in os.listdir(dirname) if f[-3:]=='png']return filesallfile = []
allfile.extend(subfile(subdirstr[0]))
allfile.extend(subfile(subdirstr[1]))markdim = []
markdim.extend([0]*10)
markdim.extend([1]*10)for s in animalsub:substr = '动物\\%s'%sssf = subfile(substr)allfile.extend(ssf)printff(s, len(ssf))markdim.extend([2]*(len(allfile)-len(markdim)))for s in fruitsub:substr = '水果\\%s'%sssf = subfile(substr)allfile.extend(ssf)printff(s, len(ssf))markdim.extend([3]*(len(allfile)-len(markdim)))
pltgif = PlotGIF()grayfile = tspload('grayfile', 'grayfile')def img2colorhist(imagefile):printf(imagefile)img = Image.open(imagefile)imghsv = img.convert('HSV')imgdata = array(Image.Image.getdata(imghsv))H = imgdata[:,0]S = imgdata[:,1]V = imgdata[:,2]plt.clf()plt.subplot(1,2,1)plt.hist(V)plt.axis([-10, 255, 0, 100000])plt.subplot(1,2,2)plt.imshow(img)plt.draw()plt.pause(.1)Vave = sum(V[V < 230]) / len(V[V<230])Save = sum(S) / shape(imgdata)[0]if Save < 20 and Vave < 60:pltgif.append(plt)return SaveVave = []printf(grayfile)
for f in grayfile:Vave.append(img2colorhist(f))'''
printf(len(Vave))
plt.clf()
plt.subplot(1,1,1)
plt.hist(Vave, 20)
plt.xlabel("平均灰度值")
plt.ylabel("次数")
plt.grid(True)
plt.tight_layout()
plt.show()''''''
SHist = []for i in range(len(allfile) - 20):SHist.append(img2colorhist(allfile[20 + i]))if i > 100: breaktspsave('grayfile', grayfile=grayfile)printf(len(grayfile))'''
''''''pltgif.save()
■ 相关文献链接:
- 第十六届全国大学生智能车竞赛全国总决赛线上比赛规范
- 第十六届全国大学生智能汽车竞赛总决赛 AI视觉组线上赛细则
- 第十六届智能汽车竞赛AI视觉组分赛区数据集发布
- RGB转换到HSV空间。
- Python Math: Convert RGB color to HSV color
- 转载本博文的公众号-TSINGHUAZHUOQING
● 相关图表链接:
- 图1.1 智能车在识别图片任务
- 图1.2.1 Apriltag图片
- 图1.2.2 数字图片
- 图1.2.3 水果-桔子
- 图1.2.4 动物-牛图片
- 图1.3.2.1 图片的RGB
- 图1.3.2.2 Apriltag RGB图片
- 图1.3.4 黑白图片 4 对应的S的分布
- 图1.3.3 不同的彩色图片对应的S分量的分布
- 图1.3.3.1 动物与水果平均S值
- 图1.3.3.2 阈值与彩色图片判断正确率
- 图1.3.3.4 色饱和度小于10的图片
- 图1.3.4.1 色保护度小于20的图片亮度值分布
- 图1.3.4.2 黑白图的亮度值分布
- 图1.3.4.3 灰度平均值
- 图1.3.4.4 所有黑白(Apriltag, 数字)图片的次级亮度平均值分布
■ 微信留言
雪地孤星
:卓大大,今天看了哈工程的视频发现一个问题,他们识别的速度很快这个不可否认能力确实很强,但是好多次我看到他们上一次的动作还未做完,下一个图片已经开始识别了,比如那个数字和水果,车还在前进后退的时候已经打激光了,是否应该一个动作完成之后在进行下一个识别?
作者: 这之间可能无法清晰界定。
雪地孤星
:好的卓大大我再问您个问题,就是那个视觉组是要
1寻迹跑完一次就要播报么?
2那个识别完一次播报时间是来不及的这个怎么办
作者: 1. 如果时间太快,就不需要播报了; 2。只要需要播报正确与错误;
特仑苏的纯。
:卓大大,AI识别既然是完全无序,每一轮之后的那张空白图片是不是没有必要存在了,刚开始启动软件存在就好呀,如果直接点下一张图片切换效果不是更好吗,中间存在一张空白图片太影响鼠标点击了
作者: 很好的建议。
特仑苏的纯。
:卓大大,这个建议进行的怎么样了呢
作者: 瘸子逛街:卓老师早上好,的确,我们也收到了这样的建议,但也有不同的建议,另外一种建议是保留中间这个空白,但去掉一轮结束后需要重新点开始的功能,用这个空白来表示新的一轮要开始了
ʎǝllɐʌ_oʇ_puᴉʍ
:卓大,“识别到动物,车模的摄像头左右摇摆两次,摇摆的角度大于90°”,是不是一个摄像头转就可以(openMV,
ʎǝllɐʌ_oʇ_puᴉʍ
:2.小车回到原位时,人还没来得及切换图片,又识别了同一张做了相同动作,算不算失败?
作者: 算失败。
ʎǝllɐʌ_oʇ_puᴉʍ
:3.跟着车模拍摄是镜头跟着还是人也要保持一定距离。我们铺好赛道后已经没地方走了,只能踩在赛道内。假如人跟着,那又看路又看手机,跑个七八圈人都晕过去了,还容易绊倒压到坡道车模,建议只用镜头跟踪。
ʎǝllɐʌ_oʇ_puᴉʍ
:因为人没来得及切换导致识别了同一张图,这是人的失误而不是车的失误,算失败我认为不合理。但不算失败又有可能确实是识别错误,毕竟人也不知道mv到底识别了哪一张。所以最终规定:软件切换图片不可能连续两张相同图片。这样就不用担心人反应不过来,识别正误也可以准确记分。
作者: 这个建议挺好的。
WEI
:卓大,按文件上,库的形状没有限制,那尺寸有吗,比如库仅仅可容纳车模的大小行吗
作者: 可以的。
Populusalba
:卓老师,越野组别之前的规则里没有说可以用曲线代替折线,新出的规则我们还没来得及改就交了,请问我们可不可以在原来所以元素的位置不变的情况下把折线改成曲线?
Populusalba
:所有元素
作者: 别改了。如果改了对于某些连线还需要重新核算距离等。还是好了用心将你们的车模调试的越快越稳为好。
....
:单车总成绩35-27=8秒,能保国二么?
作者: 这个成绩令人惊奇。可否发送过来视频让大家见识见识呢?
绅士仪态
:除了两个三岔路口之间应该是90厘米距离和十字的距离限制之外,元素和元素之间就没有距离限制了吧
作者: 没有了。
杞萱
:卓老师 请问山东赛区成绩啥时候下啊
作者: 已经公布了呀。
杞萱
:啊不好意思老师 我再去找一下
作者: https://zhuoqing.blog.csdn.net/article/details/119410129
半夜汽笛
:卓大大,越野组不弃赛的队伍获得国二的条件是什么?是三分钟所得分数超过固定分数就可以获奖,还是跟其他所有队伍放在一起依次排名确定奖项?
作者: 应该是超过一个最低固定分数即可。
Y
:卓大,请问室内组(比如基础四轮,双车,全向)可以放干簧管霍尔元件这种吗?既然没有车库,是不是干簧管这种也不允许使用
作者: 对的。 应该是这样的传感器在比赛中也起作用了。
37.5
:卓大大,AI视觉组在识别过程中多久没有识别到即可认定为不做动作,这个规则里没有明确给出
作者: 关于这个问题,我们现在考虑是每个队伍总共在2分钟内至少作出一定识别动作(无论是识别错误,还是识别正确),如果低于一定数值,说明车模的目标识别功能未能完赛。 具体最低次数,我们将会根据比赛结果统计分布来确定。
YTD
:卓大,今年还有纪念衫嘛
作者: 下周会有相关消息。
SorryMaker
:卓大,视觉组有几个问题
1.操作软件切换图片和赛道发车的人可以是两个队员吗?
2.激光打靶时我可以在激光亮起时,切换下一张图片吗。比如水果的下一张是数字,车子识别出水果,发出激光,立刻切成数字,但是不执行数字的任务,等激光照射1秒后,才执行数字任务,这样可以吗
3.激光必须照射在键盘上吗,我们使用的是surface,没有键盘,可以照射在surface面前的一张白纸上吗?或者照射到能明显看出激光的地方?
作者: 1. 可以是两个队员; 2. 可以的; 3. 可以的。
SorryMaker
:4.动物任务,车子舵机左打45°一次,右打舵机45°一次,加起来>90°,这样符合要求吗
作者: 符合。
SorryMaker
:怕到时候违规了,再向您确认一下。
我车子视觉效果上就是,轮子左摆一下,右摆一下,总共动两下。这样符合规则吧,卓大
作者: 可以的。
钉子
:卓大大,信标灯控制器的随机亮灯顺序随机性比较大,如果短距离的相邻灯亮的次数多时,在规定时间内,要比远距离相邻亮灯的次数多好几个,感觉这样的话跟运气因素影响还挺大的。
作者: 我们测试了信标灯的随机性: https://zhuoqing.blog.csdn.net/article/details/119514274
一个简单的Apriltag,数字,动物水果分类器相关推荐
- python游戏最简单代码-如何利用Python开发一个简单的猜数字游戏
前言 本文介绍如何使用Python制作一个简单的猜数字游戏. 游戏规则 玩家将猜测一个数字.如果猜测是正确的,玩家赢.如果不正确,程序会提示玩家所猜的数字与实际数字相比是"大(high)&q ...
- python编写一个简单的猜数字小游戏
该脚本包含了python基础的部分内容,python初学者既可以学习借鉴,也可以向朋友去装13. 本次编写的内容需要导入一个第三方模块random,可获得规定范围的随机数. 首先打开pycharm中下 ...
- python猜数字游戏编程入门_如何利用Python开发一个简单的猜数字游戏
导读热词 前言 本文介绍如何使用Python制作一个简单的猜数字游戏. 游戏规则 玩家将猜测一个数字.如果猜测是正确的,玩家赢.如果不正确,程序会提示玩家所猜的数字与实际数字相比是"大(hi ...
- 一个简单的猜数字游戏(附带关机惩罚)
作为一个初学C语言的小白,一个简易的C语言小游戏无非是提高了我对这门计算机语言的兴趣.接下来我将从提高自己的角度讲解一下这个简单的猜数字游戏,希望大家多多包涵. ------------------- ...
- 利用JavaScript实现一个简单的猜数字游戏
问题描述:程序随机生成一个1到10之间的数字,然后让用户随机输入一个数字,如果用户输入的 数字过大,则提示用户猜的数字过大,请往小的猜,如果用户输入的数字过小,则提示用户输入的数字过小,请往大的猜:当 ...
- 利用python做一个小游戏_如何使用python做一个简单的猜数字的小游戏
1 首先小编先打开IDLE,如下图: 2 然后这里点击菜单栏的'File',然后点击菜单"New File",如下图: 3 然后我们就在idle中新建了一个python文件,如下图 ...
- 一个简单的猜数字APP(一)
使用约束布局ConstraintLayout,郭霖大神的ConstraintLayout解析 得到随机数字 [Java学习]几种常用类 一些简单控件的使用[安卓初步]常用控件 进入界面 如上图,关键是 ...
- 用while实现一个简单的猜数字小游戏
中午闲着没事干,就写个小游戏吧,这个小游戏游戏规则就很简单,就是系统随机产出一个整数,然后用户输一个数字,如果输入的数字大于系统的整数就弹出输大了,如果小于,就弹出输小了,规则很简单就这样.下面见代码 ...
- c语言猜数字游戏新建,C语言编程 如何构建一个简单的猜数字小游戏
#include//生成随机函数起点时用到time.h int main() { int number1 = 0, choice = 0, number2 = 0; printf("$$$$ ...
最新文章
- IE8下 Select文字垂直居中的办法
- python 自然语言处理 (六) 采用deepQA搭建自动聊天机器人
- python正则表达式findall_正则表达式 re.findall 用法
- android 原生开发 3d地图 下载_arcgis api 3.x for js 入门开发系列二不同地图服务展示(附源码下载)...
- selenium--特殊元素定位
- inline-block,inline,block,table-cell,float
- Fiddler抓包原理讲解以及实例操作
- 使用TortoiseGit处理冲突亲测
- CEO “排队”卸任、企业“扎堆”造车,2021 科技圈十大事件你知道几个?
- 关于alfa无线设备
- WordPress网站建设中实用的简繁切换工具
- 金莹江苏省计算机学会教授,第二届江苏省青年计算机精英论坛”在江南大学举行...
- matlab连通区边界_matlab函数_连通区域
- 成功的自动化测试:测试员的故事
- Entry name *.xml collided终极解决方案
- 基于springboot_+java古诗词分享数字化平台
- Cocos Creator 3D 粒子系统初战,不要钱的酷炫火焰拿走不谢!
- android抗锯齿的几个方法
- linux日志切割命令,Linux 服务器log日志切割三种方法【附命令行】
- 【赛题回顾】2019 年海淀区中小学生信息学奥林匹克竞赛小学组真题
热门文章
- Yenista光学发布新型无源器件测试平台CTP10
- 火电电厂相关业务知识
- 2208: [Jsoi2010]连通数
- python 文件的操作
- 游戏开发--开源软件7--xith3D(java 3D引擎)
- python__高级 : 类当作装饰器
- 关于Tomcat上请求的编解码问题
- 爱立信为T-Mobile荷兰全新的OTT TV业务提供强大支持
- [译] Couchbase 使用 cbbackup 备份
- eclipse安装Log4E插件以及简单使用