Commit 51e890e1 刘韬

优化为并行扫码

1 个父辈 1e673479
此文件类型无法预览
...@@ -4,6 +4,8 @@ using System.Drawing; ...@@ -4,6 +4,8 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using HalconDotNet; using HalconDotNet;
using CameraVisionLib.Model; using CameraVisionLib.Model;
using System.Threading.Tasks;
using System.Diagnostics;
namespace Asa.Barcode namespace Asa.Barcode
{ {
...@@ -50,7 +52,6 @@ namespace Asa.Barcode ...@@ -50,7 +52,6 @@ namespace Asa.Barcode
if (code.Count == 0) code.AddRange(HalconGetCode(image)); if (code.Count == 0) code.AddRange(HalconGetCode(image));
break; break;
} }
return code; return code;
} }
...@@ -64,21 +65,55 @@ namespace Asa.Barcode ...@@ -64,21 +65,55 @@ namespace Asa.Barcode
{ {
List<BarcodeInfo> code = new(); List<BarcodeInfo> code = new();
Bitmap bmp = new(image); //防止原图被释放 Bitmap bmp = new(image); //防止原图被释放
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
//图像转成halcon的类型
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HObject hObj;
var zoom = scanParam.Zoom2D;
try
{
HOperatorSet.GenImageInterleaved(out hObj, bmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
if (zoom != 1)
HOperatorSet.ZoomImageFactor(hObj, out hObj, zoom, zoom, "bilinear");
bmp.UnlockBits(bmpData);
stopwatch.Stop();
Common.log.Info("to hobj time:" + stopwatch.ElapsedMilliseconds);
}
catch (Exception ex)
{
bmp.UnlockBits(bmpData);
Common.log.Error("Extract1DCode", ex);
return code;
}
switch (scanParam.HalconType) switch (scanParam.HalconType)
{ {
case CodeType.All: case CodeType.All:
code.AddRange(HalconExtract1DCode(bmp, scanParam.Zoom1D)); var t1 = Task.Run(()=> {
code.AddRange(HalconExtract2DCode(bmp, scanParam.Zoom2D)); var cs = HalconExtract1DCode(hObj, scanParam.Zoom1D);
lock (code) {
code.AddRange(cs);
}
});
var t2 = Task.Run(() => {
var cs = HalconExtract2DCode(hObj, scanParam.Zoom2D);
lock (code)
{
code.AddRange(cs);
}
});
Task.WaitAll(t1, t2);
break; break;
case CodeType.Barcode1D: case CodeType.Barcode1D:
code.AddRange(HalconExtract1DCode(bmp, scanParam.Zoom1D)); code.AddRange(HalconExtract1DCode(hObj, scanParam.Zoom1D));
break; break;
case CodeType.Barcode2D: case CodeType.Barcode2D:
code.AddRange(HalconExtract2DCode(bmp, scanParam.Zoom2D)); code.AddRange(HalconExtract2DCode(hObj, scanParam.Zoom2D));
break; break;
} }
hObj.Dispose();
bmp.Dispose();
return code; return code;
} }
...@@ -107,29 +142,16 @@ namespace Asa.Barcode ...@@ -107,29 +142,16 @@ namespace Asa.Barcode
return code; return code;
} }
private List<BarcodeInfo> HalconExtract1DCode(Bitmap bmp, float zoom) private List<BarcodeInfo> HalconExtract1DCode(HObject hObj, float zoom)
{ {
List<BarcodeInfo> codeInfo = new(); List<BarcodeInfo> codeInfo = new();
//图像转成halcon的类型
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HObject hObj;
try
{
HOperatorSet.GenImageInterleaved(out hObj, bmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
if (zoom != 1)
HOperatorSet.ZoomImageFactor(hObj, out hObj, zoom, zoom, "bilinear");
bmp.UnlockBits(bmpData);
}
catch (Exception ex)
{
bmp.UnlockBits(bmpData);
Common.log.Error("Extract1DCode", ex);
return codeInfo;
}
try try
{ {
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
HOperatorSet.Rgb1ToGray(hObj, out HObject grayImage); HOperatorSet.Rgb1ToGray(hObj, out HObject grayImage);
HOperatorSet.CreateBarCodeModel(new HTuple(), new HTuple(), out HTuple hv_BarCode); //创建条码模型 HOperatorSet.CreateBarCodeModel(new HTuple(), new HTuple(), out HTuple hv_BarCode); //创建条码模型
HOperatorSet.SetBarCodeParam(hv_BarCode, "num_scanlines", 5); //扫描线的最大数量 HOperatorSet.SetBarCodeParam(hv_BarCode, "num_scanlines", 5); //扫描线的最大数量
...@@ -141,7 +163,8 @@ namespace Asa.Barcode ...@@ -141,7 +163,8 @@ namespace Asa.Barcode
HOperatorSet.GetBarCodeResult(hv_BarCode, "all", "orientation", out HTuple hv_Orientation); //获取条码方向,x轴逆时针[0,180],顺时针[0,-180] HOperatorSet.GetBarCodeResult(hv_BarCode, "all", "orientation", out HTuple hv_Orientation); //获取条码方向,x轴逆时针[0,180],顺时针[0,-180]
HOperatorSet.SmallestRectangle2(symbolRegions, out HTuple row, out HTuple column, out HTuple phi, out HTuple length1, out HTuple length2); HOperatorSet.SmallestRectangle2(symbolRegions, out HTuple row, out HTuple column, out HTuple phi, out HTuple length1, out HTuple length2);
HOperatorSet.ClearBarCodeModel(hv_BarCode); //清除条码模型 HOperatorSet.ClearBarCodeModel(hv_BarCode); //清除条码模型
Common.log.Info("Halcon Extract1DCode Count=" + hv_String.Length); stopwatch.Stop();
Common.log.Info("Halcon Extract1DCode Count=" + hv_String.Length + " time:" + stopwatch.ElapsedMilliseconds);
if (hv_String.Length > 0) if (hv_String.Length > 0)
{ {
...@@ -170,82 +193,80 @@ namespace Asa.Barcode ...@@ -170,82 +193,80 @@ namespace Asa.Barcode
return codeInfo; return codeInfo;
} }
private List<BarcodeInfo> HalconExtract2DCode(Bitmap bmp, float zoom) private List<BarcodeInfo> HalconExtract2DCode(HObject hObj, float zoom)
{ {
List<BarcodeInfo> codeInfo = new(); List<BarcodeInfo> codeInfo = new();
//图像转成halcon的类型
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HObject hObj;
try
{
HOperatorSet.GenImageInterleaved(out hObj, bmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
if (zoom != 1)
HOperatorSet.ZoomImageFactor(hObj, out hObj, zoom, zoom, "bilinear");
bmp.UnlockBits(bmpData);
}
catch (Exception ex)
{
bmp.UnlockBits(bmpData);
Common.log.Error("Extract2DCode", ex);
return codeInfo;
}
string[] type = new string[] { "Data Matrix ECC 200", "QR Code", "PDF417" }; string[] type = new string[] { "Data Matrix ECC 200", "QR Code", "PDF417" };
try
Task[] tasks = new Task[type.Length];
for (int i = 0; i < type.Length; i++)
{ {
for (int i = 0; i < type.Length; i++) var ctype = type[i];
tasks[i] = Task.Run(() =>
{ {
HOperatorSet.Rgb1ToGray(hObj, out HObject grayImage);
//支持‘Data Matrix ECC 200’、‘QR Code’和‘PDF417’共3种类型 try
//‘standard_recognition’、‘enhanced_recognition’、‘maximum_recognition’
HOperatorSet.CreateDataCode2dModel(type[i], "default_parameters", "maximum_recognition", out HTuple dataCodeHandle);
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "timeout", 1000); //一个二维码的解码时间
//HOperatorSet.SetDataCode2dParam(dataCodeHandle, "symbol_size_min", 16); //码粒最小个数
//HOperatorSet.SetDataCode2dParam(dataCodeHandle, "symbol_size_max", 30); //码粒最大个数
if (i != 2)
{ {
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "module_size_min", 3); //码粒最小像素 Stopwatch stopwatch = new Stopwatch();
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "module_size_max", 20); //码粒最大像素 stopwatch.Start();
} HOperatorSet.Rgb1ToGray(hObj, out HObject grayImage);
HOperatorSet.FindDataCode2d(grayImage, out HObject symbolXLDs, dataCodeHandle, "stop_after_result_num", 5, out HTuple resultHandles, out HTuple decodedDataStrings); //支持‘Data Matrix ECC 200’、‘QR Code’和‘PDF417’共3种类型
//‘standard_recognition’、‘enhanced_recognition’、‘maximum_recognition’
HOperatorSet.CreateDataCode2dModel(ctype, "default_parameters", "maximum_recognition", out HTuple dataCodeHandle);
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "timeout", 1000); //一个二维码的解码时间
//HOperatorSet.SetDataCode2dParam(dataCodeHandle, "symbol_size_min", 16); //码粒最小个数
//HOperatorSet.SetDataCode2dParam(dataCodeHandle, "symbol_size_max", 30); //码粒最大个数
if (ctype != "PDF417")
{
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "module_size_min", 3); //码粒最小像素
HOperatorSet.SetDataCode2dParam(dataCodeHandle, "module_size_max", 20); //码粒最大像素
}
HOperatorSet.FindDataCode2d(grayImage, out HObject symbolXLDs, dataCodeHandle, "stop_after_result_num", 5, out HTuple resultHandles, out HTuple decodedDataStrings);
//码粒的个数 //码粒的个数
HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "symbol_rows", out HTuple _rows); HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "symbol_rows", out HTuple _rows);
HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "symbol_cols", out HTuple _cols); HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "symbol_cols", out HTuple _cols);
//每个码粒的宽高 //每个码粒的宽高
HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "module_height", out HTuple _height); HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "module_height", out HTuple _height);
HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "module_width", out HTuple _width); HOperatorSet.GetDataCode2dResults(dataCodeHandle, "all_results", "module_width", out HTuple _width);
HOperatorSet.AreaCenterXld(symbolXLDs, out HTuple hv_Area, out HTuple hv_Row, out HTuple hv_Column, out HTuple hv_PointOrder); HOperatorSet.AreaCenterXld(symbolXLDs, out HTuple hv_Area, out HTuple hv_Row, out HTuple hv_Column, out HTuple hv_PointOrder);
//释放 //释放
HOperatorSet.ClearDataCode2dModel(dataCodeHandle); HOperatorSet.ClearDataCode2dModel(dataCodeHandle);
Common.log.Info("Halcon Extract2DCode " + type[i] + " Count=" + decodedDataStrings.Length); stopwatch.Stop();
Common.log.Info("Halcon Extract2DCode " + ctype + " Count=" + decodedDataStrings.Length +" time:"+ stopwatch.ElapsedMilliseconds);
if (decodedDataStrings.Length > 0) if (decodedDataStrings.Length > 0)
{
int n = decodedDataStrings.SArr.Length;
for (int j = 0; j < n; j++)
{ {
BarcodeInfo info = new() int n = decodedDataStrings.SArr.Length;
for (int j = 0; j < n; j++)
{ {
Text = decodedDataStrings.SArr[j].Trim(), BarcodeInfo info = new()
CodeType = type[j], {
Angle = 0, Text = decodedDataStrings.SArr[j].Trim(),
Center = new PointF(Convert.ToSingle(hv_Column.DArr[j] / zoom), Convert.ToSingle(hv_Row.DArr[j] / zoom)), CodeType = ctype,
Size = new SizeF(Convert.ToSingle(_cols.LArr[j] * _width.DArr[j]), Convert.ToSingle(_rows.LArr[j] * _height.DArr[j])), Angle = 0,
Distance = 0 Center = new PointF(Convert.ToSingle(hv_Column.DArr[j] / zoom), Convert.ToSingle(hv_Row.DArr[j] / zoom)),
}; Size = new SizeF(Convert.ToSingle(_cols.LArr[j] * _width.DArr[j]), Convert.ToSingle(_rows.LArr[j] * _height.DArr[j])),
codeInfo.Add(info); Distance = 0
};
lock (codeInfo)
{
codeInfo.Add(info);
}
}
} }
} }
} catch (Exception ex)
} {
catch (Exception ex) Common.log.Error("Extract2DCode", ex);
{ }
Common.log.Error("Extract2DCode", ex); });
} }
Task.WaitAll(tasks,5000);
return codeInfo; return codeInfo;
} }
......
...@@ -27,5 +27,5 @@ D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.GenerateResou ...@@ -27,5 +27,5 @@ D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.GenerateResou
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.CoreCompileInputs.cache D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.CoreCompileInputs.cache
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\Asa.Camera.VisionLib.dll D:\rick\vs\Camera\CameraVisionLib\obj\Debug\Asa.Camera.VisionLib.dll
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\Asa.Camera.VisionLib.pdb D:\rick\vs\Camera\CameraVisionLib\obj\Debug\Asa.Camera.VisionLib.pdb
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.AssemblyReference.cache
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.CopyComplete D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.CopyComplete
D:\rick\vs\Camera\CameraVisionLib\obj\Debug\CameraVisionLib.csproj.AssemblyReference.cache
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!