Nikon相机SDK C#开发:单拍/连拍/视频流控制实战

简介:本资源是一套基于尼康官方SDK的C#与VB.NET相机控制开发套件,面向摄影自动化开发者、计算机视觉初学者及工业图像采集场景的技术人员,解决尼康相机通过桌面软件实现视频录制、连拍、单拍等远程精准控制的核心需求。压缩包共63个文件,含31个C#源码(如Nikon.cs、NikonTaskQueue.cs)、8个C#项目文件(.csproj)、6个VB.NET示例(含Form1.vb等)、5个资源文件(.resx)及2个关键DLL库,结构清晰分为bin(可执行/引用库)、src(核心封装代码)和多个功能演示项目(demo_video、demo_continuouscapture等),总大小仅295KB,轻量易集成。已有1334人学习下载,适合快速上手SDK调用逻辑、理解线程安全控制、复用图像采集任务队列设计,并直接迁移至WinForms或WPF应用开发。

1. Nikon相机SDK二次开发实战:C#桌面软件控制单拍/连拍/视频流,不依赖NIKON官方软件也能接管硬件

你有没有遇到过这种场景:在实验室做图像采集,需要定时触发Nikon单反或无反相机拍照,但每次都要手动点快门、切USB模式、等软件识别——更糟的是,NIKON官方的Camera Control Pro 2只支持有限机型,且不能嵌入到你的自动化流程里。这个资源就是为这类硬核需求准备的:它不是教程PDF,不是Demo截图,而是一套真实可运行的C#工程包,附带NIKON官方发布的Camera Control SDK(v2.x系列),含完整VS解决方案、已编译的.NET Framework 4.7.2可执行程序、以及VB.NET对照示例。它能绕过NIKON自家软件,直接通过USB HID协议与D850、Z6、Z7、D750等主流机型通信,实现毫秒级精准触发、自定义连拍间隔、实时H.264视频流拉取(非屏幕捕获)、RAW/JPEG双格式保存控制。适合做机器视觉标定、工业检测流水线触发、科研图像序列采集的工程师,也适合想把相机变成“网络摄像头+精密执行器”的嵌入式开发者。别被“SDK”二字吓住——它没用COM注册黑盒,不依赖ActiveX,所有接口都封装成干净的C#类,连VB示例都帮你写好了调用链。


2. SDK环境搭建与设备握手:从驱动安装到GetCameraList()成功返回

2.1 硬件连接与驱动就绪:USB模式选择是第一道关卡

Nikon相机不是插上USB线就能被SDK识别的“即插即用设备”。必须将相机设置为MTP(Media Transfer Protocol)模式,而非PTP(Picture Transfer Protocol)或普通充电模式。这是最常翻车的第一步:很多开发者插上线后调用CameraControl.GetCameraList()始终返回空数组,查遍日志也没报错——问题就出在相机屏幕上的那个小菜单。操作路径:相机菜单 → 设置 → USB连接 → 选“MTP(存储+控制)”。注意:Z系列无反需在“USB选择”中选“PC连接”,再进子菜单确认MTP;D系列单反则在“USB”选项下直接选MTP。> 提示:部分旧款D7000/D5100需升级固件至最新版才支持MTP下的SDK控制,低于固件号1.03的版本会静默失败。

2.2 SDK部署与.NET项目引用:避开x86/x64平台陷阱

下载的SDK压缩包内含NikonCameraControl.dll(核心COM组件)、NikonCameraControlLib.dll(.NET封装层)、NikonCameraControl.tlb(类型库)及文档。关键动作有三步:

  1. 将NikonCameraControl.dll复制到你的C#项目bin\Debug目录(非GAC注册,避免权限问题);
  2. 在Visual Studio中右键引用 → “添加引用” → 浏览到NikonCameraControlLib.dll;
  3. 必须将项目平台目标设为x86(即使你在64位Windows上开发)。因为Nikon SDK底层是32位COM组件,若设为AnyCPU或x64,运行时会抛出System.Runtime.InteropServices.COMException (0x80040154): 类未注册。
