/// <summary> /// Takes blobs information based on colors in <see cref="hsv"/> list and then sends the info through UDP. /// </summary> /// <param name="sourceImage">Image in Mat format.</param> /// <returns>Image in Mat format.</returns> private Mat Renderer(Mat sourceImage) { Mat dstNoisy = src; Mat dstClear = new Mat(); Mat dst = new Mat(); Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(2 * MorphValue + 1, 2 * MorphValue + 1)); Cv2.Blur(dstNoisy, dstClear, new Size(9, 9)); Cv2.CvtColor(dstClear, dst, ColorConversionCodes.BGR2HSV); // Convert BGR to HSV. Mat dstThreshed = new Mat(); Mat dstPreview = new Mat(); if (hsv.Count > 0) { int blobCount = 1; bool theFirst = true; foreach (int[] scal in hsv) { if (theFirst) { Cv2.InRange(dst, new Scalar(scal[0] - 10, scal[1], scal[3]), new Scalar(scal[0] + 10, scal[2], scal[4]), dstPreview); theFirst = false; } else { Mat dstPreview2 = new Mat(); Cv2.InRange(dst, new Scalar(scal[0] - 10, scal[1], scal[3]), new Scalar(scal[0] + 10, scal[2], scal[4]), dstPreview2); Cv2.AddWeighted(dstThreshed, 1.0, dstPreview2, 1.0, 0.0, dstPreview); } Cv2.InRange(dst, new Scalar(scal[0] - 10, scal[1], scal[3]), new Scalar(scal[0] + 10, scal[2], scal[4]), dstThreshed); // Morphologic transformation to close the gaps inside the blob. Cv2.MorphologyEx(src: dstThreshed, dst: dstThreshed, op: MorphTypes.Close, element: element ); blobDetection.Label(dstThreshed); blobDetection.FilterByArea(MinBlobArea, MaxBlobArea); blobDetection.RenderBlobs(dstThreshed, src); CircleSegment[] circles = Cv2.HoughCircles(dstThreshed, HoughMethods.Gradient, 1, dstThreshed.Rows / 8); // Creates all udp datagrams---------------------------------------------------- if (blobDetection.Count != 0) { for (int i = 0; i < blobDetection.Count; i++) { int processKey = blobDetection.ElementAt(i).Key; udpDatagram_1 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]mesh,sample,"; for (int j = 0; j < blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).Count; j++) { if (orientation) { udpDatagram_1 += Math.Round((float)blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).ElementAt(j).X / dst.Cols, 4).ToString().Replace(',', '.'); udpDatagram_1 += "," + (1 - Math.Round((float)blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).ElementAt(j).Y / dst.Rows, 4)).ToString().Replace(',', '.'); udpDatagram_1 += ","; } else { udpDatagram_1 += (1 - Math.Round((float)blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).ElementAt(j).X / dst.Cols, 4)).ToString().Replace(',', '.'); udpDatagram_1 += "," + Math.Round((float)blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).ElementAt(j).Y / dst.Rows, 4).ToString().Replace(',', '.'); udpDatagram_1 += ","; } } udpDatagram_1 += ";"; udpDatagram_2 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]area,"; udpDatagram_2 += "value," + blobDetection[processKey].Contour.ConvertToPolygon().Simplify(1).Area().ToString().Replace(',', '.') + ";"; udpDatagram_3 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]place,"; if (orientation) { udpDatagram_3 += "position," + (Math.Round(blobDetection[processKey].Centroid.X / dst.Cols, 3)).ToString().Replace(',', '.') + "," + (Math.Round(1 - (blobDetection[processKey].Centroid.Y / dst.Rows), 3)).ToString().Replace(',', '.') + ";"; } else { udpDatagram_3 += "position," + (Math.Round(1 - (blobDetection[processKey].Centroid.X / dst.Cols), 3)).ToString().Replace(',', '.') + "," + (Math.Round(blobDetection[processKey].Centroid.Y / dst.Rows, 3)).ToString().Replace(',', '.') + ";"; } udpDatagram_4 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]color,"; udpDatagram_4 += "hsv," + scal[0] + "-" + (scal[1] + scal[2]) / 2 + "-" + (scal[3] + scal[4]) / 2 + ";"; //Geometry udpDatagram_5 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]form,geometry,"; CvContourPolygon poly = blobDetection[processKey].Contour.ConvertToPolygon(); double epsilon = 0.04 * Cv2.ArcLength(poly, true); Point[] counterResult = Cv2.ApproxPolyDP(poly, epsilon, closed: true); int contourSimple_counter = counterResult.Length; string geometry = ""; switch (contourSimple_counter) { case 3: geometry = "triangle"; break; case 4: Rect rect = Cv2.BoundingRect(poly); float aspectRatio = 0; if (rect.Y != 0) { aspectRatio = rect.X / rect.Y; } if (aspectRatio >= 0.95 && aspectRatio <= 1.05) { geometry = "square"; } else { geometry = "rectangle"; } break; default: geometry = "unidentified" + contourSimple_counter; break; } udpDatagram_5 += geometry + ";"; if (BlobLabel) { Cv2.PutText(src, geometry, blobDetection[processKey].Centroid, HersheyFonts.HersheySimplex, 0.5, new Scalar(0, 255, 0), 2); Cv2.PutText(src, "[" + scal[0] + ", " + ((scal[1] + scal[2]) / 2) + ", " + ((scal[3] + scal[4]) / 2) + "]", new Point(blobDetection[processKey].Centroid.X, blobDetection[processKey].Centroid.Y + 20), HersheyFonts.HersheySimplex, 0.45, new Scalar(0, 255, 0), 2); } udpDatagram_6 = "[$]tracking|id=" + data_id + "|label=" + blobCount + "|[$$]" + deviceName + ",[$$$]perimeter,value,"; udpDatagram_6 += blobDetection[processKey].Contour.Perimeter().ToString().Replace(',', '.') + ";"; // UDP sender--------------------------------------------------------------------- try { byte[] sendBytes_1 = Encoding.ASCII.GetBytes(udpDatagram_1); byte[] sendBytes_2 = Encoding.ASCII.GetBytes(udpDatagram_2); byte[] sendBytes_3 = Encoding.ASCII.GetBytes(udpDatagram_3); byte[] sendBytes_4 = Encoding.ASCII.GetBytes(udpDatagram_4); byte[] sendBytes_5 = Encoding.ASCII.GetBytes(udpDatagram_5); byte[] sendBytes_6 = Encoding.ASCII.GetBytes(udpDatagram_6); udpClient.Send(sendBytes_1, sendBytes_1.Length, IP_udp, Port_udp); udpClient.Send(sendBytes_2, sendBytes_2.Length, IP_udp, Port_udp); udpClient.Send(sendBytes_3, sendBytes_3.Length, IP_udp, Port_udp); udpClient.Send(sendBytes_4, sendBytes_4.Length, IP_udp, Port_udp); udpClient.Send(sendBytes_5, sendBytes_5.Length, IP_udp, Port_udp); udpClient.Send(sendBytes_6, sendBytes_6.Length, IP_udp, Port_udp); } catch (Exception e) { Console.WriteLine(e.ToString()); } udpDatagram_1 = ""; udpDatagram_2 = ""; udpDatagram_3 = ""; udpDatagram_4 = ""; blobCount++; } } } blobCount = 1; } // Same morphologic transformation but this time for the output image. Cv2.MorphologyEx(src: dstPreview, dst: dstPreview, op: MorphTypes.Close, element: element ); return(dstPreview); }