news 2026/6/12 11:06:06

Windows下免配置挥拳动作实时检测程序(OpenCV3.0+VS2012一键运行)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows下免配置挥拳动作实时检测程序(OpenCV3.0+VS2012一键运行)

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

简介:直接双击就能用的挥拳动作检测工具,基于OpenCV3.0在Windows平台实现摄像头实时捕捉与识别。不依赖GPU、不需训练模型,用帧差法加轮廓分析判断手臂快速前伸特征,输出二值化挥拳判定结果。压缩包里包含完整VS2012工程(.sln和.vcxproj)、已编译好的test1.exe可执行文件,以及调试必需的.pdb和.ilk文件;所有逻辑集中在单个test1.cpp源码中,无第三方库依赖。支持调整检测区域(ROI)、灵敏度阈值,也方便改成拍手、抬手等其他简单动作触发逻辑。适合高校课程实验演示、健身互动原型开发、或嵌入式体感开关类轻量应用。

1. 项目概述:为什么一个“双击即用”的挥拳检测程序值得花时间深挖?

你有没有在实验室里调试过动作识别demo?我试过太多次:装CUDA、配PyTorch环境、下载几百MB的预训练模型、改config文件、调learning rate……最后发现摄像头根本没权限,或者OpenCV版本不兼容,又或者Python路径里混进了中文——一上午就没了。而这个项目标题里写着“Windows下免配置挥拳动作实时检测程序(OpenCV3.0+VS2012一键运行)”,光是“免配置”“一键运行”这六个字,就戳中了高校实验课老师、创客社团负责人、嵌入式初学者和体感交互原型开发者的共同痛点。它不是另一个深度学习玩具,而是一把真正能拧开螺丝、接上线、立刻让LED灯随你挥拳亮起的物理钥匙。

核心关键词“挥拳检测、OpenCV3、VS2012、实时动作识别”,已经框定了它的技术坐标:它扎根于传统计算机视觉的确定性逻辑,拒绝黑盒推理,拥抱可解释、可调试、可预测的工程实践。它用的是OpenCV 3.0——不是最新版,但恰恰是VS2012原生支持最稳定的C++接口版本;它不依赖GPU加速,意味着一块十年前的i3笔记本也能跑满30fps;它没有.pth或.onnx模型文件,所有判断逻辑压缩在test1.cpp一个源文件里,打开就能读、改完就能编、编完就能跑。这不是“简化版AI”,而是对动作本质的一次精准解构:挥拳不是姿态分类,而是一次具有明确时空特征的局部运动爆发——手臂从屈曲到伸展的快速位移、在固定视野区域内的显著轮廓膨胀、连续帧间像素差值的瞬时峰值。它把问题从“识别是什么”降维到“捕捉发生了什么”,这才是轻量级体感交互真正需要的底层能力。

我带过三届数字图像处理课程设计,学生交上来的“挥手控制PPT翻页”项目,80%卡在OpenCV环境搭建和摄像头初始化失败上。而这个方案,双击test1.exe后,不到两秒,窗口弹出,绿色方框锁定你的肩膀下方区域,当你缓缓抬手,框内无反应;一旦突然前冲——“滴”一声提示音,窗口右上角红色“PUNCH!”字样闪现0.5秒。这种确定性反馈,对教学演示的价值远超任何准确率99.7%却要配三天环境的模型。它适合谁?不是算法研究员,而是需要在45分钟课堂内让学生亲眼看到“动作→信号→响应”闭环的老师;是正在为智能健身镜做POC验证的硬件工程师;是想给轮椅控制器加一个“挥左拳=向左转”物理开关的康复辅具开发者。它不追求泛化,只专注把一件事做透:在资源受限、部署环境不可控的Windows桌面端,用最朴素的视觉线索,可靠地捕获一次手臂的爆发性前伸。接下来,我们就一层层剥开这个看似简单的exe背后,那些被精心设计、反复实测、写进每一行注释里的工程细节。

2. 整体设计思路与技术选型解析:为什么不用深度学习?为什么是帧差法+轮廓分析?

2.1 拒绝深度学习的底层逻辑:成本、确定性与可维护性

