保存图片有问题

This commit is contained in:
TD 2025-04-02 18:26:34 +08:00
parent babc40d36a
commit d63a6c42b3
6 changed files with 217 additions and 72 deletions

View File

@ -509,7 +509,7 @@ namespace DH.Commons.Base
private AntList<SizeTreatParam> _sizeTreatParamList = new AntList<SizeTreatParam>();
private CustomizedPoint _showLocation = new CustomizedPoint();
private string _imageSaveDirectory;
private string _imageSaveDirectory="D://Images";
private bool _saveOKOriginal = false;
private bool _saveNGOriginal = false;
private bool _saveOKDetect = false;

View File

@ -50,19 +50,19 @@ namespace DH.Commons.Base
{
OnDetectionWarningStop?.Invoke(detectionDes);
}
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
{
if (saveMap != null)
{
//ImageSaveSet imageSaveSet = new ImageSaveSet()
//{
// FullName = fullname,
// SaveImage = saveMap.CopyBitmap(),
// ImageFormat = imageFormat.DeepSerializeClone()
//};
ImageSaveSet imageSaveSet = new ImageSaveSet()
{
FullName = fullname,
SaveImage = saveMap,
//ImageSaveHelper.ImageSaveAsync(imageSaveSet);
};
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
}
}
}

View File

@ -375,7 +375,7 @@ namespace DH.Devices.Camera
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
//存图
DisplayAndSaveOriginImage(imageSet.Id);
DisplayAndSaveOriginImage(imageSet.Id,SnapshotCount);
@ -407,7 +407,7 @@ namespace DH.Devices.Camera
_imageSetList[set.Id] = set;
}
public virtual async void DisplayAndSaveOriginImage(string imgSetId)
public virtual async void DisplayAndSaveOriginImage(string imgSetId, int _counter)
{
MatSet set = _imageSetList.Values.FirstOrDefault(u => u.Id == imgSetId);
@ -423,7 +423,7 @@ namespace DH.Devices.Camera
// OnShowImageUpdated?.Invoke(this, showImage, imgSetId);
if (IsSavePicEnabled)
{
string fullname = Path.Combine(ImageSaveDirectory, $"{CameraName}_{set.Id}.{set._imageFormat.ToString().ToLower()}");
string fullname = Path.Combine(ImageSaveDirectory, $"{CameraName}_{_counter:D7}_{set.Id}.{set._imageFormat.ToString().ToLower()}");
ImageSaveAsync(fullname, showImage);
}

View File

@ -281,7 +281,7 @@ namespace DH.Devices.Vision
// GC.Collect();
}
#pragma warning restore CS0168 // 声明了变量,但从未使用过
}

View File

