news 2026/10/1 19:25:32

基于YOLOV5的红外车辆检测实战:数据、训练与部署全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOV5的红外车辆检测实战:数据、训练与部署全流程

简介:基于YOLOV5的红外车辆检测完整方案,整合源码、预训练模型与标注数据集,面向计算机视觉开发者、智能交通研究人员,解决夜间或恶劣天气下车辆目标难以识别的问题。压缩包共128个文件,以Python脚本(py/pyc)、模型权重(pt)、网络配置(yaml)、标注信息(xml/json)及红外图像(jpg/png)为主,另有演示视频(mp4/mkv)与说明文档,整体约263.77MB,涵盖训练、推理与部署全流程。已有1061人学习下载,适合需要快速搭建红外车辆实时检测系统的工程师。压缩包内目录结构清晰,便于按需查阅。资源内含训练脚本、数据预处理与模型架构定义,提供的pt模型可直接加载推理,配合测试代码可实现摄像头场景下的实时识别;若结合自有红外数据集进行微调,可进一步提升特定环境与车型的适配能力,是一套可落地复用的目标检测实战参考。

1. 红外车辆检测为什么不能直接复用白天模型

把在COCO上训练的YOLOV5权重直接接到红外夜视画面,过车虚警率往往高到没法用——这不是模型不行,而是红外图像和可见光在数据分布上根本不是一回事。YOLOV5做红外车辆识别,要拆成两条路走:先用对口的红外数据集把模型微调成“认得车”,再把推理管线压到能跟着视频流实时出框。这篇笔记按数据、训练、落地、排错四个环节,把一套可复现的红外车辆检测方案讲清楚,适合手里有红外或热成像摄像头、想基于现成YOLOV5源码快速出效果的工程师。

红外画面里车辆常是亮斑或暗斑,纹理信息少,车灯和高反光件又容易过曝成一片。白天模型学到的边缘、轮廓、色彩统计在红外场景基本失效,这不是换个阈值就能解决的事。想实时、可靠地出检测框,就得先把数据和训练策略拨正,再谈部署优化。

2. 红外车辆数据集怎么做:采集、标注与切分的完整流程

2.1 红外图像和可见光数据的三个结构性差异

第一是通道。红外摄像机输出的原始画面通常是单通道灰度,而YOLOV5默认按RGB三通道读图。直接把灰度图丢进去,模型看到的是同一份数据复制三遍,本身没问题,问题在于很多人把通道顺序搞错,或者把16位红外原始数据直接当成8位图读,结果画面灰成一团,训练半天loss不降。

第二是纹理。可见光下车辆有清晰的车身线条、车牌、玻璃反光,这些特征在红外图像里基本消失。车在红外下往往是“一团亮斑”或“一团暗斑”,轮廓模糊,边缘过渡平缓。这意味着模型不能只靠局部纹理判断,得靠整体形状和温度对比度。

第三是目标尺度分布。红外车载摄像头视野里,远处车辆可能只占二三十个像素,近处车辆又可能撑满整个画面。同一段路上,车辆尺度跨度比可见光数据集大得多,直接沿用默认锚框和输入尺寸,小目标漏检率会很高。

还有一个常被忽略的点:红外图像里天气和季节影响很大。雨天路面和车体温差小,冬天车胎和轮拱区域温度高,这些都会改变目标外观。采集数据时最好覆盖不同时段、不同天气、不同朝向,否则验证集指标好看,一上线就现原形。

2.2 你需要的文件组织方式和标签格式

YOLOV5训练自己的数据集,图省事的话,把数据按下面的目录结构放好:

infrared_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.png │ │ └── ... │ └── val/ │ ├── 000101.png │ └── ... └── labels/ ├── train/ │ ├── 000001.txt │ └── ... └── val/ ├── 000101.txt └── ...

每个txt标签文件里的每一行对应一个目标,格式是“类别id 归一化中心x 归一化中心y 归一化宽 归一化高”,比如:

0 0.5234 0.4861 0.0825 0.0652

这里类别id从0开始,如果你的标注软件导出的格式是“xmin ymin xmax ymax”或“cx cy w h”的像素值,要写脚本转成归一化格式。红外场景通常只关心“车辆”这一类,所以nc=1最常见。类别少不等于随便标,标注边界要贴着车体轮廓,不要把路面热残留圈进去。