// 正确初始化示例(放在窗体Load事件或按钮Click中) private void InitializeCamera() { try { // 初始化SDK管理器(单例) CameraControl.Initialize(); // 获取已连接相机列表(关键验证点) var cameraList = CameraControl.GetCameraList(); if (cameraList.Length == 0) { MessageBox.Show("未检测到MTP模式的Nikon相机,请检查USB连接和相机设置"); return; } // 连接第一台(通常索引0) _currentCamera = cameraList[0]; _currentCamera.Connect(); MessageBox.Show($"已连接:{_currentCamera.ModelName} (序列号: {_currentCamera.SerialNumber})"); } catch (Exception ex) { MessageBox.Show($"初始化失败:{ex.Message}"); } }

这段代码的逻辑链很清晰:先Initialize()加载COM环境,再GetCameraList()探测物理设备,最后Connect()建立会话。参数说明:GetCameraList()返回ICamera[]数组,每个元素包含ModelName、SerialNumber、FirmwareVersion等只读属性,是判断设备兼容性的第一手依据。我一般会在连接前加一句Console.WriteLine($"SDK版本: {CameraControl.Version}");,确保你用的不是2012年的老SDK。

2.3 设备能力查询:为什么Z9能连拍而D3500只能单拍?

不是所有Nikon相机都支持全部功能。SDK提供ICamera.Capabilities属性,返回一个CameraCapabilities结构体,里面明确标注了该机型是否支持LiveView、ContinuousShooting、VideoRecording等。例如:

能力项D850Z6 IID3500Z9
CanTakePicture✅✅✅✅
CanStartLiveView✅✅❌✅
CanStartVideoRecording✅✅❌✅
CanStartContinuousShooting✅✅❌✅

注意:CanStartContinuousShooting为false不意味着完全不能连拍——你可以用循环调用TakePicture()模拟,但无法使用相机原生的高速缓存连拍(如Z9的120fps),延迟和稳定性差一个数量级。实际开发中,我习惯在连接后立即检查_currentCamera.Capabilities.CanStartLiveView,若为false则禁用视频相关UI控件,避免用户误点报错。


3. 核心功能实现:单拍、连拍、视频流的C#代码落地

3.1 单次拍摄:同步阻塞 vs 异步回调的取舍

最简单的TakePicture()方法是同步阻塞的:调用后线程挂起,直到相机完成对焦、曝光、写入存储卡并返回结果。这对UI线程很危险——如果相机卡在对焦上,整个软件会假死。生产环境必须用异步模式:

// 推荐:异步拍摄(避免UI冻结) private async void btnTakeSingle_Click(object sender, EventArgs e) { try { // 启动异步任务,超时10秒 var task = Task.Run(() => _currentCamera.TakePicture()); await Task.WhenAny(task, Task.Delay(10000)); // 10秒超时 if (task.IsCompleted) { var result = task.Result; // IPhotoResult对象 Console.WriteLine($"单拍完成:{result.FileName}, RAW:{result.IsRaw}, Size:{result.FileSize}"); // 触发后续处理:缩略图生成、MD5校验、上传等 } else { MessageBox.Show("拍摄超时,请检查相机状态"); } } catch (Exception ex) { MessageBox.Show($"单拍异常:{ex.Message}"); } }

参数说明:TakePicture()返回IPhotoResult,含FileName(相机侧生成的文件名,如DSC_0001.NEF)、FileSize(字节)、IsRaw(是否为NEF格式)等。关键点在于Task.Run包装——它把COM调用扔进线程池,避免阻塞主线程。我一般会把超时时间设为8~12秒,覆盖D850在弱光下AF-S对焦的最坏情况。

3.2 连续拍摄控制:用Timer模拟vs SDK原生连拍

