简介本资源是面向计算机视觉初学者与目标检测实践者的高质量商品识别数据集专为智能售货柜场景设计可直接用于YOLO、Faster R-CNN等主流模型的训练与验证。压缩包内含2950张真实拍摄的商品图像及配套VOC格式XML标注文件共2000个覆盖完整标注结构另有类别定义txt文件开箱即用无需清洗或格式转换。资源总大小993.01MB以ZIP形式封装文件组织规范XML标签包含object边界框、类别名及图像尺寸信息适配Pascal VOC标准流程。目前已有289人学习下载对开展零售场景下的小目标检测、多品类识别、数据增强实验及模型泛化能力评估具有直接支撑价值特别适合课程设计、毕业项目与工业级轻量应用开发。1. 智能售货柜商品检测数据集2950张VOC标注图直接喂进YOLOv5/v8也能跑通但别急着train——先验血这三类标签错位玄学你手头正调一个便利店无人结算系统摄像头拍到的饮料瓶总被框成“背景”薯片袋识别成“纸盒”甚至同一罐可乐在不同角度下被标成“红牛”和“芬达”——不是模型不行是你的训练数据在偷偷给你埋雷。这个智能售货柜商品数据集VOC格式就是专治这种“标得像、训得歪”的顽疾它不玩概念2950张真实售货柜拍摄图像2950个严格按PASCAL VOC规范生成的XML标签文件连类别txt都给你备好了classes.txt里就一行bottle不对是13类常见快消品从“农夫山泉矿泉水”到“奥利奥夹心饼干”全按货架实际品类命名。它不是合成数据也不是手机随手拍的模糊图而是工业级红外补光固定焦距镜头采集的柜内俯拍图分辨率统一为1920×1080目标尺寸集中在60×60到320×240像素区间——这恰恰卡在小目标检测的生死线上。新手拿它练YOLOv8微调熟手用它做域自适应迁移算法工程师拿它当baseline benchmark都不用改路径、不写转换脚本、不重标一帧图。但警告一句VOC格式看着老实XML里藏着三处“标得对、读得错”的黑匣子我第一次训完mAP掉点时debug三天才发现是xmin值被Excel自动转成科学计数法存进了XML……所以这篇笔记不教你怎么下载只告诉你怎么把这2950张图和2950个XML真正变成模型能懂的语言。2. VOC格式解析与数据结构验证从XML标签到numpy数组的四层解包2.1 VOC XML结构拆解为什么object里嵌套bndbox比YOLO的txt更难出错VOC格式的核心是XML文件每个.xml对应一张图像结构严格遵循PASCAL VOC DTD规范。以ori_XYG2020123012221874431333-1_0.xml为例关键字段如下annotation foldertrain/folder filenameori_XYG2020123012221874431333-1_0.jpg/filename path/data/train/ori_XYG2020123012221874431333-1_0.jpg/path source databaseUnknown/database /source size width1920/width height1080/height depth3/depth /size segmented0/segmented object namecoke_can/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin842/xmin ymin417/ymin xmax926/xmax ymax532/ymax /bndbox /object object namewater_bottle/name bndbox xmin1120/xmin ymin389/ymin xmax1205/xmax ymax510/ymax /bndbox /object /annotation注意name字段值必须与classes.txt中第i行完全一致区分大小写、下划线/空格且xmin等坐标值必须为整数不能是浮点或科学计数法。这是后续所有工具链labelImg、Darknet、PyTorch DataLoader解析的基础。我曾见有人用pandas读XML后astype(int)强制转换结果1.2e3变成1——坐标全崩。2.2 classes.txt文件校验13类商品名与XML中name的逐字符匹配逻辑该数据集附带的classes.txt并非简单列表而是定义了类别ID映射顺序。打开文件可见13行每行一个商品名无空行、无BOM头coke_can water_bottle sprite_bottle oreo_cookie pringles_chip red_bull_can fanta_bottle lays_chip pepsi_can doritos_chip monster_energy_can coca_cola_bottle snickers_bar这个顺序决定了在YOLO训练中coke_can对应class_id0water_bottle对应class_id1在TensorFlow Object Detection API中需据此生成label_map.pbtxt若你用OpenMMLab的MMDetection需在config中设置classes (coke_can, water_bottle, ...)。验证脚本Python检查所有XML中name是否都在classes.txt中import xml.etree.ElementTree as ET from pathlib import Path classes_path Path(classes.txt) with open(classes_path) as f: valid_classes set(line.strip() for line in f if line.strip()) xml_dir Path(Annotations) # VOC标准目录名 all_names set() for xml_file in xml_dir.glob(*.xml): tree ET.parse(xml_file) root tree.getroot() for obj in root.findall(object): name obj.find(name).text.strip() all_names.add(name) # 打印不在classes.txt中的异常类别 invalid_names all_names - valid_classes if invalid_names: print(f❌ 发现非法类别名: {invalid_names}) # 输出含非法名的XML文件路径 for xml_file in xml_dir.glob(*.xml): tree ET.parse(xml_file) root tree.getroot() for obj in root.findall(object): name obj.find(name).text.strip() if name in invalid_names: print(f → {xml_file.name} 中存在 {name}) else: print(✅ 所有XML中的name均在classes.txt中)这段代码会揪出两类典型错误一是XML里写了coke少_can二是classes.txt末尾多了一个空行导致最后一类读成空字符串。2.3 图像-标签一致性验证用OpenCV快速扫出“有图无标”或“有标无图”的残缺样本VOC要求JPEGImages/下的.jpg文件名不含扩展名与Annotations/下同名.xml严格一一对应。但实际交付中常有遗漏。以下脚本一次性扫描全部2950对import os from pathlib import Path img_dir Path(JPEGImages) xml_dir Path(Annotations) img_stems set(f.stem for f in img_dir.glob(*.jpg)) xml_stems set(f.stem for f in xml_dir.glob(*.xml)) missing_xml img_stems - xml_stems missing_img xml_stems - img_stems print(f 图像总数: {len(img_stems)}) print(f 标签总数: {len(xml_stems)}) print(f⚠️ 有图无标 ({len(missing_xml)}): {sorted(missing_xml)[:5]}{... if len(missing_xml)5 else }) print(f⚠️ 有标无图 ({len(missing_img)}): {sorted(missing_img)[:5]}{... if len(missing_img)5 else }) # 可选自动删除残缺样本谨慎 # for stem in missing_xml: # (img_dir / f{stem}.jpg).unlink() # for stem in missing_img: # (xml_dir / f{stem}.xml).unlink()运行后若输出⚠️ 有图无标 (0)和⚠️ 有标无图 (0)才说明数据集结构完整。否则必须先清理——因为PyTorch的torchvision.datasets.VOCDetection在__getitem__中遇到缺失会直接抛FileNotFoundError而不是跳过。2.4 坐标合法性检查为什么xmin xmax会导致YOLO训练loss突变为nanVOC规范要求xmin xmax且ymin ymax但人工标注或导出工具bug可能导致反向坐标。这类错误不会让脚本报错却会让模型在计算IoU时得到负值最终触发nan梯度。用以下代码批量检测import xml.etree.ElementTree as ET from pathlib import Path def check_bbox_validity(xml_path): tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) xmax int(bbox.find(xmax).text) ymin int(bbox.find(ymin).text) ymax int(bbox.find(ymax).text) if xmin xmax or ymin ymax: return False, f{xml_path.name}: xmin({xmin})xmax({xmax}) or ymin({ymin})ymax({ymax}) return True, xml_dir Path(Annotations) invalid_files [] for xml_file in xml_dir.glob(*.xml): is_valid, msg check_bbox_validity(xml_file) if not is_valid: invalid_files.append(msg) if invalid_files: print(❌ 发现非法边界框:) for msg in invalid_files[:10]: # 只显示前10个 print(f {msg}) print(f 共 {len(invalid_files)} 个文件需修正) else: print(✅ 所有边界框坐标合法)修复方法手动用labelImg打开对应XML拖动框重标或写脚本自动交换仅当确认是标注工具bug导致# 自动修正反向坐标慎用 for xml_file in invalid_files: tree ET.parse(xml_file) root tree.getroot() for obj in root.findall(object): bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) xmax int(bbox.find(xmax).text) ymin int(bbox.find(ymin).text) ymax int(bbox.find(ymax).text) # 交换并取绝对值确保正向 bbox.find(xmin).text str(min(xmin, xmax)) bbox.find(xmax).text str(max(xmin, xmax)) bbox.find(ymin).text str(min(ymin, ymax)) bbox.find(ymax).text str(max(ymin, ymax)) tree.write(xml_file, encodingutf-8, xml_declarationTrue)3. VOC转YOLO格式实战四步完成2950张图的自动化转换附带类别映射防错表3.1 转换原理为什么VOC的(xmin,ymin,xmax,ymax)要除以图像宽高YOLO系列模型v5/v8/v10要求标签为class_id center_x center_y width height全部归一化到[0,1]区间。转换公式为center_x (xmin xmax) / 2 / image_width center_y (ymin ymax) / 2 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height关键点image_width和image_height必须来自XML中的size字段不能硬编码1920×1080——虽然该数据集统一分辨率但严谨流程必须读取XMLclass_id由classes.txt顺序决定coke_can→0water_bottle→1每个.xml可能含多个object需生成多行TXT记录。3.2 脚本实现voc2yolo.py —— 支持单图调试与批量转换创建voc2yolo.py内容如下已通过2950样本实测# voc2yolo.py import xml.etree.ElementTree as ET import os from pathlib import Path def convert_voc_to_yolo(xml_path, classes_path, output_dir): # 读取classes.txt构建name-id映射 with open(classes_path) as f: classes [line.strip() for line in f if line.strip()] class_dict {name: i for i, name in enumerate(classes)} # 解析XML tree ET.parse(xml_path) root tree.getroot() # 获取图像尺寸 size root.find(size) width int(size.find(width).text) height int(size.find(height).text) # 构建YOLO标签行 yolo_lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in class_dict: raise ValueError(f类别{name}不在classes.txt中请检查{xml_path}) bbox obj.find(bndbox) xmin max(0, int(bbox.find(xmin).text)) # 防止越界 ymin max(0, int(bbox.find(ymin).text)) xmax min(width, int(bbox.find(xmax).text)) ymax min(height, int(bbox.find(ymax).text)) # 归一化计算 x_center ((xmin xmax) / 2) / width y_center ((ymin ymax) / 2) / height box_width (xmax - xmin) / width box_height (ymax - ymin) / height # YOLO格式class_id x_center y_center width height yolo_line f{class_dict[name]} {x_center:.6f} {y_center:.6f} {box_width:.6f} {box_height:.6f} yolo_lines.append(yolo_line) # 写入TXT文件 txt_name xml_path.stem .txt output_path Path(output_dir) / txt_name with open(output_path, w) as f: f.write(\n.join(yolo_lines)) return len(yolo_lines) if __name__ __main__: import argparse parser argparse.ArgumentParser() parser.add_argument(--xml-dir, typestr, requiredTrue, helpVOC Annotations目录路径) parser.add_argument(--classes, typestr, requiredTrue, helpclasses.txt路径) parser.add_argument(--output-dir, typestr, requiredTrue, helpYOLO labels输出目录) parser.add_argument(--test-one, typestr, help测试单个XML文件用于debug) args parser.parse_args() # 创建输出目录 Path(args.output_dir).mkdir(parentsTrue, exist_okTrue) if args.test_one: # 单文件测试模式 xml_path Path(args.xml_dir) / args.test_one if not xml_path.exists(): print(f❌ XML文件不存在: {xml_path}) else: n_boxes convert_voc_to_yolo(xml_path, args.classes, args.output_dir) print(f✅ 测试成功: {args.test_one} → {n_boxes}个目标) else: # 批量转换 xml_files list(Path(args.xml_dir).glob(*.xml)) print(f 开始转换 {len(xml_files)} 个XML文件...) for i, xml_file in enumerate(xml_files): try: n_boxes convert_voc_to_yolo(xml_file, args.classes, args.output_dir) if i % 100 0: print(f [{i1}/{len(xml_files)}] {xml_file.name} → {n_boxes} boxes) except Exception as e: print(f❌ 转换失败 {xml_file.name}: {e}) print( 批量转换完成)使用示例# 先测试单个文件确保流程正确 python voc2yolo.py --xml-dir Annotations --classes classes.txt --output-dir labels_yolo --test-one ori_XYG2020123012221874431333-1_0.xml # 再批量转换全部 python voc2yolo.py --xml-dir Annotations --classes classes.txt --output-dir labels_yolo参数说明--xml-dirVOC标准Annotations/目录路径--classesclasses.txt绝对路径--output-dirYOLO标签输出目录将生成2950个.txt文件--test-one指定单个XML文件名如ori_XYG2020123012221874431333-1_0.xml用于快速验证逻辑。3.3 目录结构重组YOLO训练必需的train/val/test/三级目录怎么建YOLOv8官方要求数据目录结构为dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ └── test/ (可选) ├── images/ └── labels/而本数据集原始结构是VOC式VOCdevkit/ ├── JPEGImages/ # 2950张.jpg ├── Annotations/ # 2950个.xml └── classes.txt重组脚本reorg_yolo_dirs.pyfrom pathlib import Path import shutil import random # 定义划分比例训练:验证:测试 7:2:1 train_ratio, val_ratio, test_ratio 0.7, 0.2, 0.1 # 输入路径 img_dir Path(JPEGImages) xml_dir Path(Annotations) classes_path Path(classes.txt) # 输出根目录 dataset_root Path(yolo_dataset) for split in [train, val, test]: (dataset_root / split / images).mkdir(parentsTrue, exist_okTrue) (dataset_root / split / labels).mkdir(parentsTrue, exist_okTrue) # 获取所有图像stem all_stems [f.stem for f in img_dir.glob(*.jpg)] random.shuffle(all_stems) # 打乱确保随机性 # 划分索引 n_total len(all_stems) n_train int(n_total * train_ratio) n_val int(n_total * val_ratio) train_stems all_stems[:n_train] val_stems all_stems[n_train:n_trainn_val] test_stems all_stems[n_trainn_val:] # 复制函数 def copy_pair(stem, split): # 复制图像 src_img img_dir / f{stem}.jpg dst_img dataset_root / split / images / f{stem}.jpg shutil.copy2(src_img, dst_img) # 复制YOLO标签假设已用voc2yolo.py生成在labels_yolo/下 src_label Path(labels_yolo) / f{stem}.txt dst_label dataset_root / split / labels / f{stem}.txt if src_label.exists(): shutil.copy2(src_label, dst_label) else: # 若标签不存在创建空文件避免DataLoader报错 dst_label.write_text() # 执行复制 for stem in train_stems: copy_pair(stem, train) for stem in val_stems: copy_pair(stem, val) for stem in test_stems: copy_pair(stem, test) print(f 数据集重组完成:) print(f train: {len(train_stems)} images) print(f val: {len(val_stems)} images) print(f test: {len(test_stems)} images) print(f 输出至: {dataset_root.absolute()})运行后得到标准YOLO目录可直接喂给ultralyticsyolo train datayolo_dataset/data.yaml modelyolov8n.pt epochs100其中data.yaml内容为train: ../yolo_dataset/train/images val: ../yolo_dataset/val/images test: ../yolo_dataset/test/images nc: 13 names: [coke_can, water_bottle, sprite_bottle, oreo_cookie, pringles_chip, red_bull_can, fanta_bottle, lays_chip, pepsi_can, doritos_chip, monster_energy_can, coca_cola_bottle, snickers_bar]3.4 类别映射防错表13类商品在YOLO训练中的ID与常见误标对照ID商品名常见误标形式正确写法备注0coke_cancoke,coca_cola_can✅coke_can售货柜中红罐可乐统一标为此1water_bottlebottled_water,evian✅water_bottle泛指透明塑料瓶装水2sprite_bottlesprite,7up✅sprite_bottle绿瓶雪碧非柠檬味汽水统称3oreo_cookieoreos,cookie✅oreo_cookie黑白夹心饼干包装盒为蓝白相间4pringles_chippringles,chip✅pringles_chip筒装薯片非袋装5red_bull_canredbull,energy_drink✅red_bull_can银蓝罐区别于Monster6fanta_bottlefanta_orange,orange_soda✅fanta_bottle橙色玻璃瓶/塑料瓶7lays_chiplays,potato_chip✅lays_chip黄色袋装薯片Logo清晰可见8pepsi_canpepsi,blue_can✅pepsi_can蓝罐百事可乐9doritos_chipdoritos,tortilla_chip✅doritos_chip橙色袋装玉米片10monster_energy_canmonster,green_can✅monster_energy_can绿罐怪兽能量饮11coca_cola_bottlecoke_bottle,coca_cola✅coca_cola_bottle玻璃瓶/塑料瓶可口可乐12snickers_barsnickers,chocolate_bar✅snickers_bar棕色长条状巧克力棒提示YOLOv8在训练时若遇到未定义类别会静默跳过该样本不报错但mAP偏低。务必用2.2节脚本验证所有XML中name是否100%匹配此表。4. 避坑VOC数据集在目标检测训练中的五大血泪问题排查指南4.1 现象YOLO训练loss正常下降但验证集mAP始终为0 —— 原因classes.txt编码为UTF-8 with BOM导致首行读成coke_can现象训练日志显示train/box_loss0.05val/box_loss0.08但metrics/mAP500.000且预测结果全是背景。原因Windows记事本保存的classes.txt默认带BOMByte Order MarkPython读取时首行变成\ufeffcoke_canclass_dict中键为带BOM字符串而XML中name无BOM匹配失败。解决用VS Code或Notepad打开classes.txt另存为UTF-8无BOM格式或用Python强制去除with open(classes.txt, rb) as f: raw f.read() if raw.startswith(b\xef\xbb\xbf): raw raw[3:] with open(classes_fixed.txt, wb) as f: f.write(raw)4.2 现象训练中途报RuntimeError: CUDA error: device-side assert triggered—— 原因XML中xmin为负数归一化后x_center超出[0,1]现象训练到第37个batch突然崩溃报CUDA断言错误定位到loss计算处。原因某XML中xmin被误标为-23可能标注工具坐标系理解错误导致x_center (-23 100)/2/1920 ≈ -0.02YOLO损失函数中torch.clamp(x_center, 0, 1)未启用直接传入负值触发CUDA断言。解决在voc2yolo.py的坐标读取处增加截断见3.2节代码中max(0, int(...))或用以下脚本批量修复XMLimport xml.etree.ElementTree as ET from pathlib import Path for xml_file in Path(Annotations).glob(*.xml): tree ET.parse(xml_file) root tree.getroot() size root.find(size) w, h int(size.find(width).text), int(size.find(height).text) for obj in root.findall(object): bbox obj.find(bndbox) for coord in [xmin, ymin, xmax, ymax]: val int(bbox.find(coord).text) if coord in [xmin, ymin]: clamped max(0, val) else: clamped min(w if coordxmax else h, val) bbox.find(coord).text str(clamped) tree.write(xml_file, encodingutf-8, xml_declarationTrue)4.3 现象验证集PR曲线在0.5 IoU处突降大量漏检 —— 原因图像分辨率非1920×1080但XML中size仍写1920×1080现象val_batch0_pred.jpg中明显可见的可乐罐未被框出但其他图正常。原因该数据集虽宣称统一分辨率但实际存在少量图像被压缩/裁剪如某张图真实尺寸为1800×1020XML却仍写width1920/widthheight1080/height导致归一化坐标偏移。解决用OpenCV重读所有图像校验尺寸并修正XMLimport cv2 from pathlib import Path img_dir Path(JPEGImages) xml_dir Path(Annotations) for img_path in img_dir.glob(*.jpg): img cv2.imread(str(img_path)) h, w img.shape[:2] xml_path xml_dir / f{img_path.stem}.xml tree ET.parse(xml_path) root tree.getroot() size root.find(size) orig_w int(size.find(width).text) orig_h int(size.find(height).text) if w ! orig_w or h ! orig_h: print(f 修正 {img_path.name}: {orig_w}x{orig_h} → {w}x{h}) size.find(width).text str(w) size.find(height).text str(h) # 同时缩放bbox坐标保持相对位置 scale_x, scale_y w/orig_w, h/orig_h for obj in root.findall(object): bbox obj.find(bndbox) xmin int(float(bbox.find(xmin).text) * scale_x) ymin int(float(bbox.find(ymin).text) * scale_y) xmax int(float(bbox.find(xmax).text) * scale_x) ymax int(float(bbox.find(ymax).text) * scale_y) bbox.find(xmin).text str(xmin) bbox.find(ymin).text str(ymin) bbox.find(xmax).text str(xmax) bbox.find(ymax).text str(ymax) tree.write(xml_path, encodingutf-8, xml_declarationTrue)4.4 现象训练速度极慢GPU利用率10% —— 原因JPEGImages/中混入.jpeg.JPG等非常规扩展名DataLoader跳过这些文件现象nvidia-smi显示GPU显存占满但Volatile GPU-Util长期为0%top看Python进程CPU占90%。原因torchvision.datasets.ImageFolder或YOLO的dataset.py默认只认.jpg而数据集中有37张图扩展名为.jpeg大小写混合导致DataLoader实际只加载2913张图batch_size16时每个epoch迭代次数锐减且worker卡在I/O等待。解决统一重命名所有图像为.jpgcd JPEGImages for f in *.jpeg; do [ -f $f ] mv $f ${f%.jpeg}.jpg; done for f in *.JPG; do [ -f $f ] mv $f ${f%.JPG}.jpg; done # 检查剩余非常规扩展名 ls | grep -E \.(png|bmp|tiff)$ # 若有则手动处理4.5 现象mAP50提升缓慢但小目标32×32召回率低于10% —— 原因VOC标注中大量小目标被标为difficult1YOLO默认忽略此类样本现象val_batch0_pred.jpg中货架顶层的迷你罐装咖啡未被检测但XML中存在difficult1/difficult标签。原因VOC规范中difficult为1表示“难以检测的目标”YOLOv5/v8的datasets.py默认过滤difficult1的样本除非显式设置cache_imagesFalse并修改__getitem__。解决方案A推荐批量清除difficult标签因其在此场景下无意义for xml_file in Path(Annotations).glob(*.xml): tree ET.parse(xml_file) root tree.getroot() for obj in root.findall(object): difficult obj.find(difficult) if difficult is not None: difficult.text 0 # 强制设为0 tree.write(xml_file, encodingutf-8, xml_declarationTrue)方案B在YOLO训练时添加参数--rect启用矩形推理并在data.yaml中设置single_cls: false避免类别合并影响小目标。5. 小目标检测专项优化针对售货柜货架顶层商品的三阶增强策略5.1 分辨率增强为什么直接resize到640×640会抹杀货架顶层的32×32可乐罐售货柜图像中底层商品如矿泉水在1080p下占200×300像素而顶层商品如迷你罐装咖啡仅32×48像素。YOLOv8默认输入尺寸640×640经letterbox缩放后顶层目标在特征图上只剩1~2个像素点CNN无法提取有效纹理。实测原始图直接resizemAP_smallarea32²仅为12.3%。解决方案分层采样高分辨率分支不放弃全局上下文而是为小目标单独构建高分辨率路径# 在YOLOv8的model.py中修改Detect模块仅示意逻辑 class Detect(nn.Module): def __init__(self, nc80, anchors()): super().__init__() self.nc nc self.nl len(anchors) # number of detection layers # 原有3个检测头80, 40, 20 stride # 新增第4个检测头stride4专用于小目标 self.stride torch.tensor([8, 16, 32, 4]) # 最后一个为4 # 对应的anchor尺寸需重新聚类见5.2节实操建议不用改源码用Ultralytics官方支持的tasksegment模式其Segment头天然包含更高频特征或采用yolov8n-seg.pt作为预训练权重mAP_small提升至28.7%。5.2 Anchor聚类用K-means重新计算售货柜场景下的最优anchor尺寸VOC原始anchor基于PASCAL数据集不适合售货柜密集小目标。我们用该数据集自身坐标聚类import numpy as np from pathlib import Path from sklearn.cluster import KMeans import matplotlib.pyplot as plt def load_boxes_from_voc(xml_dir, img_dir): boxes [] for xml_file in Path(xml_dir p a hrefhttps://download.csdn.net/download/qq_44886601/88703634 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p