很多公开红外数据集自带的是可见光对齐标注框,直接用会有偏差,因为红外和可见光镜头之间存在视差。我一般会在训练前抽样两百张,把标注框叠到红外图上肉眼检查一遍。这一步花一小时,能省后面反复重训的三五天。

2.3 切分训练集验证集的脚本:三个参数与一个雷区

下面这个切分脚本可以直接用,按种子随机切分,保证验证集里有足够的正样本:

import os import random import shutil random.seed(42) src_images = "infrared_dataset/images" # 原始图像目录 src_labels = "infrared_dataset/labels" # 原始标签目录 val_ratio = 0.15 # 验证集比例 out_dir = "yolo_dataset" # 输出根目录 for split in ["train", "val"]: os.makedirs(os.path.join(out_dir, "images", split), exist_ok=True) os.makedirs(os.path.join(out_dir, "labels", split), exist_ok=True) files = [f for f in os.listdir(src_labels) if f.endswith(".txt")] random.shuffle(files) val_count = int(len(files) * val_ratio) for i, label_name in enumerate(files): split = "val" if i < val_count else "train" stem = os.path.splitext(label_name)[0] img_name = stem + ".png" # jpg/jpeg按实际后缀改 shutil.copy(os.path.join(src_labels, label_name), os.path.join(out_dir, "labels", split, label_name)) shutil.copy(os.path.join(src_images, img_name), os.path.join(out_dir, "images", split, img_name))

这段逻辑很直接,关键看三个参数:val_ratio不要低于10%,红外数据集通常不大,150到300张验证图已经能给出比较稳定的指标;random.seed(42)固定下来,方便别人复现和对比;图像后缀要按你的数据集实际格式改,红外采集常输出png或tiff,别写死成jpg。

这里有个雷区:切分前必须保证每个标签文件非空且类别id连续从0开始。红外采集时经常有空文件,也就是图像里没目标,这些文件留在训练集里会让模型学会“输出空框”,最稳妥的做法是切分时把空标签直接过滤掉,并在日志里打印过滤数量。

2.4 训练前的数据体检:用一段脚本验证标注和图像通道

花五分钟做一次数据体检,比训练到一半发现loss异常再排查强。下面脚本检查三件事:标签坐标是否越界、图像通道和位深、以及每张图的目标数量分布:

from PIL import Image import os import glob label_paths = glob.glob("yolo_dataset/labels/train/*.txt") for lp in label_paths[:500]: with open(lp) as f: for line in f: parts = line.split() cls = int(parts[0]) x, y, w, h = map(float, parts[1:]) if x - w/2 < 0 or x + w/2 > 1: print(f"越界: {lp} -> cx={x} w={w}") if y - h/2 < 0 or y + h/2 > 1: print(f"越界: {lp} -> cy={y} h={h}") if cls != 0: print(f"类别id异常: {lp} -> {cls}") img_paths = glob.glob("yolo_dataset/images/train/*.png") for ip in img_paths[:200]: img = Image.open(ip) if img.mode != "RGB" and img.mode != "L": print(f"异常图像: {ip} -> mode={img.mode}") if img.size[0] < 320 or img.size[1] < 320: print(f"尺寸过小: {ip} -> {img.size}")

YOLOV5训练时会自动把单通道灰度图转成三通道,所以mode="L"不必报错,但你要心里有数:如果数据集里混着L和RGB两种模式,预处理路径不一致,验证集指标会有抖动。坐标越界的标签训练时会被自动裁剪,但如果同时存在大量导致整框出界的噪声标框,梯度会被带偏。体检脚本的输出应当是零报错,出现任何一行提示都要回到标注环节处理,而不是带着问题继续往下走。

3. 训练YOLOV5红外模型:配置文件改法与关键超参数

3.1 单类别红外模型的data.yaml和模型配置怎么改

YOLOV5环境配置好之后,训练的第一步不是敲命令,是先写对data.yaml。单类别红外数据集的配置很简单:

path: ./yolo_dataset train: images/train val: images/val nc: 1 names: 0: vehicle

path推荐写相对路径,避免把机器相关的绝对路径带进配置。nc改成1后,模型输出头的通道数会跟着变,类别名写vehicle就行。不要在这里把红外图像预处理参数写进去,预处理要么在数据管线里统一做,要么在训练脚本里统一做,不要两边各改一半。