SDK提供StartContinuousShooting()和StopContinuousShooting(),但仅限支持该能力的机型(见上表)。对Z6/Z7/Z9,这是最优解;对D850,必须自己控节奏:

// D850兼容的连拍模拟(每500ms触发一次) private System.Windows.Forms.Timer _burstTimer; private int _burstCount = 0; private const int BURST_MAX = 10; private void StartBurstMode() { _burstCount = 0; _burstTimer = new System.Windows.Forms.Timer(); _burstTimer.Interval = 500; // 间隔500ms _burstTimer.Tick += (s, e) => { if (_burstCount < BURST_MAX) { _currentCamera.TakePicture(); // 同步调用,因在Timer线程中 _burstCount++; } else { _burstTimer.Stop(); _burstTimer.Dispose(); } }; _burstTimer.Start(); }

这里用WinForms Timer而非System.Threading.Timer,是因为前者保证Tick事件在UI线程执行,避免跨线程调用COM组件的InvalidCastException。血泪经验:曾用Task.Delay循环调用,结果在第3次TakePicture()时崩溃——COM对象上下文切换失败。Timer是更稳妥的选择。

3.3 实时视频流:从LiveView到Bitmap的零拷贝转换

LiveView不是简单“打开预览窗口”,而是持续拉取YUV422帧数据流。SDK的StartLiveView()返回ILiveView接口,其FrameReady事件每33ms(30fps)触发一次,传入ILiveViewFrame对象:

