Commit eb1109d2 LN

料盘验证时若未扫到条码,增加料盘识别

1 个父辈 58d1a0b3
......@@ -89,6 +89,7 @@
<Compile Include="assemblymanager\TrayManager.cs" />
<Compile Include="baan\AxisBean.cs" />
<Compile Include="baan\WaitUtil.cs" />
<Compile Include="deviceLibrary\halcon\EyemManager.cs" />
<Compile Include="deviceLibrary\reelCheck\MyCamera.cs" />
<Compile Include="deviceLibrary\reelCheck\ReelCheckUtil.cs" />
<Compile Include="deviceLibrary\halcon\CodeManager.cs" />
......@@ -249,6 +250,12 @@
<Content Include="Config\Camera.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="darknet\detect-tiny-label.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="darknet\detect-tiny-label.weights">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="LineConfig\Config_FeedingEquip_1.csv">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
......
......@@ -169,26 +169,16 @@ namespace OnlineStore.DeviceLibrary
{
//扫码
(bool result, string barcode) = CodeManager.ReelCheckCameraScan(new List<string> { Config.CameraName_1 }, Name);
//没扫到条码,检测到没料 ,保存图片, 清空
if (tray.IsFull)//初次检测有料盘
{
if (result)//有料盘
{
(int resCode, taskInfo task) = SServerManager.getTaskInfo(barcode);
if (resCode == -1)
{
TrayDisableManager.AddDisableTray(trayNum);
LogUtil.info($"【屏蔽料盘二次判断】【-1】【需要禁用该托盘】【{tray.ToStr()}】");
}
else if (resCode == 100)
{
tray.InoutPar.InStoreNg = true;
tray.InoutPar.PlateH = task.plateH;
tray.InoutPar.PlateW = task.plateW;
TrayManager.UpdateTrayInfo(trayNum, true, tray.InOrOutStore, tray.InoutPar);
tray.InoutPar.Corrected = true;
LogUtil.info($"【屏蔽料盘二次判断】【100】【有尺寸信息,认为NG】【{tray.ToStr()}】");
}
else if (resCode == 0)
if (resCode == 0)
{
//if (task != null)
{
......@@ -213,6 +203,21 @@ namespace OnlineStore.DeviceLibrary
LogUtil.info($"【屏蔽料盘二次判断】【初次有料,第二次有料,认为有料】【{tray.ToStr()}】");
}
}
else if (task.plateH > 0)
{
tray.InoutPar.InStoreNg = true;
tray.InoutPar.PlateH = task.plateH;
tray.InoutPar.PlateW = task.plateW;
TrayManager.UpdateTrayInfo(trayNum, true, tray.InOrOutStore, tray.InoutPar);
tray.InoutPar.Corrected = true;
LogUtil.info($"【屏蔽料盘二次判断】【100】【有尺寸信息,认为NG】【{tray.ToStr()}】");
}
else
{
TrayDisableManager.AddDisableTray(trayNum);
LogUtil.info($"【屏蔽料盘二次判断】【-1】【需要禁用该托盘】【{tray.ToStr()}】");
}
}
else//二次检测无料盘
......
[net]
# Testing
batch=1
subdivisions=1
# Training
# batch=64
# subdivisions=64
width=960
height=960
channels=3
momentum=0.9
decay=0.0005
angle=180
saturation = 1.5
exposure = 1.5
hue=.1
learning_rate=0.001
burn_in=1000
max_batches = 4000
policy=steps
steps=3200,3600
scales=.1,.1
[convolutional]
batch_normalize=1
filters=16
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=1
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
###########
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=18
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
[route]
layers = -4
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[upsample]
stride=2
[route]
layers = -1, 8
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=18
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
......@@ -46,6 +46,8 @@ namespace OnlineStore.DeviceLibrary
LoadCamera(false);
CodeLibrary.HDCodeLearnHelper.LoadConfig("", codeStr);
CodeLibrary.EyemDecode.InitModel();
EyemManager.Init();
}
catch (Exception ex)
{
......@@ -259,11 +261,11 @@ namespace OnlineStore.DeviceLibrary
}
[HandleProcessCorruptedStateExceptions]
public static (bool,string) ReelCheckCameraScan(List<string> cameraList, string deviceName)
public static (bool, string) ReelCheckCameraScan(List<string> cameraList, string deviceName)
{
bool isPreScan = deviceName.EndsWith("预扫码");
List<string> codeList = new List<string>();
bool findCode = true;
string code = "";
if (cameraList == null || cameraList.Count <= 0)
{
return (findCode, ProcessCode(codeList));
......@@ -299,7 +301,8 @@ namespace OnlineStore.DeviceLibrary
string r = "";
// bool eyemNoCode = false;
Task eyemtask = Task.Factory.StartNew(delegate {
Task eyemtask = Task.Factory.StartNew(delegate
{
List<CodeInfo> tlci = EyemDecode.ModelDecoder(ref bmp);
foreach (CodeInfo co in tlci)
{
......@@ -309,10 +312,6 @@ namespace OnlineStore.DeviceLibrary
{
codeList.Add(str);
r = r + "##eyem|" + co.CodeType + "|" + str;
//if (!findCode)
//{
// findCode = HasRightCode(str);
//}
}
}
});
......@@ -325,59 +324,59 @@ namespace OnlineStore.DeviceLibrary
//eyemNoCode = true;
}
//if (!isPreScan)
//{
// if (!findCode)
// {
// try
// {
// List<CodeInfo> cc = new List<CodeInfo>();
// eyemNoCode = true;
// RemoteDecodeHelper.RemoteDecodeParam remoteDecodeParam = new RemoteDecodeHelper.RemoteDecodeParam
// {
// codeTypeList = allCodeTypeList.ToArray(),
// codeCount = 3,
// timeout = 3000
// };
// cc = RemoteDecodeHelper.DecodeRequest(ho_Image, remoteDecodeParam);
// if (cc != null && cc.Count > 0) findCode = true;
// //if (cc != null)
// //{
// // foreach (CodeInfo c in cc)
// // {
// // string str = CodeManager.ReplaceCode(c.CodeStr);
// // if (!codeList.Contains(str))
// // {
// // codeList.Add(str);
// // r = r + "##halcon|" + c.CodeType + "|" + str;
// // if (!findCode)
// // {
// // findCode = HasRightCode(str);
// // }
// // }
// // }
// //}
// }
// catch (Exception ex)
// {
// LogUtil.error(deviceName + " RemoteDecodeHelper扫码出错:" + ex.ToString());
// }
// }
// //if (!findRightCode && SaveErrorImageToFile.Equals(1))
// if (SaveImage || (((!findCode) || eyemNoCode) && (!isPreScan)))
// {
// //如果halcon没扫出的,
// string nameStr = "";
// if (findCode && eyemNoCode)
// {
// nameStr = "eyem";
// }
// SaveImageToFile(deviceName, cameraName + nameStr, bmp);
// }
//}
code = ProcessCode(codeList);
findCode = string.IsNullOrEmpty(code) ? false : true;
if (!findCode)
{
try
{
List<CodeInfo> cc = new List<CodeInfo>();
RemoteDecodeHelper.RemoteDecodeParam remoteDecodeParam = new RemoteDecodeHelper.RemoteDecodeParam
{
codeTypeList = allCodeTypeList.ToArray(),
codeCount = 3,
timeout = 3000
};
cc = RemoteDecodeHelper.DecodeRequest(ho_Image, remoteDecodeParam);
if (cc != null && cc.Count > 0) findCode = true;
if (cc != null)
{
foreach (CodeInfo c in cc)
{
string str = CodeManager.ReplaceCode(c.CodeStr);
if (!codeList.Contains(str))
{
codeList.Add(str);
r = r + "##halcon|" + c.CodeType + "|" + str;
}
}
}
}
catch (Exception ex)
{
LogUtil.error(deviceName + " RemoteDecodeHelper扫码出错:" + ex.ToString());
}
code = ProcessCode(codeList);
findCode = string.IsNullOrEmpty(code) ? false : true;
}
if (!findCode)
{
//验证是否有料盘
findCode = EyemManager.ReelCheck(bmp);
}
if (!findCode)
{
string nameStr = "nofindCode";
SaveImageToFile(deviceName, cameraName + nameStr, bmp);
}
if (deviceName != "" || r != "")
{
LogUtil.info(deviceName + " 【" + cameraName + "】扫码完成【" + FormUtil.GetSpanStr(DateTime.Now - startTime) + "】[" + findCode + "]" + ScanCount + " :" + r);
......@@ -416,9 +415,7 @@ namespace OnlineStore.DeviceLibrary
{
LogUtil.error(deviceName + " 扫码出错:" + ex.ToString());
}
string code = ProcessCode(codeList);
findCode = string.IsNullOrEmpty(code) ? false : true;
return (findCode,code);
return (findCode, code);
}
private static int SaveErrorImageToFile = ConfigAppSettings.GetIntValue(Setting_Init.SaveErrorImageToFile);
......
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace OnlineStore.DeviceLibrary
{
public class EyemManager
{
public static bool Init()
{
try
{
int flag = eyemInitNNDetector(".\\darknet\\detect-tiny-label.cfg", ".\\darknet\\detect-tiny-label.weights", 640, 640);
if (flag != 0)
{
LogUtil.error("EyemManager" + $"初始化模型失败");
return false;
//MessageBox.Show("初始化模型失败!", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
}
LogUtil.info("EyemManager" + $"init ok ,flag="+ flag);
eyemNNDetectorParams(0.35f, 0.45f);
}
catch (Exception ex)
{
LogUtil.error(" EyemManager Init error :" + ex.ToString());
}
return true;
}
public static bool record = false;//是否保存结果图片
public static bool ReelCheck(Bitmap a)
{
try
{
Bitmap b = GetReducedImage(a, 1024, 0);
a.Dispose();
EyemImage image = new EyemImage();
image.iWidth = b.Width;
image.iHeight = b.Height;
image.iChannels = 4;
image.iDepth = 0;
//b.Dispose();
//b = new Bitmap("temp.bmp");
//eyemImageRead("temp.bmp", -1, out EyemImage image);
var bl = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
image.ucpImage = bl.Scan0;
int ipNum;
BboxContainer bboxes = new BboxContainer();
eyemNNDetector(image, out ipNum, ref bboxes, out EyemImage tpDstImg);
if (record)
{
var c = eyemCvtToBitmap(tpDstImg);
b.Save($"CameraDebug\\{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.jpg");
c.Save($"CameraDebug\\{DateTime.Now:yyyy-MM-dd-HH-mm-ss}_m.jpg");
c.Dispose();
}
eyemImageFree(ref tpDstImg);
//eyemImageFree(ref image);
b.UnlockBits(bl);
b.Dispose();
//for (int i = 0; i < ipNum; i++)
//{ }
if (ipNum > 0)
{
return true;
}
}
catch (Exception ex)
{
LogUtil.error(" EyemManager ReelCheck error :" + ex.ToString());
}
return false;
}
#region 通用
//读取图像,支持彩色与多深度
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageRead(string filename, int iFlags, out EyemImage tpImage);
//释放图像资源
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void eyemImageFree(ref EyemImage tpImage);
#endregion
#region 项目
/// <summary>
/// 初始化检测器
/// </summary>
/// <param name="detectorConfigPath">配置文件</param>
/// <param name="detectorModelPath">模型文件</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemInitNNDetector(string detectorConfigPath, string detectorModelPath, int iNetSizew, int iNetSizeh);
/// <summary>
/// 目标检测器
/// </summary>
/// <param name="tpImage">输入图像</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNNDetector(EyemImage tpImage, out int ipNum, ref BboxContainer container, out EyemImage tpDstImg);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNNDetectorParams(float fConfidence, float fNMSThreshold);
#endregion
#region 结构体
//图像信息
[StructLayout(LayoutKind.Sequential)]
public struct EyemImage
{
public IntPtr ucpImage; // 地址
public int iWidth; // 图像内存 x 方向大小
public int iHeight; // 图像内存 y 方向大小
public int iDepth; // 图像位深度(详见说明)
public int iChannels; // 图像通道数
}
// 矩形定义
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
}
[StructLayout(LayoutKind.Sequential)]
public struct BboxContainer
{
//最多支持100个目标
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public EyemRect[] bboxes;
}
#endregion
/// <summary>
/// 生成缩略图重载方法1,返回缩略图的Image对象
/// </summary>
/// <param name="width">缩略图的宽度</param>
/// <param name="height">缩略图的高度</param>
/// <returns>缩略图的Image对象</returns>
private static Bitmap GetReducedImage(Bitmap resourceImage, int width, int height)
{
if (height == 0)
{
var sc = resourceImage.Width / (float)width;
height = (int)(resourceImage.Height / sc);
}
try
{
Bitmap data = null;
//用指定的大小和格式初始化Bitmap类的新实例
using (Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb))
{
//从指定的Image对象创建新Graphics对象
using (Graphics graphics = Graphics.FromImage(bitmap))
{
//清除整个绘图面并以透明背景色填充
//graphics.Clear(Color.Transparent);
//在指定位置并且按指定大小绘制原图片对象
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
graphics.DrawImage(resourceImage, new Rectangle(0, 0, width, height));
}
data = new Bitmap(bitmap);
}
return data;
}
catch (Exception e)
{
throw e;
}
}
public T DeepClone<T>(T _object)
{
T dstobject;
using (MemoryStream mStream = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mStream, _object);
mStream.Seek(0, SeekOrigin.Begin);//指定当前流的位置为流的开头。
dstobject = (T)bf.Deserialize(mStream);
mStream.Close();
}
return dstobject;
}
#region EyemImage转换成Bitmap
public static unsafe Bitmap eyemCvtToBitmap(EyemImage tpImage)
{
if (tpImage.ucpImage == IntPtr.Zero)
throw new ArgumentNullException("图像不存在");
if (tpImage.iDepth != 0)
throw new ArgumentException("图像必须是8位无符号整型");
PixelFormat format;
switch (tpImage.iChannels)
{
case 1:
format = PixelFormat.Format8bppIndexed;
break;
case 3:
format = PixelFormat.Format24bppRgb;
break;
case 4:
format = PixelFormat.Format32bppArgb;
break;
default:
return null;
}
Bitmap bitmap = new Bitmap(tpImage.iWidth, tpImage.iHeight, format);
//对于输出灰度图像
if (format == PixelFormat.Format8bppIndexed)
{
ColorPalette palette = bitmap.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
bitmap.Palette = palette;
}
//锁定数据区
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight),
ImageLockMode.WriteOnly, format);
try
{
int pd = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
for (int y = 0; y < tpImage.iHeight; y++)
{
long offsetSrc = (y * tpImage.iWidth * tpImage.iChannels);
long offsetDst = (y * pd);
Buffer.MemoryCopy((byte*)(tpImage.ucpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
}
}
catch (Exception ex)
{
LogUtil.error("EyemManager eyemCvtToBitmap error:" + ex);
}
finally
{
bitmap.UnlockBits(bd);
}
return bitmap;
}
#endregion
}
}
......@@ -61,7 +61,7 @@ namespace OnlineStore.DeviceLibrary
/// </summary>
public bool InStoreNg = false;
/// <summary>
/// 手动判断NG
/// 手动判断NG 不处理
/// </summary>
public bool ManualJudgeNG = false;
/// <summary>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!