LabelMachine.claclabel.cs
12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
using CodeLibrary;
using Newtonsoft.Json;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeviceLibrary
{
public partial class LabelMachine
{
SolidBrush blue = new SolidBrush(Color.BlueViolet);
SolidBrush red = new SolidBrush(Color.Red);
SolidBrush yellow = new SolidBrush(Color.Yellow);
SolidBrush AliceBlue = new SolidBrush(Color.AliceBlue);
Font font = new Font(FontFamily.GenericSansSerif, 60);
Pen Greenpen = new Pen(Color.Green, 10);
//Size pointsize = new Size(15, 15);
int pointsize = 16;
/// <summary>
/// 计算贴标位置
/// </summary>
/// <param name="Label_Pix_Point">二维码坐标</param>
/// <returns>XY轴贴标点,R轴角度,是否反转标签</returns>
public (Point, double, bool) ClacLabel(Point Label_Pix_Point)
{
bool ReverseLabel = false;
int Right_Batch_X = Config.Right_Batch_X;
if (MoveInfo.ReelParam.PlateW == 13)
{
Right_Batch_X = Right_Batch_X + Config.Label_Offset_Pixel_13;
}
else if (MoveInfo.ReelParam.PlateW == 15)
{
Right_Batch_X = Right_Batch_X + Config.Label_Offset_Pixel_15;
}
//照片中料盘中心点像素位置
Point Center_Pix_Point = new Point(Right_Batch_X, Config.Right_Batch_Y);
//二维码坐标
//Point Label_Pix_Point = new Point(X, Y);
//中心点到二维码角度,右侧为0度,+180转换到左侧为0度
var angle = Common.getAngle(Center_Pix_Point, Label_Pix_Point) + 180;
//中心点到二维码距离
var distance = Common.distance(Center_Pix_Point, Label_Pix_Point);
//中心点到标签中心的角度
double rr = 20;
var lr = Math.Cos(rr * Math.PI / 180);
//中心点到标签中心的距离
var ll = lr * distance;
//标签中心到盘心的坐标
var labelCenterAngle = rr + angle;
if (labelCenterAngle < 0)
labelCenterAngle = 360 + labelCenterAngle;
//标签中心的坐标
var labelCenter = Common.PointWithAngle(Center_Pix_Point, labelCenterAngle - 180, ll);
/*
//从二维码坐标开始, 往中心点坐标推移一定的距离,获得推移后的坐标
Point AxisPixPoint = Common.PointWithAngle(Label_Pix_Point, angle, Config.Label_R_Offset_Pixel);
//匹配角度与贴标旋转轴的角度差
var labelAngle = angle - Config.Label_R_Angle_Diff+360;
if (labelAngle > 360)
labelAngle -= 360;
*/
//因为标签不统一暂时改为以二维码为中心贴标
labelCenter = Label_Pix_Point;
labelCenterAngle = angle;
//贴标位置轴的像素坐标
Point AxisPixPoint = Common.PointWithAngle(labelCenter, labelCenterAngle, Config.Label_R_Offset_Pixel);
//计算贴标角度的脉冲值
//if (labelCenterAngle > Config.Label_R_MaxAngle)
//{
// ReverseLabel = true;
// labelCenterAngle -= 180;
//}
int labelAxisPos = (int)((double)Config.Label_R_360 / 335 * (double)labelCenterAngle);
MoveInfo.log($"计算结果,Label_R_360:{Config.Label_R_360},贴标角度:{labelCenterAngle},R轴:{labelAxisPos}");
//计算贴标像素点位与图像中心点的差
Point p1 = new Point(AxisPixPoint.X - Config.Right_Batch_X, AxisPixPoint.Y - Center_Pix_Point.Y);
//计算像素*脉冲像素比得到脉冲值+中心点基准脉冲
var x = (int)(p1.X * Config.Cam_Pixel_X_Ratio) + Config.Label_X_Base;
var y = (int)(p1.Y * Config.Cam_Pixel_Y_Ratio) + Config.Label_Y_Base;
p1.X = x;
p1.Y = y;
MoveInfo.log($"计算结果,图像像素中心{Center_Pix_Point},二维码像素坐标{Label_Pix_Point},角度{angle},贴标角度{labelCenterAngle},贴标像素点位为{AxisPixPoint},轴点位为{p1},R轴{labelAxisPos},盘宽{MoveInfo.ReelParam.PlateW}");
if (saveLabelDebugBmp)
{
IOMove(IO_Label_Type.Camera_Led, IO_VALUE.HIGH);
Task.Delay(10).Wait();
Bitmap bitmap = Camera._cam.GrabOneImage(Config.CameraName);
IOMove(IO_Label_Type.Camera_Led, IO_VALUE.LOW);
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
//Bitmap bitmap = new Bitmap("d:\\出料模块-20210424-043753-0162.bmp");
printLabelDebugBitmap(bitmap, Label_Pix_Point, Center_Pix_Point, AxisPixPoint, angle, p1, labelCenterAngle, labelAxisPos, labelCenter);
bitmap.Dispose();
}
return (p1, labelAxisPos, ReverseLabel);
}
void printLabelDebugBitmap(Bitmap srcbitmap, Point Label_Pix_Point, Point Center_Pix_Point, Point AxisPixPoint, double angle, Point AxisP1, double labelAngle, double labelAxisPos, Point labelCenter)
{
Bitmap bitmap = new Bitmap(srcbitmap.Width, srcbitmap.Height, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
g.DrawImage(srcbitmap, 0, 0);
srcbitmap.Dispose();
g.FillEllipse(blue, Common.EllipseCenter(Label_Pix_Point, pointsize));
g.FillEllipse(yellow, Common.EllipseCenter(Center_Pix_Point, pointsize));
g.FillEllipse(red, Common.EllipseCenter(AxisPixPoint, pointsize));
g.FillEllipse(AliceBlue, Common.EllipseCenter(labelCenter, pointsize));
g.DrawLine(Greenpen, AxisPixPoint, Label_Pix_Point);
g.DrawString($"angle:{angle}", font, blue, 0, 0);
g.DrawString($"AxisP1:{AxisP1}", font, red, 0, 80);
g.DrawString($"labelAngle:{labelAngle}/{labelAxisPos}", font, red, 0, 160);
g.Save();
Directory.CreateDirectory("/image/LabelDebug/");
bitmap.Save("/image/LabelDebug/" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".jpg", ImageFormat.Jpeg);
g.Dispose();
}
NamedPipeClient namedPipeClient = new NamedPipeClient("OcrService", ".");
/// <summary>
/// 计算贴标位置
/// </summary>
/// <param name="Label_Pix_Point">二维码坐标</param>
/// <returns>XY轴贴标点,R轴角度,是否反转标签</returns>
public (Point, double, bool) ClacLabel2(Point Label_Pix_Point, Bitmap bitmap, ReelParam reelParam)
{
OcrProcess.Run();
Point qrcenter = Label_Pix_Point;
//string file = @"D:\853string\Image_20210604173619489.bmp";
//图像剪切范围矩形
var orgCrop = Rectangle.Inflate(new Rectangle(qrcenter, new Size(1, 1)), 410, 410);
//计算剪切后的二维码中心坐标点
qrcenter.X = qrcenter.X - orgCrop.X;
qrcenter.Y = qrcenter.Y - orgCrop.Y;
///var bitmap = new Bitmap(file);
var b1 = Common.ImageCrop(bitmap, orgCrop);
//pictureBox1.Image = b1;// crop(bitmap, new Rectangle(0,0,bitmap.Width,bitmap.Height));
bitmap.Dispose();
Directory.CreateDirectory("/image/LabelDebug/");
string filename = "/image/LabelDebug/" + reelParam.ReeID + "-" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".temp.bmp";
b1.Save(filename);
//调用算法服务
var resp = namedPipeClient.Request(filename);
MoveInfo.log($"贴标OCR file:{filename}, 计算结果:" + resp);
//File.Delete(file + ".temp.bmp");
var l = JsonConvert.DeserializeObject<List<TextBlock>>(resp);
List<TextBlock> newlist = new List<TextBlock>();
//过滤合规数据
foreach (var t in l.ToArray())
{
//Console.WriteLine(Sim(t.Text, "PN+VC63.33034.L0L-018139"));
var s1 = Common.Sim(t.Text.Length >= 27 ? t.Text.Substring(0, 27) : t.Text, "PN+VC:"+ reelParam.PN);
var s2 = Common.Sim(t.Text.Length >= 6 ? t.Text.Substring(0, 6) : t.Text, "PN+VC:");
var s3 = Common.Sim(t.Text.Length >= 7 ? t.Text.Substring(0, 7) : "", "VPN:RTL");
MoveInfo.log($"text:{t.Text}");
MoveInfo.log($"s1:{s1}, s2:{s2}, s3:{s3}");
if ((s1 > 0.7 || s2 > 0.9) && s3 < 0.7 && t.Text.Length < 33)
{
newlist.Add(t);
MoveInfo.log($"s1:{s1}, s2:{s2} , {t.Text}");
}
}
//List<Point> RightPoint
Point labelPoint = Point.Empty;
double labelAngle = 0;
double lastDistance = 0;
TextBlock lasttextBlock = new TextBlock();
if (newlist.Count == 0)
{
MoveInfo.log($"贴标OCR 筛选结果失败");
return ClacLabel(Label_Pix_Point);
}
MoveInfo.log($"贴标OCR 筛选结果:" + JsonConvert.SerializeObject(newlist));
Graphics graphics = Graphics.FromImage(b1);
graphics.FillEllipse(AliceBlue, Common.EllipseCenter(qrcenter,pointsize));
foreach (var lp in newlist)
{
//textBox1.Text += JsonConvert.SerializeObject(lp) + "\r\n";
//字符起始位置左下角定位点
var sp = lp.BoxPoints;
var (dc, topindex) = Common.DistanceWithBoxAndPoint(sp, qrcenter);
if (dc > lastDistance)
{
lastDistance = dc;
lasttextBlock = lp;
var lf = (topindex == 0) ? 3 : topindex - 1;//左下角点位
var ld = (lf == 0) ? 3 : lf - 1;//横向点位
labelPoint = sp[lf];
labelAngle = Common.getAngle(sp[lf], sp[ld]) + 90;
}
for (int i = 0; i < lp.BoxPoints.Count; i++)
{
if (i == 0)
graphics.FillEllipse(blue, Common.EllipseCenter(lp.BoxPoints[i], pointsize));
else
graphics.FillEllipse(red, Common.EllipseCenter(lp.BoxPoints[i], pointsize));
}
}
graphics.FillEllipse(yellow, Common.EllipseCenter(labelPoint, pointsize) );
MoveInfo.log($"贴标OCR lasttextBlock:" + JsonConvert.SerializeObject(lasttextBlock));
//graphics.FillEllipse(red, new Rectangle(lc.X, lc.Y, pointsize.Width, pointsize.Height));
//纵向偏移
labelPoint = Common.PointWithAngle(labelPoint, labelAngle, Config.Label_Offset_Y);
//横向偏移
labelPoint = Common.PointWithAngle(labelPoint, labelAngle - 90, Config.Label_Offset_X);
graphics.FillEllipse(yellow, Common.EllipseCenter(labelPoint, pointsize));
graphics.Save();
graphics.Dispose();
b1.Save(filename+".result.jpg",ImageFormat.Jpeg);
b1.Dispose();
if (labelAngle < 0)
labelAngle = 360 + labelAngle;
//计算贴标角度的脉冲值
if (labelAngle > Config.Label_R_MaxAngle)
{
if (labelAngle > Config.Label_R_MaxAngle + (360 - labelAngle) / 2)
labelAngle = 0;
else
labelAngle = Config.Label_R_MaxAngle;
}
int labelAxisPos = (int)((double)Config.Label_R_360 / Config.Label_R_MaxAngle * (double)labelAngle);
//换算为剪切前的像素位置
labelPoint.Offset(orgCrop.X, orgCrop.Y);
//计算贴标像素点位与图像中心点的差
Point p2 = new Point(labelPoint.X - Config.Right_Batch_X, labelPoint.Y - Config.Right_Batch_Y);
//MoveInfo.log($"计算结果,Label_R_360:{Config.Label_R_360},贴标角度:{labelAngle},R轴:{labelAxisPos},贴标计算像素位置:{labelPoint},换算全图像素位置:{p1}");
//计算像素*脉冲像素比得到脉冲值+中心点基准脉冲
var x = (int)(p2.X * Config.Cam_Pixel_X_Ratio) + Config.Label_X_Base;
var y = (int)(p2.Y * Config.Cam_Pixel_Y_Ratio) + Config.Label_Y_Base;
Point p1 = new Point(x, y);
MoveInfo.log($"计算结果,Label_R_360:{Config.Label_R_360},贴标角度:{labelAngle},R轴:{labelAxisPos},贴标计算像素位置:{p2},换算伺服脉冲位置:{p1}");
return (p1, labelAxisPos, false);
}
}
}