WinForm使用Python.Net调用Yolov8将图像显示在pictureBox控件上.
前面就是Yolov8常见的目标识别代码, 由于跟业务有关太多就不贴出来了. 主要就是下面这部分,
cv2.VideoCapture(video_path);
dynamic result = cap.read();
bool success = (bool)result[0];
dynamic frame = result[1];
// 对当前帧进行目标检测
dynamic results = model.track(frame, persist: true);
// 可视化检测结果,调整边框宽度和文字大小
dynamic annotated_frame = results[0].plot(line_width: 1, font_size: 0.5, conf: false, labels: false);
int width = annotated_frame.shape[1]; int height = annotated_frame.shape[0]; // 获取数组内存信息 这种做法只需要0-1ms处理一帧 dynamic arrayInterface = annotated_frame.__array_interface__;//numpy自带属性 dynamic data_info = arrayInterface["data"]; long address = (long)data_info[0]; // 将 Python int 转换为 long IntPtr ptr = new IntPtr(address); int stride = width * 3; // 24bpp RGB format byte[] imageData = new byte[height * stride]; System.Runtime.InteropServices.Marshal.Copy(ptr, imageData, 0, imageData.Length); var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var bitmapData = bitmap.LockBits( new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb ); System.Runtime.InteropServices.Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length); bitmap.UnlockBits(bitmapData); st.Stop(); var trasfer = st.ElapsedMilliseconds + "ms"; st.Restart(); UpdateUIOnNewThread(bitmap); st.Stop(); var update = st.ElapsedMilliseconds + "ms"; /* 0: 640x384 106 cans, 47.3ms Speed: 1.6ms preprocess, 47.3ms inference, 1.4ms postprocess per image at shape (1, 3, 640, 384) 1ms 0ms */
// 在非UI线程中调用此方法更新UI private void UpdateUIOnNewThread(Bitmap bitmap) { if (this.InvokeRequired) { // 如果当前线程不是UI线程,使用Invoke将操作封送到UI线程 this.Invoke(new Action(() => { // 这里可以安全地操作UI控件 pictureBox1.Image = bitmap; })); } else { // 如果已经在UI线程中,直接执行 pictureBox1.Image = bitmap; } }