有人习惯直接把数据集拷贝到YOLOV5目录下运行,我一般不会这样做。数据集体积大,训练中又涉及频繁读取,放在机械盘和固态盘上训练速度差距明显。另外,path指向的目录里不要出现中文和空格,Windows下尤其容易踩路径编码问题。

3.2 预训练权重加载方式:从COCO迁移红外场景的两种选择

YOLOV5官方提供的yolov5s.pt在COCO上训练过,直接拿来做红外车辆检测的起点是常见做法,但迁移方式要分情况处理。

第一种是直接全量微调:

python train.py --data infrared.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 200

这种做法的优点是利用了COCO特征提取器的通用能力,适合你的红外数据集图像分布相对稳定、目标形态和COCO里的车接近的场景。缺点是红外域差异大时,模型要花更多epoch去“忘掉”可见光特征。

第二种是先冻结backbone训练,再解冻微调:

python train.py --data infrared.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --freeze 10

--freeze 10表示冻结前10层,也就是让backbone先不动,只训练检测头去适配红外特征。跑完100轮后再用同一份数据解冻全模型继续微调。这种做法在红外图像质量差、可见光预训练特征用处有限的场景下更稳,不容易一开始就把预训练权重破坏掉。

3.3 影响红外训练的四个超参数:epoch、batch、mosaic和锚框

红外数据集通常不大,超参数选择和可见光大不相同。我按影响程度排序说说。

epoch方面,红外场景域差异大,200轮是底线,我习惯设250到300轮。不要因为数据量小就只跑50轮,模型还没适应红外分布就停了,指标必然难看。但要注意配合早停机制,YOLOV5默认开启耐性停止,建议设置--patience 50,避免过拟合后还傻跑。

batch大小直接受显存约束。低显存运行模型时把batch压到8甚至4,但训练速度和BN统计稳定性都会下降。这里有个折中做法:固定batch后,把图像输入尺寸从默认640降到512,目标不大的场景下512足够,显存占用却能明显下降。

mosaic增强在红外场景要谨慎。YOLOV5默认开启mosaic,把四张图拼在一起训练,对可见光目标检测提升明显。但红外夜间场景中,四张低对比度灰度图拼在一起,会造成大量互相干扰的亮度区块,模型反而学出很多“假阳性纹理”。我会在训练后半程关闭mosaic,YOLOV5官方代码里这个参数叫mosaic,从超参数文件里设为0.5,或者使用--mosaic 0.5。如果发现损失震荡,直接关到0跑完剩余轮次。

锚框是红外车辆检测最容易忽略的一环。红外车辆的宽高比和可见光差异不大,但尺度分布差异大——远距离小目标占比高,长约宽比接近1:1甚至竖长条。用脚本重算锚框:

python utils/autoanchor.py --data infrared.yaml --img 640 --rect

运行后确认脚本给出的新锚框和默认锚框的差异。如果平均宽高比变化超过20%,说明默认锚框确实不匹配你的红外数据,训练时用新的锚框。如果差异不大,保留默认值即可,不用为了改而改。

3.4 跑一轮训练前的清单和训练日志怎么看

启动训练前我会过一遍清单:标注框有没有越界,train和val的文件数量比例是否合理,类别id是不是只有0,超参数文件里mosaic是不是被改成0.5或更低,预训练权重路径存在。然后跑一个短迭代确认能正常出loss:

python train.py --data infrared.yaml --weights yolov5s.pt --img 640 --batch 8 --epochs 5

这5轮用来验证数据管线和显存占用,不追求指标。确认没报错后再跑正式训练。

训练日志里真正值得盯的是这几个数值:val/obj_loss、mAP@0.5和P/R。train/box_loss降得快不代表模型好用,训练loss低到接近0而验证mAP不涨,基本就是过拟合信号。红外场景数据量小,过拟合比可见光场景来得更早,我更关注验证集指标从第几轮开始停滞——如果连续40轮验证mAP不涨,就可以停了,追求最后那0.5%的mAP没有工程意义。

4. 实时检测落地:从模型到视频流的工程接线

4.1 用训练好的权重跑摄像头推理的最小脚本

YOLOV5官方仓库的detect.py本身就能接摄像头做实时检测,但工程上我更习惯写一个精简的推理脚本,把后处理逻辑露出来,方便按场景调参:

import torch import cv2 import numpy as np model = torch.hub.load('./yolov5', 'custom', path='runs/train/exp/weights/best.pt', source='local', device='0') model.conf = 0.35 # 置信度阈值,红外场景建议先高后低 model.iou = 0.45 # NMS的IoU阈值 model.max_det = 50 # 单帧最大目标数 cap = cv2.VideoCapture(0) # 红外摄像头设备号或RTSP地址 while cap.isOpened(): ret, frame = cap.read() if not ret: break results = model(frame, size=640) boxes = results.pred[0].cpu().numpy() for x1, y1, x2, y2, conf, cls in boxes: cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.imshow("infrared", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break

这段代码的核心是后处理三段。model.conf、model.iou和model.max_det对应YOLOV5后处理里的置信度过滤、NMS和数量上限,红外场景配高置信度阈值能压掉路面热残留造成的虚警。results.pred[0]返回的是已经做过NMS的框,每行是xyxy坐标、置信度和类别id。

红外摄像头接入方式和普通USB摄像头一样,VideoCapture(0)是设备索引,换成RTSP地址就是网络摄像头。注意红外视频帧率本身只有15到25帧,如果推理跟不上,画面会有明显延迟感。轮询模式在帧率低时没问题,但多路或者高分辨率场景就必须做线程化改造,见下文。

4.2 实时性卡在哪:预处理、推理和后处理的时间分账

把一帧红外图像从摄像头拉到出框,时间主要花在三段:预处理、推理、后处理。用推理一百帧的平均耗时去看,预处理通常占10%左右,后处理在目标密集时能占到30%,大头还是模型推理。

预处理慢在图像缩放和格式转换。摄像头来的帧分辨率常是1920x1080,而模型输入是640x640,每次resize都是整帧操作。可以用448或512的输入尺寸降推理时间,红外目标不需要特别精细的纹理,448输入对小目标不够友好,但会牺牲一些远距离检测能力,要在帧率与距离之间找平衡。

推理提速最直接的是半精度推理。如果你的显卡支持FP16,加载权重后把模型切成半精度:

model.model.half() model.conf = 0.35

半精度推理在多数专业卡上能带来40%以上的提速,memory占用还能降一半。需要注意红外图像预处理时要把输入数据也转成torch.float16,否则类型不匹配直接报错。

后处理慢的根源是NMS在CPU上逐框计算。目标密集的红外场景一帧有几十个候选框,每帧跑NMS开销可观。不要每秒都重算一次阈值,固定住conf和iou参数就能让后处理路径稳定。如果单帧目标实在太多,把max_det降到30,能压住边缘场景的延迟抖动。

4.3 多路视频流下的工程化安排

多路红外摄像头是更常见的部署场景。每路一路视频流开一个推理线程,GPU会被反复刷成瓶颈,因为单张卡的显存和计算单元有限。更好的做法是把多路帧收集到公共队列,合并成batch推理:

import queue import threading frame_queue = queue.Queue(maxsize=16) batch_size = 4 def collect_loop(cap_index): cap = cv2.VideoCapture(cap_index) while True: ret, frame = cap.read() if ret: frame_queue.put(frame, block=True) def infer_loop(): frames_batch = [] while True: frame = frame_queue.get() frames_batch.append(frame) if len(frames_batch) == batch_size: results = model(frames_batch, size=640) frames_batch = []

这种写法的核心是让多路采集线程只管读帧,推理线程按batch合并后一次跑多张,GPU利用率显著提高。代价是延迟增加,因为要攒够batch_size才推理,对实时性要求高的单路场景不适用。一条经验线是:单路摄像头用单帧推理,三路以上再考虑batch合并,否则延迟带来的体验损失大于吞吐收益。

5. 红外车辆检测的常见坑与排查

5.1 红外车灯过曝导致检测框跳动

现象:夜间会车时,车灯区域过曝成一大团亮斑,检测框在灯和车身之间跳来跳去,置信度忽高忽低。

原因:红外图像中车灯和路面温差大,传感器动态范围有限,灯周围一片过曝。模型学的目标形状不稳定,同一辆车在画面里呈现两种形态。

解决:先在数据增强阶段对所有训练图做一次灰度对比度裁剪,把过曝亮斑压到目标范围内,让模型学习车体整体轮廓而不是灯斑。部署端再把model.conf从默认0.25提到0.35到0.40,可以明显减少过曝区域的抖动框。如果用的摄像头支持手动增益或AGC关闭,尽量固定曝光参数,让推理输入分布和训练分布一致。

5.2 模型在路面热残留区域产生虚警