看到“动作识别”,第一反应往往是YOLO、MediaPipe或自建CNN。但在这个项目里,所有深度学习路径都被主动关闭了。这不是技术保守,而是基于三个硬约束的理性取舍:

  • 部署成本归零:一个TensorRT优化后的轻量模型,仍需安装CUDA驱动、cuDNN库、特定版本的OpenCV contrib模块,还要处理GPU显存分配异常。而本方案的可执行文件test1.exe仅1.2MB,静态链接OpenCV3.0核心库(imgproc、video、highgui),双击即启,连VC++2012运行时都打包进去了。我在一台刚重装Win7的实验室老电脑上测试,全程无需联网、无需管理员权限、无需额外安装任何组件。

  • 判定逻辑完全透明:深度学习输出一个0.92的“挥拳概率”,你无法知道它是被袖口反光误导,还是被背景窗帘晃动欺骗。而本方案的判定链条是:原始帧 → 灰度化 → 高斯模糊 → 帧差(t与t-2)→ 二值化(阈值=30)→ 形态学闭运算 → 轮廓查找 → 过滤面积<500px²的噪声 → 计算最大轮廓质心偏移量 → 若Δx>80px且Δy<-20px(强调前伸+微抬)→ 触发挥拳事件。每一个环节的中间结果都能实时可视化(按空格键切换显示模式),故障排查像读电路图一样清晰。

  • 参数调整直觉化:教学场景中,老师需要向学生解释“为什么这里设阈值30而不是25”。帧差法的阈值直接对应像素灰度变化强度,30意味着至少有30级灰度跃变才被视为有效运动——这比解释“卷积核感受野大小对特征提取的影响”直观一百倍。我在某高校体感交互课上,让学生现场修改test1.cpp第87行的THRESHOLD_DIFF = 30,调到15,立刻看到背景树叶晃动引发误触发;调到50,则挥拳动作变慢就漏检。这种即时反馈,是模型微调永远给不了的教学穿透力。

2.2 帧差法为何选“t与t-2”而非“t与t-1”?

帧差法的核心是计算相邻帧的像素差异。但直接用frame[t] - frame[t-1]会带来两个致命问题:一是运动模糊导致差值扩散,二是高频噪声(如荧光灯频闪)产生大量伪边缘。本方案采用frame[t] - frame[t-2](跳帧差分),其物理意义是捕捉持续性的运动趋势。举个例子:你以60fps拍摄挥拳,从起始到击打点约15帧。若用t-t-1差分,第1帧到第2帧的差值可能只有肩部微动(小值),第2帧到第3帧才是手臂加速(大值),但单帧差分无法累积这种趋势;而t-t-2差分,第3帧减第1帧,直接放大了加速段的位移量,同时因跳过中间帧,天然抑制了单帧噪声。我在实测中对比过三种差分方式(t-t-1、t-t-2、t-t-3)在相同光照下的误报率:t-t-1为12.3%,t-t-2降至3.1%,t-t-3虽进一步降到1.8%,但会导致慢速挥拳(如老年人健身动作)漏检率达35%。最终选择t-t-2,是在抗噪性与动作包容性之间找到的黄金平衡点。

2.3 ROI区域设计:为什么锁定“肩下150px至肘上50px”?

检测区域(Region of Interest, ROI)不是随便画个框。test1.cpp中第42行定义的ROI矩形Rect(roi_x, roi_y, roi_w, roi_h),默认值为(160, 240, 320, 200),即从画面x=160,y=240开始,宽320高200像素。这个坐标的设定依据是标准USB摄像头(如罗技C270)在640×480分辨率下的典型人体构图:当用户正对摄像头站立,肩线约在y=200处,肘关节约在y=400处。ROI的y起点设为240(肩线下40px),确保覆盖整个小臂运动范围;高度200px则刚好从肩下延伸至肘上50px,既避开躯干大面积静止区域(减少帧差噪声),又完整包含前臂伸展时的轨迹空间。我在不同身高用户(155cm~185cm)测试中发现,此ROI对92%的受试者无需调整即可稳定检测。若遇特殊场景(如坐姿检测),只需修改第43行roi_y = 240roi_y = 300,将ROI下移60px,即可适配肘部更低的构图——这种调整粒度,比重新训练一个姿态估计模型快100倍。

3. 核心代码解析与关键参数详解:test1.cpp逐行拆解

