如何将C++实现的面阵视频生成线扫图像代码转换为C#版本?
线扫图像生成核心逻辑 C#/EmguCV 实现
前置依赖
- 项目需安装EmguCV相关Nuget包
- 需引用以下命名空间:
using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Structure; using System.Drawing;
成员变量定义
对应原C++代码的全局状态变量,可直接放在窗体类中作为成员:
// 可根据你的需求调整帧尺寸参数 private const int FrameWidth = 640; private const int FrameHeight = 480; // 存储线扫生成的结果图像 private Mat _lineImage = new Mat(new Size(FrameWidth, FrameHeight), DepthType.Cv8U, 3); // 拼接展示用图像:左半部分为原视频帧,右半部分为线扫结果 private Mat _combinedImage = new Mat(new Size(FrameWidth * 2, FrameHeight), DepthType.Cv8U, 3); // 帧计数 private long _frameCount = 0; // 线扫竖线的X坐标,可替换为你在PictureBox上绘制的竖线实际位置 private int ScanLineX => FrameWidth / 2;
每帧核心处理代码
你可以在视频帧读取回调中调用该方法,传入当前读取到的视频帧即可:
/// <summary> /// 单帧处理核心逻辑 /// </summary> /// <param name="image">当前读取到的视频帧</param> public void ProcessFrame(Mat image) { // 可选:非摄像头流统一缩放到预设尺寸,对应原C++的resize逻辑 // CvInvoke.Resize(image, image, new Size(FrameWidth, FrameHeight)); // 在当前帧上绘制扫描指示线 CvInvoke.Line(image, new Point(ScanLineX + 1, 0), new Point(ScanLineX + 1, FrameHeight - 1), new Bgr(Color.FromArgb(255, 0, 128)).MCvScalar, 1); // 线扫图像拼接核心逻辑 if (_frameCount >= _lineImage.Cols) { // 线扫图像已满,整体左移一列腾出末尾空间 using var srcRange = _lineImage.GetColRange(1, _lineImage.Cols - 1); using var dstRange = _lineImage.GetColRange(0, _lineImage.Cols - 2); srcRange.CopyTo(dstRange); // 将当前帧扫描线的列写入线扫图像最后一列 using var currentCol = image.GetCol(ScanLineX); using var lastCol = _lineImage.GetCol(_lineImage.Cols - 2); currentCol.CopyTo(lastCol); } else { // 线扫图像未满,直接写入对应位置 using var currentCol = image.GetCol(ScanLineX); using var targetCol = _lineImage.GetCol((int)_frameCount); currentCol.CopyTo(targetCol); } // 可选:拼接原帧和线扫结果用于展示,不需要可删除 using var originalRange = image.GetColRange(0, image.Cols - 1); using var combinedLeftRange = _combinedImage.GetColRange(0, image.Cols - 1); originalRange.CopyTo(combinedLeftRange); using var lineRange = _lineImage.GetColRange(0, image.Cols - 1); using var combinedRightRange = _combinedImage.GetColRange(image.Cols, _combinedImage.Cols - 1); lineRange.CopyTo(combinedRightRange); _frameCount++; // 可选:保存当前拼接图,对应原C++注释的imwrite逻辑 // CvInvoke.Imwrite($"{_frameCount.ToString().PadLeft(4, '0')}.jpg", _combinedImage); }
注意事项
- 临时Mat对象用
using包裹可自动释放非托管资源,避免内存泄漏 - 处理完成的
_lineImage和_combinedImage可调用ToBitmap()方法转成Bitmap对象,直接赋值给Winform PictureBox控件展示
内容的提问来源于stack exchange,提问作者user3177511
相关产品推荐
相关产品推荐