现象:车开走后路面上留下明显的轮胎热痕迹,模型持续输出“车辆”框,有时连续几十帧不消失。

原因:胎痕区域温度高,形状偏长条形,与被检车辆的远处轮廓相似。数据里缺少这类负样本,模型把它们当成了正样本。

解决:从实际场景采集路面残留、热斑区域的图像加入训练集,但不要标注成车辆,而是作为背景图混入,让模型看到更多“车开走之后路面长什么样”的反例。数据处理时也可以做区域随机抠除,把温度热点区域从训练样本里随机抹掉一部分,降低模型对这类纹理的敏感度。加上这些样本后,虚警通常一轮训练就能压下来。

5.3 训练loss正常但验证mAP上不去

现象:训练集loss稳定下降,P/R曲线却徘徊在0.8以下,尤其在小目标上漏检严重。

原因:这是红外数据集最常见的“分布矛盾”之一。数据量小,目标尺度跨度大,小目标只占少量标注框,模型整体向中大型目标倾斜。另一种可能是标注框本身偏大,把背景框了进去,模型学出的目标边界是“车外加一圈”,小目标被标注框稀释得更厉害。

解决:先跑autoanchor重算锚框,再看验证集里小目标的占比。如果小目标占比确实低,把验证切分改成按尺度分层抽样,保证小目标在验证集里有足够数量,否则mAP评价本身就失真。同时把输入尺寸从640提到768,小目标的特征图响应会强很多——代价是推理帧率下降,需要在训练阶段就决定部署尺寸,不要训练用640、部署用768,两者指标对不上。

5.4 推理端帧率上不去、延迟波动明显

现象:单路摄像头,显卡占用率只有40%,但帧率只有8到10帧,且每隔几秒卡顿一次。

原因:帧率瓶颈往往不在GPU推理,而在CPU上的视频解码、图像resize和画框。红外摄像头输出的YUV格式在CPU上转BGR本身就耗时,再加上每帧缩放到640和绘制矩形框,大量CPU操作拖慢了整条链路。另一处容易被忽视的是帧读取阻塞:cap.read()读完一帧再推理,摄像头缓冲和推理跟不上时,延迟逐步累积。

解决:把读取、预处理、推理、绘制拆成两个线程,采集线程只负责读帧放进队列,推理线程从队列取帧处理。延迟波动一般就消失了。顺手把可视化绘制降到每三帧画一次框,或者只输出检测结果不上屏,CPU占用立减。

5.5 换了一路摄像头后检测效果全面下滑

现象:A摄像头标定调试正常,换到B摄像头后漏检率暴涨,框的位置整体偏移。

原因:两个摄像头的视场角、安装角度、红外波段响应不同。YOLOV5训练数据来自A摄像头,模型学到的目标尺度分布和温标特征全部偏向A。B摄像头的画面亮度和对比度分布不同,甚至红外图像是反相的,模型直接失效。

解决:这是红外项目最常见的上线事故。先把B摄像头的图像做直方图匹配,让亮度分布接近A,再看指标能否恢复。如果还不行,就把B摄像头的部分帧加入训练集做增量微调。第二次做数据时我就学乖了:训练一个红外模型前先确认它能覆盖至少两种不同摄像头参数,或在部署流程里加上简单的画面自检,跳过亮度分布偏差过大的输入。

6. 验证与进阶:交付出前最后做的事情

6.1 用验证集指标给交付贴标签

训练结束后,不要只截一张loss曲线图就算交付。用YOLOV5自带的验证命令一次性输出全部评价指标:

python val.py --data infrared.yaml --weights runs/train/exp/weights/best.pt --img 640 --conf 0.35 --iou 0.45

输出会包含mAP@0.5、mAP@0.5:0.95、precision和recall。红外单类别场景,我一般以mAP@0.5大于0.85作为交付基准,mAP@0.5:0.95大于0.55说明框的位置精度也够用。如果后者偏低,往往是标注边界不齐或锚框匹配差,不要急着改模型,先抽几十张验证图把标注框叠上去看贴合度。

可视化检查同样重要。把推理结果拼接成视频,重点看三个片段:远距离小目标有没有连续漏检、夜间车灯过曝时框是否稳定、车停着不动时会不会掉框。连续帧之间的检测稳定性,比单帧mAP更能反映部署效果。

6.2 导出ONNX做半精度推理,把帧率再压一档