private ILiveView _liveView; private Bitmap _liveBitmap; private void StartLiveView() { _liveView = _currentCamera.StartLiveView(); _liveView.FrameReady += LiveView_FrameReady; } private void LiveView_FrameReady(object sender, LiveViewFrameEventArgs e) { // e.Frame.Data 是byte[],格式为YUY2(YUV422) // 直接转Bitmap(避免内存拷贝) if (_liveBitmap == null || _liveBitmap.Width != e.Frame.Width || _liveBitmap.Height != e.Frame.Height) { _liveBitmap = new Bitmap(e.Frame.Width, e.Frame.Height, PixelFormat.Format24bppRgb); } // YUY2 to RGB24 转换(简化版,实际用unsafe指针加速) ConvertYUY2ToRGB24(e.Frame.Data, _liveBitmap, e.Frame.Width, e.Frame.Height); // 更新PictureBox(假设picLiveView是WinForms控件) if (picLiveView.InvokeRequired) picLiveView.Invoke((MethodInvoker)(() => picLiveView.Image = _liveBitmap)); else picLiveView.Image = _liveBitmap; }

参数说明:e.Frame.Width/Height通常是1280×720(Z系列)或640×480(D系列),e.Frame.Data.Length = Width × Height × 2(YUY2每像素2字节)。ConvertYUY2ToRGB24函数需自行实现,核心是YUY2采样规则:每4字节(Y0,U,Y1,V)生成2个RGB像素。我一般用unsafe块+指针运算,比Marshal.Copy快3倍。注意:FrameReady事件在非UI线程触发,PictureBox.Image赋值必须Invoke,否则抛InvalidOperationException。


4. 避坑指南:五个让开发者抓狂的真实问题与解法

4.1 现象:GetCameraList()返回空数组,设备管理器显示“Nikon Camera”正常

原因:Windows 10/11默认启用“快速启动”,导致USB设备在休眠唤醒后丢失MTP会话状态;或相机USB线接触不良(尤其第三方线缆供电不足)。
解决:① 关闭快速启动:控制面板 → 电源选项 → 选择电源按钮的功能 → 更改当前不可用设置 → 取消勾选“启用快速启动”;② 换原装USB线,或使用带独立供电的USB集线器;③ 拔插相机USB线后,在设备管理器中右键“Nikon Camera” → “卸载设备”,再重插。

4.2 现象:TakePicture()抛出HRESULT:0x80070005 (拒绝访问)

原因:Windows Defender或第三方杀软拦截了COM组件调用;或相机正在被其他进程占用(如NIKON Transfer 2、Windows照片应用自动导入)。
解决:① 临时关闭实时防护(测试用);② 任务管理器结束所有Nikon*、Transfer*进程;③ 在代码中增加占用检测:if (_currentCamera.IsBusy) { MessageBox.Show("相机正忙"); return; }。

4.3 现象:LiveView画面卡顿、掉帧严重(<10fps)

原因:FrameReady事件处理函数内做了耗时操作(如Bitmap.Save()、File.WriteAllText());或PictureBox启用了双缓冲但未优化。
解决:①FrameReady内只做内存拷贝和Invoke,所有IO操作移至单独线程;②PictureBox设置DoubleBuffered = true(需反射设置,WinForms默认不开启);③ 降低LiveView分辨率:调用_currentCamera.LiveViewSize = LiveViewSize.Small;(Z系列支持Small/Medium/Large)。

4.4 现象:连拍时相机突然停止响应,IsBusy始终为true

原因:D系列单反缓存满后需等待写入SD卡,SDK未暴露缓存状态;或连续调用TakePicture()未加间隔,触发相机保护机制。
解决:① 对D850/D750等机型,连拍间隔设为≥800ms;② 在TakePicture()后加Thread.Sleep(100)(粗暴但有效);③ 监听ICamera.CameraStatusChanged事件,当Status == CameraStatus.Ready时再触发下一张。

4.5 现象:VB.NET示例编译报错“类型‘ICamera’未定义”

原因:VB项目未正确引用NikonCameraControlLib.dll,或未在文件顶部添加Imports NikonCameraControlLib。
解决:① VB项目属性 → “引用” → 确认NikonCameraControlLib状态为“已启用”;② 在.vb文件首行添加Imports NikonCameraControlLib;③ 若仍报错,右键引用 → “属性” → 将“嵌入互操作类型”设为False(默认True会导致类型丢失)。


5. 进阶技巧:自定义参数配置、错误恢复与多机协同

5.1 相机参数精细控制:绕过Auto,直写ExposureCompensation与ISO

SDK提供ICamera.Settings属性,暴露ExposureCompensation(-5.0~+5.0,步进1/3EV)、IsoSensitivity(如IsoSensitivity._200)、ShutterSpeed(ShutterSpeed._1_125)等枚举。但要注意:某些参数组合会冲突(如手动ISO + Auto Shutter),相机可能静默忽略。安全写法是分步设置并验证:

// 安全设置曝光参数(先设ISO,再设快门,最后补偿) private void SetExposureSafe(double isoValue, string shutterStr, double compValue) { try { // 1. 先设ISO(基础感光度) _currentCamera.Settings.IsoSensitivity = GetIsoEnum(isoValue); // 自定义映射函数 // 2. 再设快门(避免ISO未生效时快门无效) _currentCamera.Settings.ShutterSpeed = GetShutterEnum(shutterStr); // 3. 最后设补偿(影响最终曝光量) _currentCamera.Settings.ExposureCompensation = compValue; // 4. 主动读回验证(关键!) var actualIso = _currentCamera.Settings.IsoSensitivity; var actualShutter = _currentCamera.Settings.ShutterSpeed; Console.WriteLine($"设置完成:ISO={actualIso}, 快门={actualShutter}"); } catch (Exception ex) { Console.WriteLine($"参数设置失败:{ex.Message}"); } } private IsoSensitivity GetIsoEnum(double value) { // 映射ISO数值到SDK枚举(示例) return value switch { 100 => IsoSensitivity._100, 200 => IsoSensitivity._200, 400 => IsoSensitivity._400, 800 => IsoSensitivity._800, _ => IsoSensitivity.Auto }; }

参数说明:GetIsoEnum和GetShutterEnum是必须自己写的映射函数,因为SDK枚举名(如_200、_1_125)不直接对应数值。验证步骤第4步极其重要——我曾因跳过这步,在Z6上设ISO 1600却实际生效为Auto,导致整批图像曝光不一致。

5.2 断连自动恢复:从“相机拔掉就崩”到“热插拔无缝续拍”

生产环境必须处理USB意外断开。SDK的ICamera.Disconnected事件可捕获,但恢复连接需重新初始化:

private void SetupReconnect() { _currentCamera.Disconnected += (s, e) => { Console.WriteLine("相机已断开,启动重连..."); _reconnectTimer = new Timer { Interval = 2000 }; // 2秒后重试 _reconnectTimer.Tick += ReconnectAttempt; _reconnectTimer.Start(); }; } private void ReconnectAttempt(object sender, EventArgs e) { try { // 重新获取设备列表 var list = CameraControl.GetCameraList(); if (list.Length > 0 && list[0].SerialNumber == _currentCamera.SerialNumber) { _currentCamera = list[0]; _currentCamera.Connect(); Console.WriteLine("重连成功!"); _reconnectTimer.Stop(); _reconnectTimer.Dispose(); // 恢复LiveView或连拍状态 if (_isLiveViewRunning) StartLiveView(); } } catch { // 继续重试 } }

这里用Timer而非Task.Delay,是因为Disconnected事件在COM线程触发,await Task.Delay可能导致上下文丢失。SerialNumber比ModelName更可靠,避免同型号多机时混淆。

5.3 多相机协同:用SerialNumber做唯一标识,避免设备错乱

当同时连接Z6和D850时,GetCameraList()[0]不总是Z6——顺序取决于USB端口枚举顺序。必须用序列号绑定:

// 启动时扫描并缓存设备 private Dictionary<string, ICamera> _cameras = new(); private void ScanCameras() { var list = CameraControl.GetCameraList(); foreach (var cam in list) { _cameras[cam.SerialNumber] = cam; // 键为序列号 } } // 控制指定相机(如Z6序列号以"Z6-"开头) private ICamera GetCameraByModel(string modelPrefix) { return _cameras.FirstOrDefault(x => x.Key.StartsWith(modelPrefix)).Value; } // 示例:Z6负责视频,D850负责连拍 var z6 = GetCameraByModel("Z6-"); var d850 = GetCameraByModel("D850-"); z6?.StartLiveView(); d850?.StartContinuousShooting();

表格:多机协同关键字段对比

字段是否唯一是否稳定适用场景
SerialNumber✅ 全局唯一✅ 插拔不变设备绑定、日志追踪
ModelName❌ 同型号重复✅UI显示、功能判断
Index(数组下标)❌ 动态变化❌仅用于首次枚举

从那以后我每次初始化相机管理器,都强制走一遍ScanCameras()+SerialNumber字典缓存,再配合Disconnected事件更新字典。这套逻辑在某高校的显微镜多相机同步采集系统里跑了三年,没出过一次设备错绑。希望帮到你。

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

相关新闻

SpringBoot+Vue+MyBatis企业级网络教学系统源码全解析

SpringBoot+Vue+MyBatis企业级网络教学系统源码全解析

1. 这到底是一套什么系统&#xff1a;先读懂业务模型再谈技术拿到这套标题里写着“企业级大学生计算机基础网络教学系统管理系统源码&#xff5c;SpringBootVueMyBatis架构MySQL数据库【完整版】”的项目时&#xff0c;我建议你不要急着点运行&#xff0c;先坐下来把业务模型盘…

2026/10/20 10:20:02 阅读更多 →
AI协同开发STM32:从需求到烧录的五个阶段与踩坑实录

AI协同开发STM32:从需求到烧录的五个阶段与踩坑实录

1. 为什么嵌入式开发突然开始聊"AI协同"前阵子跟几个做嵌入式的老伙计吃饭&#xff0c;聊到一个挺有意思的现象&#xff1a;以前大家聚在一起&#xff0c;话题基本绕不开"你用的哪家IDE""寄存器手册翻到第几页了""这个中断优先级怎么又配错…

2026/10/20 10:20:02 阅读更多 →
ESP32-C3 Super Mini连不上WiFi?六大原因与排查流程

ESP32-C3 Super Mini连不上WiFi?六大原因与排查流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:19:01 阅读更多 →

最新新闻

零基础入门SuperGlue-pytorch:图像特征匹配实战指南

零基础入门SuperGlue-pytorch:图像特征匹配实战指南

简介&#xff1a;这份资源是 SuperGlue 的 PyTorch 实现与配套培训材料&#xff0c;面向已掌握 Python 与深度学习基础、希望深入图像特征匹配与位姿估计的开发者与研究者。它基于官方超点实现&#xff0c;重点解决了训练 batchsize 受限、损失计算缓慢等痛点&#xff0c;支持 …

2026/10/20 13:31:30 阅读更多 →
从rea到React、实时管道与推理引擎:三条技术线拆解

从rea到React、实时管道与推理引擎:三条技术线拆解

1. 当标题只剩下三个字母&#xff1a;一次关于“rea”的逆向拆解拿到“rea”这个标题的时候&#xff0c;我第一反应是&#xff1a;这要么是个缩写&#xff0c;要么是个半截词&#xff0c;要么就是某个内部项目的代号。正文空白、关键词空白、摘要空白&#xff0c;连热搜词和网络…

2026/10/20 13:31:30 阅读更多 →
PyTorch实战避坑指南:从动态图、张量到混合精度与显存优化

PyTorch实战避坑指南:从动态图、张量到混合精度与显存优化

1. 为什么“PyTorch”这个标题值得单独拎出来聊如果你在技术社区里闲逛&#xff0c;看到有人只甩出“pytorch”这六个字母当标题&#xff0c;底下大概率会分成两拨人&#xff1a;一拨觉得这有啥好聊的&#xff0c;装个库跑个import torch就完事了&#xff1b;另一拨则会心一笑&…

2026/10/20 13:31:30 阅读更多 →
bilibot 快速上手指南:三步跑通用B站评论微调的本地聊天机器人

bilibot 快速上手指南:三步跑通用B站评论微调的本地聊天机器人

bilibot 快速上手指南&#xff1a;三步跑通用B站评论微调的本地聊天机器人 【免费下载链接】bilibot A local chatbot fine-tuned by bilibili user comments. 项目地址: https://gitcode.com/GitHub_Trending/bi/bilibot bilibot 是一个能跑在你自己电脑上的本地聊天机…

2026/10/20 13:31:30 阅读更多 →
iOS 上的 Minecraft Java 版怎么跑:PojavLauncher 免费完整上手攻略

iOS 上的 Minecraft Java 版怎么跑:PojavLauncher 免费完整上手攻略

iOS 上的 Minecraft Java 版怎么跑&#xff1a;PojavLauncher 免费完整上手攻略 【免费下载链接】PojavLauncher_iOS A Minecraft: Java Edition Launcher for Android and iOS based on Boardwalk. Succeeded by https://github.com/AngelAuraMC/Amethyst-iOS 项目地址: htt…

2026/10/20 13:31:30 阅读更多 →
汇川电脑版示教器软件部署指南:环境配置与连接排错

汇川电脑版示教器软件部署指南:环境配置与连接排错

简介&#xff1a;汇川机器人电脑版示教器软件是面向工业自动化工程师、产线调试人员及机器人应用开发者的专业级PC端编程与调试工具&#xff0c;用于替代传统手持示教器&#xff0c;实现远程控制、离线仿真、示教点管理与故障诊断&#xff0c;显著提升产线部署与维护效率。资源…

2026/10/20 13:30:26 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →