Lumenera单色相机raw 8bit帧转OpenCV Mat显示异常如何解决
问题原因&解决方案
你遇到的线条重影、图像重复问题核心是Mat构造时宽高参数顺序写反了,EmguCV的Mat构造函数第一个参数是图像高度,第二个才是宽度,顺序颠倒会导致内存数据的行解析完全错位。另外还有几个可优化的点可以避免额外问题:
必须修改的核心问题
修正Mat构造的宽高顺序,原代码的Mat构造逻辑参数完全颠倒:
// 原错误写法(宽在前,高在后) Result = new Mat(imf.Width / frameFormat.SubSampleX, imf.Height / frameFormat.SubSampleY, Emgu.CV.CvEnum.DepthType.Cv8U, 1, rawFrame, 0);
修改为:
int finalWidth = imf.Width / frameFormat.SubSampleX; int finalHeight = imf.Height / frameFormat.SubSampleY; // 正确顺序:高度在前,宽度在后,8bit单通道步长等于宽度 Result = new Mat(finalHeight, finalWidth, Emgu.CV.CvEnum.DepthType.Cv8U, 1, rawFrame, finalWidth);
其他可优化的问题
- 避免原地转换出错:你现在把同一个
rawFrame同时作为LucamConvertFrameToGreyscale8的输入和输出指针,部分版本的Lumenera SDK不支持原地转换,建议分开申请两块内存分别存原始Raw帧和转换后的灰度帧。 - 修复内存泄漏:你用
Marshal.AllocHGlobal申请的非托管内存默认不会被Mat自动释放,要么把数据拷贝到Mat的托管内存再释放非托管内存,要么自己实现Mat用完后的内存回收逻辑,示例如下:
// 转换完成后拷贝一份,再释放非托管内存避免泄漏 Mat cloneMat = Result.Clone(); Marshal.FreeHGlobal(rawFrame); return cloneMat;
- 如果后续要处理彩色帧,构造Mat时也需要注意宽高顺序,同时通道数对应设置为3,深度对应
Cv8U(24位RGB)/Cv16U(48位RGB)即可。
你已经确认SDK自带的存图接口正常,说明采集和转换流程没有问题,优先修改宽高顺序即可解决绝大多数显示错位问题。
内容的提问来源于stack exchange,提问作者wavepacket0
相关产品推荐
相关产品推荐