@ -8,6 +8,8 @@ using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
@ -76,12 +78,13 @@ namespace DH.Devices.Vision
//未能获得检测配置
return detectResult;
}
detectResult.DetectName = detectConfig.Name;
detectResult.ImageSaveDirectory=detectConfig.ImageSaveDirectory;
detectResult.SaveNGDetect=detectConfig.SaveNGDetect;
detectResult.SaveNGOriginal=detectConfig.SaveNGOriginal;
detectResult.SaveOKDetect=detectConfig.SaveOKDetect;
detectResult.SaveOKOriginal=detectConfig.SaveOKOriginal;
detectResult.DetectionOriginImage = originImgSet.Clone().ToBitmap();
//detectResult.DetectionOriginImage = originImgSet.Clone().ToBitmap();
Stopwatch sw = new Stopwatch();
#region 1.
sw.Start();
@ -263,22 +266,22 @@ namespace DH.Devices.Vision
}
foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
{
bool b = group.ToList().Any(f =>
{
return f.FilterOperation(d);
});
//foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
//{
// bool b = group.ToList().Any(f =>
// {
// return f.FilterOperation(d);
// });
if (b)
{
d.FinalResult = group.Key;
break;
}
// if (b)
// {
// d.FinalResult = group.Key;
// break;
// }
}
//}
});
#endregion
#region 5.NG
@ -455,9 +458,9 @@ namespace DH.Devices.Vision
}
catch (Exception ex)
{
LogAsync(DateTime.Now, LogLevel.Error, $"模型加载成功是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
// LogAsync(DateTime.Now, LogLevel.Error, $"模型加载成功是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
//throw new ProcessException($"异常是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}");
throw new ProcessException($"异常是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}");
}
return mLEngineSet;
}
@ -1000,14 +1003,14 @@ namespace DH.Devices.Vision
List<IShapeElement> detectionResultShapesClone = new List<IShapeElement>(detectionResultShapes);
DetectionDone(DetectionId, resultMask, detectionResultShapes);
detectResult.DetectionOriginImage = CopyBitmapWithLockBits(resultMask);
SaveDetectResultImageAsync(detectResult);
// SaveDetectResultCSVAsync(detectResult);
}
catch (Exception ex)
{
LogAsync(DateTime.Now, LogLevel.Exception,
$"{Name}显示{detectResult.DetectName}检测结果异常,{ex.GetExceptionMessage()}");
//LogAsync(DateTime.Now, LogLevel.Exception,
// $"{Name}显示{detectResult.DetectName}检测结果异常,{ex.GetExceptionMessage()}");
}
finally
{
@ -1016,17 +1019,58 @@ namespace DH.Devices.Vision
}
});
}
public static Bitmap CopyBitmapWithLockBits(Bitmap original)
{
Bitmap copy = new Bitmap(original.Width, original.Height, original.PixelFormat);
BitmapData originalData = original.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.ReadOnly,
original.PixelFormat
);
BitmapData copyData = copy.LockBits(
new Rectangle(0, 0, copy.Width, copy.Height),
ImageLockMode.WriteOnly,
copy.PixelFormat
);
int bytesPerPixel = Image.GetPixelFormatSize(original.PixelFormat) / 8;
int byteCount = originalData.Stride * original.Height;
byte[] buffer = new byte[byteCount];
System.Runtime.InteropServices.Marshal.Copy(originalData.Scan0, buffer, 0, byteCount);
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, copyData.Scan0, byteCount);
original.UnlockBits(originalData);
copy.UnlockBits(copyData);
return copy;
}
/// <summary>
///图片异步保存
/// </summary>
public void SaveDetectResultImageAsync(DetectStationResult detectResult)
public void SaveDetectResultImageAsync1(DetectStationResult detectResult)
{
string format = detectResult.ImageFormat.ToString().ToLower();
if(detectResult.ImageSaveDirectory!=null)
{
if (!Directory.Exists(detectResult.ImageSaveDirectory))
{
}
else
{
}
}else
{
return;
}
//根目录
string rootPath = Path.Combine(detectResult.ImageSaveDirectory,
DateTime.Now.ToString("yyyyMMdd"), BatchNO, detectResult.DetectName);
DateTime.Now.ToString("yyyyMMdd"), detectResult.DetectName);
if (detectResult.ResultState != ResultState.OK)
{
@ -1078,12 +1122,21 @@ namespace DH.Devices.Vision
Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap);
string prefix = Path.Combine(rootPath, "NGFitImages", detectResult.ResultLabel);
Directory.CreateDirectory(prefix); // 自动创建所有缺失的目录
string fullname = Path.Combine(prefix, $"{detectResult.Pid}_NGFitImage_{detectResult.DetectName}_{detectResult.Id}.{format}");
SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat);
// SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat);
// 使用回调或 Task.ContinueWith 确保保存完成后再释放资源
//SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat)
// .ContinueWith(t =>
// {
// resultMask?.Dispose();
// preTreatedBitmap?.Dispose();
// resultMap?.Dispose();
// detectionFitImage?.Dispose();
// }, TaskScheduler.Default);
resultMask?.Dispose();
preTreatedBitmap?.Dispose();
@ -1134,8 +1187,7 @@ namespace DH.Devices.Vision
Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes);
resultDisplay.Dispose();
detectionResultShapes.Clear();
Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap);
@ -1148,11 +1200,12 @@ namespace DH.Devices.Vision
SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat);
resultMask?.Dispose();
preTreatedBitmap?.Dispose();
resultMap?.Dispose();
detectionFitImage?.Dispose();
//resultDisplay.Dispose();
//detectionResultShapes.Clear();
//resultMask?.Dispose();
//preTreatedBitmap?.Dispose();
//resultMap?.Dispose();
//detectionFitImage?.Dispose();
}
@ -1163,6 +1216,7 @@ namespace DH.Devices.Vision
}
public virtual Bitmap GetResultImage(Bitmap baseImage, List<IShapeElement> eleList)
{
try
@ -1189,5 +1243,112 @@ namespace DH.Devices.Vision
}
}
public void SaveDetectResultImageAsync(DetectStationResult detectResult)
{
if (detectResult.ImageSaveDirectory == null) return;
string format = detectResult.ImageFormat.ToString().ToLower();
string rootPath = Path.Combine(detectResult.ImageSaveDirectory,
DateTime.Now.ToString("yyyyMMdd"), detectResult.DetectName);
try
{
if (detectResult.ResultState != ResultState.OK)
{
SaveNGImages(detectResult, rootPath, format);
}
else
{
SaveOKImages(detectResult, rootPath, format);
}
}
catch (Exception ex)
{
// Logger.Error($"保存检测结果失败: {ex.Message}");
}
}
private void SaveNGImages(DetectStationResult result, string rootPath, string format)
{
// NG 原图
if (result.SaveNGOriginal && result.DetectionOriginImage != null)
{
string prefix = Path.Combine(rootPath, "NGRawImages", result.ResultLabel);
Directory.CreateDirectory(prefix);
string fullname = Path.Combine(prefix, $"{result.Pid}_NGRawImage_{result.DetectName}_{result.Id}.{format}");
SaveImageAsync(fullname, result.DetectionOriginImage, result.ImageFormat);
}
// NG 结果图
if (result.SaveOKDetect && result.DetectionOriginImage != null)
{
string displayTxt = BuildDisplayText(result);
using (Bitmap resultMask = result.DetectionOriginImage.CopyBitmap())
using (Bitmap preTreatedBitmap = result.DetectionOriginImage.CopyBitmap())
{
var detectionResultShapes = new List<IShapeElement>(result.DetectionResultShapes)
{
new DetectResultDisplay(result, resultMask, displayTxt)
};
using (Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes))
using (Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap))
{
string prefix = Path.Combine(rootPath, "NGFitImages", result.ResultLabel);
Directory.CreateDirectory(prefix);
string fullname = Path.Combine(prefix, $"{result.Pid}_NGFitImage_{result.DetectName}_{result.Id}.{format}");
SaveImageAsync(fullname, detectionFitImage, result.ImageFormat);
}
}
}
}
private void SaveOKImages(DetectStationResult result, string rootPath, string format)
{
// OK 原图
if (result.SaveOKOriginal && result.DetectionOriginImage != null)
{
string prefix = Path.Combine(rootPath, "OKRawImages", result.ResultLabel);
Directory.CreateDirectory(prefix);
string fullname = Path.Combine(prefix, $"{result.Pid}_OKRawImage_{result.DetectName}_{result.Id}.{format}");
SaveImageAsync(fullname, result.DetectionOriginImage, result.ImageFormat);
}
// OK 结果图
if (result.SaveOKDetect && result.DetectionOriginImage != null)
{
string displayTxt = BuildDisplayText(result);
using (Bitmap resultMask = result.DetectionOriginImage.CopyBitmap())
using (Bitmap preTreatedBitmap = result.DetectionOriginImage.CopyBitmap())
{
var detectionResultShapes = new List<IShapeElement>(result.DetectionResultShapes)
{
new DetectResultDisplay(result, resultMask, displayTxt)
};
using (Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes))
using (Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap))
{
string prefix = Path.Combine(rootPath, "OKFitImages", result.ResultLabel);
Directory.CreateDirectory(prefix);
string fullname = Path.Combine(prefix, $"{result.Pid}_OKFitImage_{result.DetectName}_{result.Id}.{format}");
SaveImageAsync(fullname, result.DetectionOriginImage, result.ImageFormat);
}
}
}
}
private string BuildDisplayText(DetectStationResult result)
{
StringBuilder sb = new StringBuilder();
result.DetectDetails.ForEach(d => sb.AppendLine($"{d.LabelName} score:{d.Score:f2} area:{d.Area:f2}"));
if (result.realSpecs?.Count > 0)
{
result.realSpecs.ForEach(d => sb.AppendLine($"{d.Code} score:{d.ActualValue}"));
}
return sb.ToString();
}
}
}