3.1 主循环结构:如何保证30fps实时性?

test1.cpp的主函数main()结构极简,但每一步都针对性能优化。核心循环(第120行起)如下:

while (true) { cap >> frame; // 1. 读取一帧(约3ms) if (frame.empty()) break; // 2. ROI裁剪(关键!避免全图计算) Mat roi_frame = frame(roi_rect); cvtColor(roi_frame, gray, COLOR_BGR2GRAY); // 3. ROI内灰度化(省去全图480*640计算) // 4. 高斯模糊降噪(核大小5x5,sigma=0) GaussianBlur(gray, gray, Size(5,5), 0); // 5. 帧差计算(t与t-2) absdiff(gray, prev_gray2, diff); prev_gray2 = prev_gray1.clone(); // 6. 帧缓冲更新 prev_gray1 = gray.clone(); // 7. 二值化与形态学处理 threshold(diff, bin, THRESHOLD_DIFF, 255, THRESH_BINARY); morphologyEx(bin, bin, MORPH_CLOSE, kernel); // 闭运算连接断裂轮廓 // 8. 轮廓分析与挥拳判定 vector<vector<Point>> contours; findContours(bin, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); if (!contours.empty()) { // 找最大轮廓并计算质心偏移 Moments mu = moments(contours[0]); Point2f mc(mu.m10/mu.m00, mu.m01/mu.m00); float dx = mc.x - prev_mc.x; float dy = mc.y - prev_mc.y; if (dx > MIN_DX && dy < MIN_DY) { // 前伸+微抬判据 punch_flag = true; last_punch_time = getTickCount(); } prev_mc = mc; } // 9. 可视化叠加(仅调试用,发布版可注释) rectangle(frame, roi_rect, Scalar(0,255,0), 2); if (punch_flag) { putText(frame, "PUNCH!", Point(10,30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0,0,255), 2); playSound(); // 播放提示音 punch_flag = false; } imshow("Punch Detector", frame); char key = waitKey(33); // 33ms≈30fps,waitKey阻塞确保帧率稳定 if (key == 27) break; // ESC退出 }

这段代码的精妙之处在于计算域收缩:所有耗时操作(灰度化、高斯模糊、帧差、二值化)都在ROI子图roi_frame上进行,而非原始640×480帧。这意味着高斯模糊的计算量从640×480×25次乘加,锐减至320×200×25次,提速近3倍。waitKey(33)的硬编码33ms,是经过实测的帧率锚点——即使CPU占用率飙升,它也会强制等待至33ms才进入下一帧,避免因处理延迟导致帧率崩塌。我在i5-3210M(2012年笔记本CPU)上实测,此循环平均耗时28ms,留有5ms余量应对瞬时负载。

3.2 关键参数物理意义与实测调优表

所有可调参数集中在test1.cpp开头的宏定义区(第25-35行)。它们不是随意设定的魔法数字,而是基于大量真实场景测试得出的经验值:

参数名默认值物理意义实测影响推荐调整场景
THRESHOLD_DIFF30帧差二值化的灰度阈值<25:荧光灯频闪误触发;>45:慢速挥拳漏检光照强(窗边)→ 调至35;弱光(会议室)→ 调至25
MIN_DX80.0f质心X方向最小位移(像素)<60:易受呼吸微动干扰;>100:需大幅挥拳才触发儿童用户→ 调至60;VR手柄联动→ 调至120(防误触)
MIN_DY-20.0f质心Y方向最大位移(负值表示上移)>-10:抬手易误判;<-30:标准挥拳可能因角度被判无效坐姿检测(肘部低)→ 调至-10;拳击训练(强调上勾)→ 调至-40
ROI_X,ROI_Y160, 240ROI左上角坐标X偏移影响左右手检测平衡;Y偏移决定覆盖小臂范围左撇子用户→ ROI_X调至100;高个子→ ROI_Y调至200

特别说明MIN_DY的负值设计:挥拳时小臂前伸必然伴随肘关节微抬(生物力学决定),Y方向位移为负值(OpenCV坐标系Y向下为正)。若设为正值,系统会将“向下砸拳”误判为有效,而这在多数交互场景中是危险动作。我在健身房实测发现,专业拳击手的直拳Y位移均值为-18.3±3.2px,故取-20作为鲁棒阈值。

3.3 轮廓质心追踪的稳定性增强技巧

单纯比较当前帧与前一帧质心,会因单帧噪声导致剧烈抖动。代码中(第158行)采用了双缓冲质心记忆

// prev_mc存储上一有效轮廓质心,prev_mc2存储上上帧 if (contours.size() >= 1) { Moments mu = moments(contours[0]); Point2f mc(mu.m10/mu.m00, mu.m01/mu.m00); // 仅当当前质心与prev_mc距离<50px才更新,过滤跳跃噪声 if (norm(mc - prev_mc) < 50.0) { prev_mc2 = prev_mc; prev_mc = mc; } }

这个50px的距离阈值,对应现实尺度约15cm(按摄像头距离1.5米估算)。任何超过此距离的“质心突跳”,都被判定为噪声或目标丢失,维持旧值。这使得系统在用户短暂侧身、镜头轻微晃动时,仍能保持判定连续性。我在测试中故意用纸板遮挡镜头1秒再移开,系统能在2帧内恢复追踪,无误触发。

4. 实操部署与二次开发指南:从双击运行到定制你的专属动作

4.1 零配置运行全流程(含常见陷阱排雷)

拿到压缩包后,真正的“一键运行”需要绕过几个Windows经典陷阱。以下是我在37台不同品牌电脑(从Win7到Win11)上验证的标准化流程:

  1. 解压与路径安全:将压缩包解压到纯英文路径,如D:\punch_demo\。严禁使用含空格或中文的路径(如C:\我的程序\),否则VS2012生成的.ilk调试文件会加载失败,导致exe启动黑屏。这是Windows API对长路径和特殊字符的古老限制。

  2. 摄像头权限检查:Win10/11需手动开启摄像头权限。进入设置→隐私→相机→允许应用访问相机,确保“本地账户”开关为开。若仍无画面,在代码第105行cap.open(0)后添加诊断:
    cpp if (!cap.isOpened()) { printf("Error: Cannot open camera! Check privacy settings.\n"); return -1; }

  3. 首次运行必做校准:双击test1.exe后,窗口出现绿色ROI框。此时静止站立3秒,让程序自动采集背景帧(prev_gray2初始化)。若跳过此步,初始帧差会因背景未稳定而爆满,触发连续误报。我在教学现场见过学生因急着挥拳,导致程序前10秒疯狂报警,其实是自己没等校准完成。

  4. 灵敏度微调实战:若发现挥拳不触发,不要急着改代码。先按键盘'+'键(代码第212行),每次增加THRESHOLD_DIFF值5点;若频繁误报,按'-'键降低。这个热键功能在test1.cpp第208-215行实现,是专为现场调试设计的免编译调节方式。我在某次创客马拉松中,用此法在30秒内帮参赛队将误报率从18%压至0%。

4.2 三分钟扩展新动作:从挥拳到拍手、抬手

所有动作扩展都遵循同一范式:修改质心运动判据。以“拍手”为例(双手在胸前快速合拢),其运动特征是:X方向位移小(双手向中线靠拢),Y方向位移小,但轮廓面积变化剧烈(合掌时手掌重叠,面积骤减)。只需在挥拳判定块后(第175行)插入:

// 拍手检测:基于面积变化率 float area_ratio = contour_area / prev_contour_area; if (area_ratio < 0.6 && abs(dx) < 30 && abs(dy) < 30) { // 面积缩至60%以下且无大幅位移 clap_flag = true; printf("CLAP DETECTED!\n"); } prev_contour_area = contour_area;

而“抬手”动作(如控制智能家居),特征是Y方向大幅上移(dy > 100)。只需将挥拳的dy < MIN_DY改为dy > 100,并调整MIN_DX< 30(抑制水平移动干扰)。我在为养老院设计紧急呼叫按钮时,就是用此法将抬手动作的误报率控制在0.2%以内——老人缓慢抬手不会触发,但突发性抬手(如摔倒后求助)100%捕获。

4.3 VS2012工程编译避坑指南

虽然提供已编译exe,但二次开发必经编译环节。VS2012(VC110)的坑比想象中多:

  • OpenCV库路径硬编码:工程属性中附加包含目录指向$(OPENCV_DIR)\build\include附加库目录指向$(OPENCV_DIR)\build\x86\vc110\lib。若你安装OpenCV到D:\opencv\,需在VS中工具→选项→项目和解决方案→VC++目录,将$(OPENCV_DIR)环境变量设为D:\opencv。否则编译报错cannot open include file 'opencv2/opencv.hpp'

  • 运行时库一致性:项目属性C/C++→代码生成→运行时库必须设为/MT(多线程静态链接)。若误设为/MD(动态链接),exe在无VS运行时的电脑上会弹出MSVCP110.dll缺失错误。这是本项目能“免配置”的关键——所有C++运行时都静态打包进exe。

  • 调试符号文件(.pdb)的妙用:压缩包中的test1.pdb不仅是调试用,更是逆向分析的利器。用Visual Studio打开exe,加载pdb后,F11单步进入任意OpenCV函数(如findContours),能看到汇编指令与源码映射。我在修复某次轮廓检测漂移bug时,正是通过pdb定位到CHAIN_APPROX_SIMPLE算法在特定形态下压缩过度,遂改用CHAIN_APPROX_TC89_L1获得更精确轮廓。

5. 常见问题与实战排障手册:那些文档里不会写的血泪教训

5.1 典型问题速查表

现象根本原因解决方案实测耗时
启动黑屏,无任何窗口Win7系统缺少KB2533623补丁,导致VS2012运行时初始化失败安装微软补丁KB2533623(官网搜索编号下载)5分钟
摄像头画面卡在第一帧不动USB摄像头被其他程序(如QQ视频、Zoom)独占任务管理器结束所有explorer.exe外的视频相关进程,或拔插摄像头重置1分钟
挥拳时窗口右上角闪红字但无声音系统禁用了默认播放设备,或PlaySoundAPI被组策略屏蔽进入控制面板→声音→播放,设默认设备为“扬声器”;或注释掉playSound()调用,改用printf打印日志2分钟
ROI框内有大量白色噪点,持续触发环境光照过强(如正午阳光直射),导致帧差值普遍>50在代码第87行将THRESHOLD_DIFF临时改为50,或拉上窗帘降低照度30秒
挥拳动作明显但无响应用户距离摄像头过远(>2.5米),小臂在ROI内成像不足50px将ROI宽度roi_w从320增至400,或靠近摄像头至1.2-1.8米最佳距离1分钟

5.2 那些只有踩过才懂的隐藏技巧

  • “伪深度”增强法:当用户戴深色衣服(如黑T恤)导致手臂与背景对比度低时,单纯提高帧差阈值会引入噪声。我在某次展会演示中,临时在代码第75行cvtColor后插入:
    cpp // 对ROI区域做局部对比度拉伸,增强暗部细节 equalizeHist(gray, gray); // 单行解决,无需额外库
    这招让黑衣用户的检测成功率从42%跃升至91%,原理是CLAHE算法的轻量版替代。

  • 跨平台移植的平滑过渡:有用户问能否移植到树莓派。答案是肯定的,但需注意:OpenCV3.0的ARM版不支持MORPH_CLOSE的完整形态学核。我的方案是删掉第142行morphologyEx,改用两次dilate加两次erode模拟闭运算,代码量只增3行,性能损失可忽略。

  • 防止“连续挥拳”误判的冷却机制:原始代码挥拳后立即重置标志位,若用户快速连击,可能被识别为一次超长动作。我在第185行加入冷却锁:
    cpp static int64 last_punch_time = 0; if (punch_flag && (getTickCount() - last_punch_time) > 0.5 * getTickFrequency()) { // 仅当距上次挥拳超0.5秒才触发 printf("PUNCH!\n"); last_punch_time = getTickCount(); }
    这个0.5秒是人体生理极限——职业拳手最快直拳间隔也需0.3秒以上,设置0.5秒既防连击误判,又不影响正常交互节奏。

  • 终极调试神器:帧差热力图:按键盘'h'键(需自行在代码中添加),可将diff矩阵映射为伪彩色热力图(红=高差值,蓝=低差值)。这让我在发现某款摄像头存在固有坏点(固定位置持续高差值)后,仅用5行代码在absdiff后添加坏点掩膜,彻底解决顽固误报。这种现场即战力,是任何云端AI服务都无法提供的。

6. 应用场景延展与工程化思考:从demo到产品化落地

这个程序的价值,远不止于“能检测挥拳”。它是一套可复用的轻量级动作触发框架,其设计哲学对实际产品开发极具启发性。我在参与某医疗康复设备开发时,将本方案的核心逻辑迁移至嵌入式平台:用STM32+OV7670摄像头模组,移植test1.cpp的帧差+轮廓分析算法(C语言重写),内存占用压至48KB,功耗低于120mW。设备用于监测中风患者上肢康复训练动作完成度,医生通过平板查看“今日挥拳达标次数”,数据准确率99.2%(与临床评估一致)。关键在于,我们没追求“识别100种动作”,而是聚焦“挥拳”这一单一指标,用确定性算法保障医疗数据的可信度——这正是本项目最珍贵的遗产。

另一个案例是某智能家居公司的“无感开关”。他们原计划用毫米波雷达,成本高达$85/台。我们用本方案改造:将USB摄像头替换为广角红外摄像头($12),在test1.cpp中增加红外图像自适应白平衡(第68行插入cv::createCLAHE(2.0, Size(8,8))->apply(gray, gray)),成功实现黑暗环境下挥手开灯。整机BOM成本降至$23,且用户教育成本为零——老人看到摄像头就知道“对着它挥手就行”,无需学习APP操作。

这些落地经验指向一个共识:在资源受限、可靠性要求高的IoT与嵌入式场景中,“够用就好”的确定性算法,往往比“先进但脆弱”的AI模型更具生命力。本项目的test1.cpp,本质上是一个可执行的动作语义解析器——它把摄像头输入的原始像素流,翻译成“发生了挥拳”这一高层语义事件。这种从像素到语义的简洁映射,正是工业级边缘计算所渴求的范式。当你下次面对一个“需要动作触发”的需求时,不妨先问自己:这个问题,真的需要深度学习吗?还是说,一个精心设计的帧差阈值、一个合理的ROI区域、一组符合人体工学的运动判据,就足以优雅地解决?

我个人在实际使用中发现,最强大的功能从来不是代码本身,而是它赋予开发者的掌控感。你可以盯着每一帧的差值矩阵,理解为什么这一次触发了;可以修改一行参数,立刻看到行为改变;可以在30分钟内,把它变成拍手、抬手、甚至摇头检测。这种“所见即所得”的工程透明度,是任何黑盒模型都无法替代的底气。它不承诺万能,但承诺每一次挥拳,都被这个世界,稳稳地看见。

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

简介:直接双击就能用的挥拳动作检测工具,基于OpenCV3.0在Windows平台实现摄像头实时捕捉与识别。不依赖GPU、不需训练模型,用帧差法加轮廓分析判断手臂快速前伸特征,输出二值化挥拳判定结果。压缩包里包含完整VS2012工程(.sln和.vcxproj)、已编译好的test1.exe可执行文件,以及调试必需的.pdb和.ilk文件;所有逻辑集中在单个test1.cpp源码中,无第三方库依赖。支持调整检测区域(ROI)、灵敏度阈值,也方便改成拍手、抬手等其他简单动作触发逻辑。适合高校课程实验演示、健身互动原型开发、或嵌入式体感开关类轻量应用。


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

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

HC32F460 + FreeRTOS 三平台工程模板(Keil/IAR/GCC全支持)

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的HC32F460微控制器FreeRTOS开发模板&#xff0c;原生兼容Keil MDK、IAR EWARM和GNU GCC三大主流编译环境。工程采用分层架构设计&#xff1a;User目录存放用户应用逻辑&#xff0c;source集成标准…

作者头像 李华
网站建设 2026/6/12 11:01:51

2001-2024年上市公司供应链地理加权距离

上市公司供应链地理加权距离2001-2024该数据包含了 2001&#xff5e;2024 年中国 A 股上市公司的供应链地理加权距离指标&#xff0c;具体包括&#xff1a;Disw_s&#xff1a;供应商地理加权距离&#xff08;ln(1 Σ 距离 采购额占比)&#xff09;Disw_c&#xff1a;客户地理…

作者头像 李华