openCV.imwrite写入无效/失败/无反应问题;ping常见故障传输失败问题

本文分享了在使用OpenCV的imwrite方法保存图片时遇到的问题及解决方案,并介绍了在网络配置中如何正确设置静态IP以避免Ping不通的情况。

最近在修电脑过程中又发现了两个小问题,在网上搜索并没有快速找到有效的解决方案,于是自己探索了一下,简单分享,希望有用。

问题一
openCV在使用imwrite方法保存图片时,我想将时间插到文件名中,但每次都没有生成文件,也没有报错,最终发现是保存路径参数中包含特殊符号“:”,这是一个坑,其他特殊符号一定要注意。

问题二
两台电脑在组内网时发现静态IP ping不通,报错“常见故障,传输失败”,网上一搜一堆,都说得很全面,但我觉得第一个排查的应该是本机静态IP有没有配置错误,我ping的居然是本机IP,而且两台电脑都是配的同一个静态IP地址,所以报了那个错,改过来就ping通了。

以下是一个用C#编写的winforms窗体程序,其主要功能在于产品的logo和条形码检测,我会分文件发送代码段给你,请详细给出代码的解释: MainForm.cs:/** * 依赖: VS2017~、.net sdk 4.6.2、DevExpress21.2.7 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Windows.Forms; using System.Threading; using System.Threading.Tasks; using OpenCvSharp; using OpenCvSharp.Extensions; using AForge.Video; using ChenaoboSharpLib; using Timer = System.Windows.Forms.Timer; using System.Linq; namespace LogoTest { public partial class MainForm : Form { private readonly SystemInfoProvider _systemInfoProvider = new SystemInfoProvider(); // 系统信息 private readonly JsonConfigManager _cfgManager = new JsonConfigManager("config.json"); // 配置文件 private readonly Timer _systemTimer = new Timer() { Interval = 1000 }; // 每秒更新一次时间 private TplinkMvCamera _mvCamera; // 工业相机用作logo检测 private UvcCamera _uvcCamera = new UvcCamera(); // USB摄像头用作SN扫码 private List<string> _selectedLabels; // 选择的要识别的logo类型 private List<string> _detectedDistinctLabels; // 存放检测到的logo类别名称 private Dictionary<int, string> _modelLabelId_to_logoName; // 中英文映射 private string _modelName; // 模型名称 private Yolo11OpenVino _detector1; // 目标检测器 private BarcodeDecoder _barCodeDetector = new BarcodeDecoder(); // 条形码检测器 private string oldSN = "0000000000000"; // 上一次的SN private volatile bool _snDecoding = false; // SN解码中标志 private float reTestDelay = 0; // 自动重测延时 private volatile int reTestTimes = 0; // 重测次数 private readonly TTS _tts = new TTS(100, 100); // 文本转语音 private SerialPortTransceiver _serialPortTransceiver; // 串口收发器 private string _comNum = null; // 串口号 private readonly List<CommonLib.Log.LogType> logs = new List<CommonLib.Log.LogType>(); // 日志 private readonly int logMaxCount = 1000; // 日志长度 // 构造函数 public MainForm() { // 初始化UI InitializeComponent(); // 设定UI初始状态(和在设计器中设置效果是一样的) barButtonItemAutoGainAndExposure.Enabled = false; barEditItemGain.Enabled = false; barEditItemExposure.Enabled = false; // 注册回调 Load += new EventHandler(MainForm_Load); // 窗口加载 FormClosing += new FormClosingEventHandler(MainForm_FormClosing); // 串口关闭 PictureBox_Preview.DoubleClick += PictureBox_DoubleClick; PictureBox_Result.DoubleClick += PictureBox_DoubleClick; pictureBoxUsb.DoubleClick += PictureBox_DoubleClick; barEditRetestTime.EditValueChanged += change_retestTime; barEditItemGain.EditValueChanged += ChangeMvCameraCfg; barEditItemExposure.EditValueChanged += ChangeMvCameraCfg; // 定时器回调 _systemTimer.Tick += SystemTimer_Tick; } // 系统定时器回调1,每1s进入一次,显示时间 private void SystemTimer_Tick(object sender, EventArgs e) { base.Invoke(new Action(delegate //UI线程 { labelRealTime.Text = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"; labelCpuLoad.Text = $"CPU: {_systemInfoProvider.GetCpuUsage():F1}%"; labelRamLoad.Text = $"RAM: {_systemInfoProvider.GetRamUsageDetails()}"; })); } // 加载assets中的模型到下拉列表 private void LoadModels() { comboxModels.Items.Clear();//清空 // 加载模型文件名称到下拉列表 string assetsFolderPath = Path.Combine(Application.StartupPath, "assets"); if (Directory.Exists(assetsFolderPath)) { string[] xmlFiles = Directory.GetFiles(assetsFolderPath, "*.xml"); foreach (string file in xmlFiles) { comboxModels.Items.Add(Path.GetFileName(file)); } } else { WinFormsUtils.ShowTipDialog("assets文件夹不存在! 请联系管理员"); return; } } // 窗口加载回调 private void MainForm_Load(object sender, EventArgs e) { Text = "LogoTest —— 吸顶AP上盖Logo检测工具 V1.0.5"; labelCpuModel.Text = _systemInfoProvider.GetCpuModel(); //获取cpu型号 labelCpuLoad.Text = $"CPU: {_systemInfoProvider.GetCpuUsage():F1}%"; labelRamLoad.Text = $"RAM: {_systemInfoProvider.GetRamUsageDetails()}"; gridControl1.DataSource = logs; // 日志数据源 // 显示串口列表 repositoryItemComboBox5.Items.Clear(); string[] coms = System.IO.Ports.SerialPort.GetPortNames(); foreach (var item in coms) { repositoryItemComboBox5.Items.Add(item); } LoadModels(); //加载模型列表 // logo选项及其预览图片 var dict = new Dictionary<string, string>(); var imageFiles = Directory.GetFiles("assets") .Where(f => Path.GetExtension(f).Equals(".png", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(f).Equals(".jpg", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(f).Equals(".jpeg", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(f).Equals(".bmp", StringComparison.OrdinalIgnoreCase)) .ToArray(); foreach (var file in imageFiles) { var fileName = Path.GetFileName(file); // 获取文件名(含扩展名) var key = Path.GetFileNameWithoutExtension(file); // 移除扩展名,作为字典键 if (!string.IsNullOrEmpty(key)) { dict[key] = "assets\\" + fileName; } } new WinFormsUtils.CheckListBoxWithImagePreview(checkedListBox1, dict); // 模型label与logo选项名称的对应关系(模型的label为英文) _modelLabelId_to_logoName = new Dictionary<int, string>(); _modelLabelId_to_logoName.Add(0, "TP-LINK"); _modelLabelId_to_logoName.Add(1, "中国电信"); _modelLabelId_to_logoName.Add(2, "TP-LINK凹印"); _modelLabelId_to_logoName.Add(3, "ChinaMobile"); _modelLabelId_to_logoName.Add(4, "域联"); _modelLabelId_to_logoName.Add(5, "MERCURY"); //加载配置 if (_cfgManager.KeyExists("modelName")) barEditItemSelectModel.EditValue = _cfgManager.GetValue<string>("modelName"); if (_cfgManager.KeyExists("comNum")) barEditItem3.EditValue = _cfgManager.GetValue<string>("comNum"); if (_cfgManager.KeyExists("reTestGap")) barEditRetestTime.EditValue = _cfgManager.GetValue<string>("reTestGap"); if (_cfgManager.KeyExists("selectLogos")) { var selectedLogs = new List<string>(); selectedLogs = _cfgManager.GetValue<List<string>>("selectLogos"); foreach (string log in selectedLogs) { for (int i = 0; i < checkedListBox1.Items.Count; i++) { if (log == checkedListBox1.Items[i].ToString()) { checkedListBox1.SetItemChecked(i, true); } } } } // 开启系统定时器 _systemTimer.Start(); } //点击开始 private void BarButtonItem_Start_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { reTestDelay = Convert.ToSingle(barEditRetestTime.EditValue); reTestTimes = 0; if (checkedListBox1.CheckedItems.Count < 1)//已选logo类型数量 { WinFormsUtils.ShowTipDialog("请先选择logo元素"); return; } _selectedLabels = new List<string>(); foreach (var item in checkedListBox1.CheckedItems) { _selectedLabels.Add(item.ToString()); } if (barCheckItem_com.Checked) { _comNum = barEditItem3.EditValue as string; if (_comNum == null) { WinFormsUtils.ShowTipDialog("开启了串口输出,但是未选择串口"); return; } } _serialPortTransceiver = new SerialPortTransceiver(_comNum);//串口发送SN 波特率9600 _serialPortTransceiver.Open(); if (barEditItemSelectModel.EditValue == null) { WinFormsUtils.ShowTipDialog("未选择AI模型"); return; } _modelName = $"{barEditItemSelectModel.EditValue}"; Trace.WriteLine(">>>初始化条码解码器"); _barCodeDetector = new BarcodeDecoder(barCheckItemTryHarder.Checked); Thread.Sleep(100); // 不加延时会概率性不解码 Trace.WriteLine(">>>初始化工业相机"); _mvCamera = new TplinkMvCamera("TPLINK_MV_CAMERA_SDK"); if (!_mvCamera.ListCamera()) return; if (!_mvCamera.ConnectCameraAndStart()) return; _mvCamera.PictureboxPreview(PictureBox_Preview, 20); //预览 barButtonItemAutoGainAndExposure_ItemClick(null, null); try { Trace.WriteLine(">>>初始化USB相机"); _uvcCamera = new UvcCamera();//USB摄像头用作SN检测 _uvcCamera.Connect(0); _uvcCamera.FrameCaptured += UsbCamera_ImageGrabbed; } catch (Exception error) { WinFormsUtils.ShowTipDialog(error.ToString()); } _detector1 = new Yolo11OpenVino($"assets\\{_modelName}", 0.7f, 0.5f); //UI SwitchUI(true); //创建目录 if (!Directory.Exists("results")) { Directory.CreateDirectory("results"); } // 保存配置 _cfgManager.SetValue("modelName", barEditItemSelectModel.EditValue.ToString()); _cfgManager.SetValue("comNum", barEditItem3.EditValue.ToString()); _cfgManager.SetValue("reTestGap", barEditRetestTime.EditValue.ToString()); _cfgManager.SetValue("selectLogos", _selectedLabels); } //修改相机参数 private void ChangeMvCameraCfg(object sender, EventArgs e) { var edit = sender as DevExpress.XtraBars.BarEditItem; if (edit != null) { var value = Convert.ToDouble(edit.EditValue); switch (edit.Name) { case "barEditItemGain": _mvCamera.ChangeGain((float)value); break; case "barEditItemExposure": _mvCamera.ChangeExposureTime((float)value * 1000); //ms转us break; } } } //UI切换 private void SwitchUI(bool startClicked) { base.Invoke(new Action(delegate //UI线程 { //点开始后才可以点的 BarButtonItem_Stop.Enabled = startClicked; barButtonItemReTestOnce.Enabled = startClicked; barButtonItemAutoGainAndExposure.Enabled = startClicked; barEditItemGain.Enabled = startClicked; barEditItemExposure.Enabled = startClicked; //点开始后不可点的 barStaticItem1.Enabled = !startClicked; barCheckItem2.Enabled = !startClicked; barCheckItem_com.Enabled = !startClicked; barEditItem3.Enabled = !startClicked; BarButtonItem_Start.Enabled = !startClicked; checkedListBox1.Enabled = !startClicked; barEditRetestTime.Enabled = !startClicked; barCheckRetest.Enabled = !startClicked; barStaticItem3.Enabled = !startClicked; barEditItemSelectModel.Enabled = !startClicked; })); } //stop按钮回调 private void BarButtonItem_Stop_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _mvCamera.StopAndDisconnectCameraAndDestroySdk(); try { _uvcCamera.Dispose(); // 销毁资源 } catch (Exception error) { WinFormsUtils.ShowTipDialog(error.ToString()); } _serialPortTransceiver.Dispose(); SwitchUI(false); oldSN = "0000000000000"; } //关闭窗口回调 private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (BarButtonItem_Stop.Enabled) //如果未停止,先停止 { BarButtonItem_Stop_ItemClick(null, null); } } //USB摄像头取图回调 private void UsbCamera_ImageGrabbed(object sender, NewFrameEventArgs e) { Image snImage = new Bitmap(e.Frame) as Image; // 必须复制,否则报错 // UI base.Invoke(new Action(delegate { pictureBoxUsb.Image = snImage; })); if (!_snDecoding) { _snDecoding = true; //防止重复进入 string SN = _barCodeDetector.Detect(ref snImage);//解码 // UI base.Invoke(new Action(delegate { labelSn.Text = SN; pictureBoxUsb.Image = snImage; //显示红线 })); if (SN != oldSN //是新SN,说明放上去新产品 && SN.Length == 13 && System.Text.RegularExpressions.Regex.IsMatch(SN, "1[1-3][0-9][0-9ABC][0-9A-Z]{9}")) // SN筛选规则 { oldSN = SN; reTestTimes = 0; TestMain(SN); } _snDecoding = false; } } //双击全屏显示画面 private void PictureBox_DoubleClick(object sender, EventArgs e) { var pictureBox = sender as PictureBox; if (pictureBox != null && pictureBox.Image != null) { WinFormsUtils.FullScreenImageForm fullScreenForm = new WinFormsUtils.FullScreenImageForm(pictureBox.Image); fullScreenForm.Show(); } } //测试主体 private void TestMain(string SN) { Bitmap bmp = _mvCamera.GetCurrentFrame(); Mat srcImg = OpenCvUtils.BitmapToBgrMat(bmp); #region logo检测 _detectedDistinctLabels = new List<string>(); OnePicResults yoloResult = _detector1.InferenceMat(srcImg, false); Mat result_image = yoloResult.ResultImg; //推理后的画框图像 var detResults = yoloResult.DetResults; //检测结果列表 foreach (var r in detResults) //绘制模型1检测框 { Scalar color = _detector1.labelColors[r.LabelId]; Cv2.PutText(result_image, $"{r.LabelName} {r.Confidence:F2}", new OpenCvSharp.Point(r.Rect.TopLeft.X, r.Rect.TopLeft.Y + 10), HersheyFonts.HersheySimplex, 4, color, thickness: 4); Cv2.Rectangle(result_image, r.Rect, color, thickness: 4); // 检测标签id转logo名称 if (_modelLabelId_to_logoName.TryGetValue(r.LabelId, out string detectedLogo)) { // 将检测到的logo类别添加到distinct列表 if (!_detectedDistinctLabels.Contains(detectedLogo)) { _detectedDistinctLabels.Add(detectedLogo); } } } Trace.WriteLine($">>>检测到的logo类别: {String.Join(", ", _detectedDistinctLabels.ToArray())}"); bool result = true; foreach (string label in _detectedDistinctLabels) { if (!_selectedLabels.Contains(label))//distinctLabels没有都包含在已选logo类别中,也就是多了 { result = false; } } if (_selectedLabels.Count != _detectedDistinctLabels.Count)//distinctLabels数量和已选logo类别数量不符,也就是少了 { result = false; } #endregion #region 测试结果处理 //串口发送PASS的SN if (barCheckItem_com.Checked) { #if !DEBUG if (result) #else if (true) #endif { Task.Run(() => { try { _serialPortTransceiver.Send(SN+"\r\n"); // 带换行 Thread.Sleep(Convert.ToInt32(barEditItemComSleep.EditValue)); // 延时 TODO:测试 } catch (Exception error) { WinFormsUtils.ShowTipDialog(error.ToString()); } }); } } //语音播报测试结果 Color resultColor = result ? Color.Green : Color.Red; string resultStr = result ? "PASS" : "FAIL"; if (barCheckItem2.Checked) _tts.Read(result ? "合格" : "测试不合格,请重新测试"); //保存图片 string tempPath = Path.Combine(Application.StartupPath, "results"); string addedPath = string.Empty; for (int ind = 0; ind < _selectedLabels.Count; ind++) { addedPath += _selectedLabels[ind].ToString(); if (!(ind == _selectedLabels.Count - 1)) { addedPath += ","; } } if (!Directory.Exists(Path.Combine(Path.Combine(tempPath, addedPath), resultStr))) { Directory.CreateDirectory(Path.Combine(Path.Combine(tempPath, addedPath), resultStr)); } String filename = Path.Combine(tempPath, addedPath, resultStr, DateTime.Now.ToString("yyyyMMdd_HHmmss_") + SN + ".jpg"); Cv2.ImWrite(filename, result_image); //保存log string selectedLogoStr = addedPath; string detectedLogoStr = String.Join(",", _detectedDistinctLabels); string logStr = string.Format("{0}\t{1}\t{2}\t选择的logo={3}\t检测到的logo={4}", SN, resultStr, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), selectedLogoStr, detectedLogoStr); CommonLib.Log.WriteResult(logStr);//写入日志文件 if (logs.Count > logMaxCount) { logs.RemoveAt(logMaxCount); } logs.Insert(0, new CommonLib.Log.LogType //TODO 增加日志:实际检测到的logo,需要检测的logo,用序号1~10显示 { SN = SN, TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Result = resultStr, SelectedLogo = selectedLogoStr, DetectedLogo = detectedLogoStr }); #endregion //UI base.Invoke(new Action(delegate { PictureBox_Result.Image = BitmapConverter.ToBitmap(result_image);//AI结果图像显示 Label_Result.ForeColor = resultColor; Label_Result.Text = resultStr; gridControl1.RefreshDataSource();//显示日志 })); //FAIL自动重测 if (!result && barCheckRetest.Checked && reTestTimes < 1) //自动重测一次 { reTestTimes += 1; Thread.Sleep((int)(reTestDelay * 1000)); //自动重测延时 TestMain(oldSN); } } //复杂解码选项改变 private void barCheckItem1_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (barCheckItemTryHarder.Checked) { _barCodeDetector = new BarcodeDecoder(true); } else { _barCodeDetector = new BarcodeDecoder(false); } } //文本框颜色控制 private void gridView1_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e) { if (e.RowHandle == 0) { e.Appearance.BackColor = Color.Yellow; } if (gridView1.GetRowCellValue(e.RowHandle, gridColumn3).ToString() == "FAIL") { e.Appearance.BackColor = Color.PaleVioletRed; } } #if !DEBUG //监听热键 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.M) { barButtonItemReTestOnce.PerformClick(); return true; } return base.ProcessCmdKey(ref msg, keyData); } #endif //重测延时调整 private void change_retestTime(object sender, EventArgs e) { reTestDelay = Convert.ToSingle(barEditRetestTime.EditValue); } //点击重测一次 private void barButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { reTestTimes = 1; TestMain(oldSN); } //显示日志文件夹 private void barButtonItem3_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { Process.Start("explorer", $"/n, {System.Environment.CurrentDirectory}\\results"); } //关于 private void barButtonItem5_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { Task.Run(() => { string url; if (pingHost("10.192.249.146")) { url = "http://10.192.249.146:8090/pages/viewpage.action?pageId=157548787"; } else { url = "https://docs.tp-manu.com.cn/pages/viewpage.action?pageId=157548787"; } Process.Start(url); }); } //检测ping通 private bool pingHost(string host) { Trace.WriteLine($">>>Ping:{host}"); bool result = false; System.Net.NetworkInformation.Ping pinger = new System.Net.NetworkInformation.Ping(); try { System.Net.NetworkInformation.PingReply reply = pinger.Send(host); if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) { result = true; } } catch (System.Net.NetworkInformation.PingException error) { WinFormsUtils.ShowTipDialog(error.ToString()); return false; } Trace.WriteLine($">>>Ping result:{result}"); return result; } //刷新串口列表 private void barStaticItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { Trace.WriteLine(">>>Refresh COM list"); //刷新串口列表 repositoryItemComboBox5.Items.Clear(); string[] coms = System.IO.Ports.SerialPort.GetPortNames(); foreach (var item in coms) { repositoryItemComboBox5.Items.Add(item); } WinFormsUtils.ShowTipDialog("串口列表已刷新!"); } // 下载模型 private void barButtonItemRefreshModels_ItemClick_1(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { WinFormsUtils.ShowTipDialog("将从远端服务器下载模型文件, 并更新模型下拉选择列表。\r\n这将花一定时间...点击确定继续"); string remoteHost; if (NetworkUtils.PingHost("10.192.249.146")) remoteHost = "10.192.249.146"; else remoteHost = "172.18.100.58"; SshUtils.DownloadFilesToLocal(remoteHost, "root", "Tplink123", "/home/tp/containers/remoteAssets", "assets"); LoadModels(); } // 自动增益曝光 private void barButtonItemAutoGainAndExposure_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { _mvCamera.AutoConfigOn(); Thread.Sleep(1000); // 等待自动调整完毕 _mvCamera.AutoConfigOff(); barEditItemGain.EditValue = _mvCamera.GetGain(); barEditItemExposure.EditValue = _mvCamera.GetExposureTime() / 1000; } } }
最新发布
10-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

某工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值