View File

@ -264,18 +264,23 @@ namespace DHSoftware
var cameraBase = ConfigModel.CameraBaseList[i];
if (cameraBase.CamType == EnumCamType.Do3think)
{
Do3ThinkCamera cam = new Do3ThinkCamera();
Do3ThinkCamera cam =new Do3ThinkCamera();
cam.IsSavePicEnabled = cameraBase.IsSavePicEnabled;
cam.CameraName = cameraBase.CameraName;
cam.CameraIP = cameraBase.CameraIP;
cam.IsEnabled = cameraBase.IsEnabled;
cam.ImageSaveDirectory = "D://Cam1//";
Cameras.Add(cam);
cam.OnLog -= _visionEngine_OnLog;
cam.OnLog += _visionEngine_OnLog;
cam.CameraConnect();
cam.OnHImageOutput += OnCameraHImageOutput;
if(cameraBase.IsEnabled)
{
cam.OnLog -= _visionEngine_OnLog;
cam.OnLog += _visionEngine_OnLog;
cam.CameraConnect();
cam.OnHImageOutput += OnCameraHImageOutput;
}
}
else if (cameraBase.CamType == EnumCamType.hik)
{
@ -653,7 +658,7 @@ namespace DHSoftware
PLC.OnNewPieces += MainMotion_NewPieces;
}
ConfigModel.CameraBaseList.ForEach(d =>
Cameras.ForEach(d =>
{
if (d is CameraBase cam)
{
@ -874,17 +879,7 @@ namespace DHSoftware
if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName))
{
localImageSet.Dispose();
//this.BeginInvoke(new MethodInvoker(delegate ()
//{
// // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
// // richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName);
// // 设置回原来的滚动位置
// // richTextBox1.SelectionStart = richTextBox1.TextLength;
// // richTextBox1.ScrollToCaret();
//}));
////重新生成实例 销毁之前的实例
LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.CameraName} 找到产品{productNumber}但是没有推理1");
@ -922,18 +917,7 @@ namespace DHSoftware
return;
}
UpdateResult(DateTime.Now, null, product.ProductResult.GetEnumDescription());
// ProductNum_Total++;
// CalculateOEE();
this.BeginInvoke(new MethodInvoker(delegate ()
{
//int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
//richTextBox1.AppendText($"统计结果成功,{productNumber} 吹气!\n");
// 设置回原来的滚动位置
// richTextBox1.SelectionStart = richTextBox1.TextLength;
// richTextBox1.ScrollToCaret();
}));
#region 6.