训练好best.pt之后,我会导出为ONNX格式,再转成TensorRT或OpenVINO来跑推理。YOLOV5官方脚本一行就能完成导出:

python export.py --weights runs/train/exp/weights/best.pt --include onnx --half

导出后验证一次输出精度没有明显下降,再把原来的PyTorch推理换成ONNX Runtime推理。同样的显卡,这一套操作通常能把帧率再提50%;CPU部署的红外检测系统,转成ONNX后配合OpenVINO是性价比最高的加速路径。

我的习惯是导出前先用原始PyTorch跑一次验证集,导出后再跑一次,对比两次mAP差距不超过0.01才继续,超过就回退到原始格式排查。这步检测相当于给部署上了一道保险。

6.3 交付时顺便把阈值参数埋成配置

最后说一个让我少跑好几趟现场的习惯:把置信度阈值、NMS阈值、输入尺寸、最大检测数全部提到外部配置项。项目第一阶段调试时阈值写死在代码里方便,真到部署环境,现场灯光、摄像头角度一变,就得重新调这三四个参数。如果它们是配置文件里的键值,远程改配置比重新发一版程序简单得多。

红外车辆检测的坑大多不在模型结构本身,而在数据和部署环境的差异。训练前把数据体检做到位,训练时盯着验证集指标而不是loss,部署后用线程化和半精度把延迟压住,这套流程走下来,从拿到红外摄像头到稳定出框,一周内就能看到可以交付的版本。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 19:21:27

AI工程从零手搓:从张量到微型语言模型的完整实践

今年我把大量业余时间投进了一个叫ai-engineering-from-scratch的个人项目。简单说&#xff0c;就是给自己立了条规矩&#xff1a;凡是跟 AI 相关的环节&#xff0c;能自己动手实现的&#xff0c;绝不直接调封装好的接口。从手写张量运算开始&#xff0c;到训练一个微型语言模型…

作者头像 李华
网站建设 2026/10/1 19:20:17

AI工程化落地指南:从智能体训练到多AI协作工作流

今天是2026年9月22日&#xff0c;星期二。照例&#xff0c;我把过去24小时里AI圈值得关注的信息仔细捋了一遍——模型侧有新的训练方法公开&#xff0c;应用侧有几个项目落地动作&#xff0c;开发工具链这边也有不少更新。这篇日报我会尽量少说空话&#xff0c;每条信息后面都附…

作者头像 李华
网站建设 2026/10/1 19:19:57

AI驱动Blender MCP快速生成智慧仓储数字孪生模型

1. 项目缘起与整体架构拆解1.1 为什么选“智慧仓储”作为数字孪生落地场景做数字孪生这几年&#xff0c;我经手过园区、机房、产线、变电站好几个方向&#xff0c;最后发现智慧仓储是最适合拿来练手、也最容易出效果的场景。原因很直接&#xff1a;仓储空间的几何结构规整&…

作者头像 李华
网站建设 2026/10/1 19:19:10

iOS上运行Windows程序:Wine+FEX-Emu+DXMT兼容层实战

1. 项目缘起&#xff1a;为什么要在 iOS 上折腾 Wine 兼容层第一次看到 "Madeira" 这个项目名&#xff0c;很多人会以为是那个葡萄牙的旅游海岛&#xff0c;但在我们这群喜欢折腾跨平台兼容层的人眼里&#xff0c;它指向的是另一件事&#xff1a;把 Windows 应用搬到…

作者头像 李华
网站建设 2026/10/1 19:18:56

ShuffleNet轻量CNN实战:8类菠萝成熟度图像分类

简介&#xff1a;基于ShuffleNet的轻量级图像分类实战项目&#xff0c;面向有基础CNN知识、希望在移动端或小模型场景落地分类任务的开发者。完整覆盖菠萝成熟度8分类流程&#xff0c;数据集划分清晰&#xff0c;训练集4808张、测试集806张&#xff0c;并已提供训练好的权重文件…

作者头像 李华
网站建设 2026/10/1 19:18:38

openrig 实战:用 YAML 和 tmux 统一编排 Claude Code 与 Codex

1. 从零认识 openrig&#xff1a;它到底解决什么问题第一次看到 openrig 这个名字&#xff0c;很多人会以为是某个硬件支架项目&#xff0c;毕竟 rig 在英文里有“装配、支架”的意思。但在当前 AI 编程工具爆发的语境下&#xff0c;openrig 指向的是一个非常具体且刚需的方向&…

作者头像 李华