private void Targets(byte[,] array_Outline, int nx, int ny, double[] die_size) { ArrayList D = new ArrayList(); ArrayList C = getTargets(array_Outline, nx, ny); //建立目標物件集合 //過濾長寬不夠之物件 for (int k = 0; k < C.Count; k++) { TgInfo T = (TgInfo)C[k]; if (T.height < _img_height * 0.8 && T.width < _img_width * 0.8) { continue; } D.Add(T); } C = D; //依長寬排序 for (int i = 0; i < 10; i++) { for (int j = i + 1; j < C.Count; j++) { TgInfo T = (TgInfo)C[i], G = (TgInfo)C[j]; if (T.width + T.height < G.width + G.height) { C[i] = G; C[j] = T; } } } if (C.Count == 0) { throw new AvvaException("找不到切割道交點"); } Filter(C, nx, ny, die_size); }
private void Filter(ArrayList C, int nx, int ny, double[] die_size) { int top_x_add_all = 0; int left_y_add_all = 0; int right_y_add_all = 0; int down_x_add_all = 0; int counter = 0; List <float> angle_List = new List <float>(); TgInfo _target = (TgInfo)C[0]; _target.left_point_list = new List <Point>(); _target.right_point_list = new List <Point>(); _target.top_point_list = new List <Point>(); _target.down_point_list = new List <Point>(); _target.left_centerpoint_list = new List <Point>(); _target.right_centerpoint_list = new List <Point>(); _target.top_centerpoint_list = new List <Point>(); _target.down_centerpoint_list = new List <Point>(); Ver_Line.Clear(); Hor_Line.Clear(); //輪廓點內補滿 byte[,] Tbin = Fill(_target.P, nx, ny); #region 找出左右上下點集合 for (int m = 0; m < _target.P.Count; m++) { Point p = (Point)_target.P[m]; if (p.X == _target.xmn || p.X == _target.xmn + 1) { _target.left_point_list.Add(p); } if (p.X == _target.xmx || p.X == _target.xmx - 1) { _target.right_point_list.Add(p); } if (p.Y == _target.ymn || p.Y == _target.ymn + 1) { _target.top_point_list.Add(p); } if (p.Y == _target.ymx || p.Y == _target.ymx - 1) { _target.down_point_list.Add(p); } } _target.left_point_list = _target.left_point_list.OrderBy(p => p.Y).ToList(); _target.right_point_list = _target.right_point_list.OrderBy(p => p.Y).ToList(); _target.top_point_list = _target.top_point_list.OrderBy(p => p.X).ToList(); _target.down_point_list = _target.down_point_list.OrderBy(p => p.X).ToList(); #endregion #region 左右上下 center point list #region 左 center point list for (int l = 1; l < _target.left_point_list.Count; l++) { if (l == 1) { left_y_add_all = _target.left_point_list[0].Y; counter = 1; } if ((_target.left_point_list[l].Y - _target.left_point_list[l - 1].Y) < 9) { left_y_add_all = left_y_add_all + _target.left_point_list[l].Y; counter = counter + 1; } else { left_y_add_all = left_y_add_all / counter; _target.left_centerpoint_list.Add(new Point(_target.xmn, left_y_add_all)); left_y_add_all = _target.left_point_list[l].Y; counter = 1; } if (l == _target.left_point_list.Count - 1) { left_y_add_all = left_y_add_all / counter; _target.left_centerpoint_list.Add(new Point(_target.xmn, left_y_add_all)); left_y_add_all = 0; counter = 0; } } #endregion #region 右 center point list for (int l = 1; l < _target.right_point_list.Count; l++) { if (l == 1) { right_y_add_all = _target.right_point_list[0].Y; counter = 1; } if ((_target.right_point_list[l].Y - _target.right_point_list[l - 1].Y) < 9) { right_y_add_all = right_y_add_all + _target.right_point_list[l].Y; counter = counter + 1; } else { right_y_add_all = right_y_add_all / counter; _target.right_centerpoint_list.Add(new Point(_target.xmx, right_y_add_all)); right_y_add_all = _target.right_point_list[l].Y; counter = 1; } if (l == _target.right_point_list.Count - 1) { right_y_add_all = right_y_add_all / counter; _target.right_centerpoint_list.Add(new Point(_target.xmx, right_y_add_all)); right_y_add_all = 0; counter = 0; } } #endregion #region center point list for (int l = 1; l < _target.top_point_list.Count; l++) { if (l == 1) { top_x_add_all = _target.top_point_list[0].X; counter = 1; } if ((_target.top_point_list[l].X - _target.top_point_list[l - 1].X) < 9) { top_x_add_all = top_x_add_all + _target.top_point_list[l].X; counter = counter + 1; } else { top_x_add_all = top_x_add_all / counter; _target.top_centerpoint_list.Add(new Point(top_x_add_all, _target.ymn)); top_x_add_all = _target.top_point_list[l].X; counter = 1; } if (l == _target.top_point_list.Count - 1) { top_x_add_all = top_x_add_all / counter; _target.top_centerpoint_list.Add(new Point(top_x_add_all, _target.ymn)); top_x_add_all = 0; counter = 0; } } #endregion #region center point list for (int l = 1; l < _target.down_point_list.Count; l++) { if (l == 1) { down_x_add_all = _target.down_point_list[0].X; counter = 1; } if ((_target.down_point_list[l].X - _target.down_point_list[l - 1].X) < 9) { down_x_add_all = down_x_add_all + _target.down_point_list[l].X; counter = counter + 1; } else { down_x_add_all = down_x_add_all / counter; _target.down_centerpoint_list.Add(new Point(down_x_add_all, _target.ymx)); down_x_add_all = _target.down_point_list[l].X; counter = 1; } if (l == _target.down_point_list.Count - 1) { down_x_add_all = down_x_add_all / counter; _target.down_centerpoint_list.Add(new Point(down_x_add_all, _target.ymx)); down_x_add_all = 0; counter = 0; } } #endregion #endregion #region 刪除重複點 for (int i = _target.left_centerpoint_list.Count - 1; i > 0; i--) { if (_target.left_centerpoint_list[i].Y == _target.left_centerpoint_list[i - 1].Y) { _target.left_centerpoint_list.Remove(_target.left_centerpoint_list[i]); } } for (int i = _target.right_centerpoint_list.Count - 1; i > 0; i--) { if (_target.right_centerpoint_list[i].Y == _target.right_centerpoint_list[i - 1].Y) { _target.right_centerpoint_list.Remove(_target.right_centerpoint_list[i]); } } for (int i = _target.top_centerpoint_list.Count - 1; i > 0; i--) { if (_target.top_centerpoint_list[i].X == _target.top_centerpoint_list[i - 1].X) { _target.top_centerpoint_list.Remove(_target.top_centerpoint_list[i]); } } for (int i = _target.down_centerpoint_list.Count - 1; i > 0; i--) { if (_target.down_centerpoint_list[i].X == _target.down_centerpoint_list[i - 1].X) { _target.down_centerpoint_list.Remove(_target.down_centerpoint_list[i]); } } #endregion #region 找水平與垂直線 //找水平線 for (int w = 0; w < _target.left_centerpoint_list.Count; w++) { for (int s = 0; s < _target.right_centerpoint_list.Count; s++) { List <Point> Point_Set = new List <Point>(); int error_point = 0; for (int r = _target.xmn; r < _target.xmx + 1; r++) { Point p_H = new Point(); p_H = Point.Round(GetHorizontalLineY(_target.left_centerpoint_list[w], _target.right_centerpoint_list[s], r)); if (Tbin[r, p_H.Y] != 1) { //PointInLine = false; //break; error_point = error_point + 1; } } if (error_point < 200) { Point_Set.Add(_target.left_centerpoint_list[w]); Point_Set.Add(_target.right_centerpoint_list[s]); Hor_Line.Add(Point_Set); } } } // 找垂直線 for (int w = 0; w < _target.top_centerpoint_list.Count; w++) { for (int s = 0; s < _target.down_centerpoint_list.Count; s++) { List <Point> Point_Set = new List <Point>(); int error_point = 0; for (int r = _target.ymn; r < _target.ymx + 1; r++) { Point p_H = new Point(); p_H = Point.Round(GetVerticalLineX(_target.top_centerpoint_list[w], _target.down_centerpoint_list[s], r)); if (Tbin[p_H.X, r] != 1) { //PointInLine = false; //break; error_point = error_point + 1; } } if (error_point < 200) { Point_Set.Add(_target.top_centerpoint_list[w]); Point_Set.Add(_target.down_centerpoint_list[s]); Ver_Line.Add(Point_Set); } } } #endregion if (Hor_Line.Count == 0 && Ver_Line.Count == 0) { throw new AvvaException("影像中沒有切割道或交點"); } //只找到垂直切割道 if (Ver_Line.Count != 0 && Hor_Line.Count == 0) { for (int i = 0; i < Ver_Line.Count; i++) { angle_List.Add(Angle(Ver_Line[i][0], Ver_Line[i][1], new Point(Ver_Line[i][0].X, Ver_Line[i][0].Y + 1))); } } //只找到水平切割道 else if (Ver_Line.Count == 0 && Hor_Line.Count != 0) { for (int i = 0; i < Hor_Line.Count; i++) { angle_List.Add(Angle(Hor_Line[i][0], Hor_Line[i][1], new Point(Hor_Line[i][0].X + 1, Hor_Line[i][0].Y))); } } //找直線交點 else { List <List <Point> > intersect_list = new List <List <Point> >(); for (int h = 0; h < Hor_Line.Count; h++) { List <Point> intersect_row = new List <Point>(); for (int s = 0; s < Ver_Line.Count; s++) { Point centerpoint = Point.Round(GetIntersection(Hor_Line[h][0], Hor_Line[h][1], Ver_Line[s][0], Ver_Line[s][1])); angle_List.Add(Angle(centerpoint, Hor_Line[h][1], new Point(centerpoint.X + 1, centerpoint.Y))); intersect_row.Add(centerpoint); } intersect_list.Add(intersect_row); } FindDieSize(die_size, intersect_list); } AngleAverage = angle_List.Average(); _target_points = _target.P; }
private ArrayList getTargets(byte[,] q, int nx, int ny) { ArrayList A = new ArrayList(); byte[,] b = (byte[, ])q.Clone();//建立輪廓點陣列副本 for (int i = 1; i < nx - 1; i++) { for (int j = 1; j < ny - 1; j++) { if (b[i, j] == 0) { continue; } TgInfo G = new TgInfo(); G.xmn = i; G.xmx = i; G.ymn = j; G.ymx = j; G.P = new List <Point>(); ArrayList nc = new ArrayList(); //每一輪搜尋的起點集合 nc.Add(new Point(i, j)); //輸入之搜尋起點 G.P.Add(new Point(i, j)); b[i, j] = 0; //清除此起點之輪廓點標記 do { ArrayList nb = (ArrayList)nc.Clone(); //複製此輪之搜尋起點集合 nc = new ArrayList(); // 清除準備蒐集下一輪搜尋起點之集合 for (int m = 0; m < nb.Count; m++) { Point p = (Point)nb[m];//搜尋起點 //在此點周邊3X3區域內找輪廓點 for (int ii = p.X - 1; ii <= p.X + 1; ii++) { for (int jj = p.Y - 1; jj <= p.Y + 1; jj++) { //if (ii - 1 >= 0 && jj - 1 >= 0 &&ii+1<=f.ny&&jj+1<=f.nx) continue; //if (b[ii, jj] == 1 && b[ii - 1, jj] == 1 && b[ii + 1, jj] == 1 && b[ii, jj - 1] == 1 && b[ii, jj + 1] == 1&& b[i - 1, j-1] == 1&& b[i - 1, j+1] == 1&& b[i + 1, j-1] == 1&& b[i + 1, j+1] == 1) continue;//非輪廓點忽略 if (b[ii, jj] == 0) { continue; //非輪廓點忽略 } Point k = new Point(ii, jj); //建立點物件 nc.Add(k); //本輪搜尋新增的輪廓點 G.P.Add(k); G.np += 1; //點數累計 if (ii < G.xmn) { G.xmn = ii; } if (ii > G.xmx) { G.xmx = ii; } if (jj < G.ymn) { G.ymn = jj; } if (jj > G.ymx) { G.ymx = jj; } b[ii, jj] = 0;//清除輪廓點點標記 } } } } while (nc.Count > 0); //此輪搜尋有新發現輪廓點時繼續搜尋 //if (Z[i - 1, j] == 1) continue;//排除白色區塊的負目標,起點左邊是黑點 G.width = G.xmx - G.xmn + 1; //寬度計算 G.height = G.ymx - G.ymn + 1; //高度計算 A.Add(G); //加入有效目標集合 } } return(A); //回傳目標物件集合 }