// 候補輪郭の円形度を計算する public void calcCircularity() { // 円形度 = 4π * S/L^2 (S = 面積, L = 図形の周囲長) double perimeter = Imgproc.arcLength(this.contour2f, true); this._circularity = 4.0 * Mathf.PI * this.area / (perimeter * perimeter); // perimeter = 0 のとき気をつける }
public static bool isHeart(List <Point> shape) { //Check number of vertices if (shape.Count < 20) { return(false); } MatOfPoint shape_area = new MatOfPoint(); shape_area.fromList(shape); MatOfPoint2f shape_area2f = new MatOfPoint2f(shape_area.toArray()); // if (Imgproc.contourArea(shape_area) > 6000) // return false; double area = Imgproc.contourArea(shape_area); double perim = Imgproc.arcLength(shape_area2f, true); double ratio = area / perim; if (ratio < 18 || ratio > 23) { return(false); } for (int i = 1; i < shape.Count; i++) { if (distanceTwoPoints(shape[i - 1], shape[i]) > 20) { return(true); } } return(false); }
private void GetCubies(List <MatOfPoint> contours, Mat imgMat, int index, List <Cubies> cubies) { MatOfPoint2f matOfPoint2f = new MatOfPoint2f(); MatOfPoint2f approxCurve = new MatOfPoint2f(); MatOfPoint approx = new MatOfPoint(); foreach (var contour in contours) { matOfPoint2f.fromList(contour.toList()); Imgproc.approxPolyDP(matOfPoint2f, approxCurve, 0.1 * Imgproc.arcLength(matOfPoint2f, true), true); try { approxCurve.convertTo(approx, CvType.CV_32S); OpenCVForUnity.Rect rect = Imgproc.boundingRect(approx); if (approx.total() == 4) { cubies.Add(new Cubies(rect.x, rect.y, colorsList[index])); Imgproc.rectangle(imgMat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 40, 150), 2); } } catch (ArgumentOutOfRangeException e) { } } print("Number of cubies: " + cubies.Count); }
public bool GetPosition(Mat frame, bool isKeyboardFound) { Mat frameProc = new Mat(); //frame.rows(), frame.cols(), CvType.CV_16UC3 Mat frameMask = new Mat(); Mat hierarchy = new Mat(); Imgproc.cvtColor(frame, frameProc, Imgproc.COLOR_BGR2HSV); Scalar lowerB = new Scalar(HueLower, SatLower, ValLower); Scalar upperB = new Scalar(HueUpper, SatUpper, ValUpper); Core.inRange(frameProc, lowerB, upperB, frameMask); Core.bitwise_and(frame, frame, frameProc, frameMask); //Imgproc.bilateralFilter(frameProc, frameProc, 9, 50, 100); Imgproc.morphologyEx(frameProc, frameProc, 2, Mat.ones(5, 5, CvType.CV_8U)); // Imgproc.dilate(frameProc, frameProc, Mat.ones(5, 5, CvType.CV_8U)); //Mat.ones(5, 5, CvType.CV_8U), anchor: new Point(-1, -1), iteration:2 Imgproc.cvtColor(frameProc, frameProc, Imgproc.COLOR_BGR2GRAY); List <MatOfPoint> contoursList = new List <MatOfPoint>(); Imgproc.findContours(frameProc, contoursList, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE); int count = 0; foreach (MatOfPoint contour in contoursList) { MatOfPoint2f approx = new MatOfPoint2f(); MatOfPoint2f contourf = new MatOfPoint2f(contour.toArray()); Imgproc.approxPolyDP(contourf, approx, 0.01 * Imgproc.arcLength(contourf, true), true); //print(approx.dump()); if (approx.rows() == 4 && Imgproc.contourArea(contour) >= min_area) { count++; if (count >= 2) { continue; } else { OpenCVForUnity.CoreModule.Rect track_win = Imgproc.boundingRect(approx); TrackWindow = new int[] { track_win.x, track_win.y, track_win.width, track_win.height }; if (frame.height() - 5 < TrackWindow[0] + TrackWindow[2] && TrackWindow[0] + TrackWindow[2] <= frame.height() || 0 <= TrackWindow[0] && TrackWindow[0] < 5 || frame.width() - 5 < TrackWindow[1] + TrackWindow[3] && TrackWindow[1] + TrackWindow[3] <= frame.width() || 0 <= TrackWindow[1] && TrackWindow[1] < 5) { continue; } else { Approx = approx; Contour = contour; return(isKeyboardFound = true); } } } } return(isKeyboardFound = false); }
public bool verificaImagemContorno(Texture2D textParam) { var bytes = textParam.EncodeToJPG(); File.WriteAllBytes("imagem1_tratamento.png", bytes); Texture2D camFoto = textParam; // Escala de cinza. CV_8UC1 Mat img1Mat = new Mat(camFoto.height, camFoto.width, CvType.CV_8UC1); Utils.texture2DToMat(camFoto, img1Mat); Imgproc.GaussianBlur(img1Mat, img1Mat, new Size(5, 5), 0); Texture2D tex3 = new Texture2D(img1Mat.cols(), img1Mat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(img1Mat, tex3); bytes = tex3.EncodeToJPG(); File.WriteAllBytes("imagem1_tratamento_gaussian.png", bytes); Imgproc.threshold(img1Mat, img1Mat, 120, 255, Imgproc.THRESH_BINARY); tex3 = new Texture2D(img1Mat.cols(), img1Mat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(img1Mat, tex3); bytes = tex3.EncodeToJPG(); File.WriteAllBytes("imagem1_tratamento_threshold.png", bytes); List <MatOfPoint> srcContours = new List <MatOfPoint>(); Mat srcHierarchy = new Mat(); Imgproc.findContours(img1Mat, srcContours, srcHierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE); int totalB = 0, totalQ = 0, totalR = 0, totalP; for (int i = 0; i < srcContours.Count; i++) { Imgproc.drawContours(img1Mat, srcContours, i, new Scalar(100, 100, 100), 2, 8, srcHierarchy, 0, new Point()); } tex3 = new Texture2D(img1Mat.cols(), img1Mat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(img1Mat, tex3); bytes = tex3.EncodeToJPG(); File.WriteAllBytes("imagem1_tratamento_findcountors.png", bytes); for (int i = 0; i < srcContours.Count; i++) { MatOfPoint2f mont = new MatOfPoint2f(srcContours[i].toArray()); var aprox = new MatOfPoint2f(); Imgproc.approxPolyDP(mont, aprox, 0.01 * Imgproc.arcLength(mont, true), true); Debug.Log(aprox.size()); //if (aprox.size().area == 3) //{ // Debug.Log("Triangulo"); //} } return(false); }
public void GenerateSVG(string path) { StringWriter svgWriter = new StringWriter(); Vector2 size = new Vector2(instance.imageProcessingResults[0].cols(), instance.imageProcessingResults[0].rows()); svgWriter.WriteLine("<svg width=\"" + size.x + "\" height=\"" + size.y + "\" xmlns=\"http://www.w3.org/2000/svg\">"); List <MatOfPoint> contours = new List <MatOfPoint>(); MatOfPoint2f approx = new MatOfPoint2f(); Mat srcHierarchy = new Mat(); int colorIndex = 0; foreach (var layer in instance.imageProcessingResults) { var background = yarnEntities.First(y => y.yarnPanel.isBackground && y.yarnPanel.yarnZone == YarnPanel.YarnZone.Weft); if (colorIndex != background.clusterId) { Imgproc.findContours(layer, contours, srcHierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); svgWriter.WriteLine("<g>"); for (int i = 0; i < contours.Count; i++) { MatOfPoint2f cnt = new MatOfPoint2f(contours[i].toArray()); double epsilon = 0.01 * Imgproc.arcLength(cnt, true); //Imgproc.approxPolyDP(cnt, approx, epsilon, true); approx = cnt; List <Point> contourList = approx.toList(); svgWriter.Write("<path fill=\"none\" stroke=\"#" + ColorUtility.ToHtmlStringRGB(instance.clusterList[colorIndex]) + "\" d=\"M"); for (int j = 0; j < contourList.Count; j++) { svgWriter.Write("" + contourList[j].x + " " + (size.y - contourList[j].y) + " L"); } svgWriter.GetStringBuilder().Length -= 1; //Eliminamos la última 'L' svgWriter.WriteLine("Z\" />"); } svgWriter.WriteLine("</g>"); } colorIndex++; } svgWriter.WriteLine("</svg>"); File.WriteAllText(path, svgWriter.ToString()); }
public string Detect(MatOfPoint2f c) { var shape = "Não identificado"; var peri = Imgproc.arcLength(c, true); var epsilon = 0.04 * peri; var aprox = new MatOfPoint2f(); Imgproc.approxPolyDP(c, aprox, epsilon, true); if (aprox.rows() == 3) { UnityEngine.Debug.Log("Triângulo"); //webCamTextureToMatHelper.Dispose(); } //else if (aprox.rows() == 4) //{ // shape = ""; // var rect = Imgproc.boundingRect(aprox); // var ar = rect.width / rect.height; // if (ar >= 0.95 && ar <= 1.05) // { // UnityEngine.Debug.Log("Quadrado"); // } // else // { // UnityEngine.Debug.Log("Retângulo"); // } //} //else if (aprox.rows() == 5) //{ // UnityEngine.Debug.Log("Pentágono"); //} //else if (aprox.rows() == 0) //{ // UnityEngine.Debug.Log("Círculo"); //} return(shape); }
private void Find4PointContours(Mat image, List <MatOfPoint> contours) { contours.Clear(); List <MatOfPoint> tmp_contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(image, tmp_contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); foreach (var cnt in tmp_contours) { MatOfInt hull = new MatOfInt(); Imgproc.convexHull(cnt, hull, false); Point[] cnt_arr = cnt.toArray(); int[] hull_arr = hull.toArray(); Point[] pts = new Point[hull_arr.Length]; for (int i = 0; i < hull_arr.Length; i++) { pts[i] = cnt_arr[hull_arr[i]]; } MatOfPoint2f ptsFC2 = new MatOfPoint2f(pts); MatOfPoint2f approxFC2 = new MatOfPoint2f(); MatOfPoint approxSC2 = new MatOfPoint(); double arclen = Imgproc.arcLength(ptsFC2, true); Imgproc.approxPolyDP(ptsFC2, approxFC2, 0.01 * arclen, true); approxFC2.convertTo(approxSC2, CvType.CV_32S); if (approxSC2.size().area() != 4) { continue; } contours.Add(approxSC2); } }
public void getAnswerNumber(Mat align) { Mat align_gray = new Mat(), align_edges = new Mat(); Imgproc.cvtColor(align, align_gray, Imgproc.COLOR_RGB2GRAY); Imgproc.Canny(align_gray, align_edges, 50, 50); Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(2 + 1, 2 + 1), new Point(1, 1)); Imgproc.dilate(align_edges, align_edges, element); //Shape detection List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(align_edges, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0)); List <MatOfPoint> hulls = new List <MatOfPoint>(); //Texture2D tex = new Texture2D(align_edges.width(), align_edges.height(), TextureFormat.RGB24, false); //Utils.matToTexture2D(align_edges, tex); //byte[] bytes1 = tex.EncodeToJPG(); //File.WriteAllBytes("D:/2019/OMR/" + "test.png", bytes1); for (int i = 0; i < contours.Count; i++) { MatOfInt hull_temp = new MatOfInt(); Imgproc.convexHull(contours[i], hull_temp); int[] arrIndex = hull_temp.toArray(); Point[] arrContour = contours[i].toArray(); Point[] arrPoints = new Point[arrIndex.Length]; for (int k = 0; k < arrIndex.Length; k++) { arrPoints[k] = arrContour[arrIndex[k]]; } MatOfPoint temp = new MatOfPoint(); temp.fromArray(arrPoints); //Filter outliers if (Imgproc.contourArea(temp) > 90000 && Imgproc.contourArea(temp) < 110000) { hulls.Add(temp); } } List <MatOfPoint2f> hull2f = new List <MatOfPoint2f>(); for (int i = 0; i < hulls.Count; i++) { MatOfPoint2f newPoint = new MatOfPoint2f(hulls[i].toArray()); hull2f.Add(newPoint); } List <Rect> rects = new List <Rect>(); for (int i = 0; i < hulls.Count; i++) { //Approximate polygon MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(hull2f[i], approx, 0.01 * Imgproc.arcLength(hull2f[i], true), true); List <Point> approx_polygon = approx.toList(); approx_polygon = Scannerproc.filterPolygon(approx_polygon); double area = Imgproc.contourArea(approx); if (Scannerproc.isSquare(approx_polygon)) { Rect r = Imgproc.boundingRect(new MatOfPoint(approx_polygon.ToArray())); bool isContain = false; for (int k = 0; k < rects.Count; k++) { if (Scannerproc.distanceTwoPoints(rects[k].tl(), r.tl()) < 100) { //if (rects[k].contains(r) || r.contains(rects[k])) isContain = true; } } if (!isContain) { rects.Add(r); // Imgproc.rectangle(align, r.tl(), r.br(), new Scalar(255, 0, 0, 255), 3); for (int j = 1; j < 21; j++) { Rect roi = new Rect((int)r.tl().x + (int)((r.width * 1.3) / 6), (int)r.tl().y + (r.height / 21) * j, (int)((r.width * 4.7) / 6), r.height / 21); int num = getAnswerNumber(align, roi); if (num != 0) { Imgproc.putText(align, " " + num, new Point(roi.x - 40, roi.y + 25), 1, 2, new Scalar(255, 0, 0, 255), 3, Core.LINE_AA, false); Imgproc.rectangle(align, roi.tl(), roi.br(), new Scalar(0, 255, 0, 255), 2); } } } } //Center of mass int cx = 0, cy = 0; for (int k = 0; k < approx_polygon.Count; k++) { cx += (int)approx_polygon[k].x; cy += (int)approx_polygon[k].y; } cx /= approx_polygon.Count; cy /= approx_polygon.Count; // Imgproc.circle(roi, new Point(cx, cy), 5, new Scalar(255), -1); } if (rects.Count == 4) { nowDetected = false; } }
// Update is called once per frame void Update() { Resources.UnloadUnusedAssets(); //Fixes the memory leak //Get new picture from camera imgTexture = new Texture2D(webcamTexture.width, webcamTexture.height); imgTexture.SetPixels(webcamTexture.GetPixels()); imgTexture.Apply(); Mat imgMat = new Mat(imgTexture.height, imgTexture.width, CvType.CV_8UC3); Utils.texture2DToMat(imgTexture, imgMat); Mat processedMat = new Mat(); Imgproc.dilate(imgMat, imgMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 1))); //Grayscale the picture Imgproc.cvtColor(imgMat, processedMat, Imgproc.COLOR_RGB2GRAY); //Blur the picture Imgproc.GaussianBlur(processedMat, processedMat, new Size(3, 3), 1); Imgproc.equalizeHist(processedMat, processedMat); //Find Edges Mat edgesOfPicture = new Mat(); Imgproc.Canny(processedMat, edgesOfPicture, 75, 225); List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(edgesOfPicture, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); MatOfPoint2f matOfPoint2f = new MatOfPoint2f(); MatOfPoint2f approxCurve = new MatOfPoint2f(); List <Rect> rects = new List <Rect>(); try { for (int idx = 0; idx >= 0; idx = (int)hierarchy.get(0, idx)[0]) { MatOfPoint contour = contours[idx]; Rect rect = Imgproc.boundingRect(contour); double contourArea = Imgproc.contourArea(contour); matOfPoint2f.fromList(contour.toList()); Imgproc.approxPolyDP(matOfPoint2f, approxCurve, Imgproc.arcLength(matOfPoint2f, true) * 0.02, true); long total = approxCurve.total(); if (total == 4) { ArrayList cos = new ArrayList(); Point[] points = approxCurve.toArray(); for (int j = 2; j < total + 1; j++) { cos.Add(angle(points[(int)(j % total)], points[j - 2], points[j - 1])); } cos.Sort(); Double minCos = (Double)cos[0]; Double maxCos = (Double)cos[cos.Count - 1]; bool isRect = total == 4 && minCos >= -0.1 && maxCos <= 0.3; if (isRect) { if (rect.width > 20) { rects.Add(rect); } List <double[]> Colors = new List <double[]>(); for (int op = 0; op < 10; op++) { if (rects.Count == 9) { allCubiesScaned = true; Color[] blockOfColour = imgTexture.GetPixels(rect.x + rect.width / 2, rect.y + rect.height, rect.width / 3, rect.height / 3, 0); float r = 0, g = 0, b = 0; foreach (Color pixelBlock in blockOfColour) { r += pixelBlock.r; g += pixelBlock.g; b += pixelBlock.b; } r = r / blockOfColour.Length; g = g / blockOfColour.Length; b = b / blockOfColour.Length; Rgb rgb = new Rgb(r, g, b); Colors.Add(new double[] { rgb.R * 255, rgb.G * 255, rgb.B * 255 }); print(Colors.Count); if (Colors.Count == 9) { ColorMap.Colors = Colors; ColorMap.Redraw(); } } } Imgproc.drawContours(imgMat, contours, idx, new Scalar(255, 100, 155), 4); } } } } catch (ArgumentOutOfRangeException e) { } Texture2D texture = new Texture2D(imgMat.cols(), imgMat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(imgMat, texture); gameObject.GetComponent <Renderer>().material.mainTexture = texture; }
void FormatImageSquare() { Mat mainMat = new Mat(baseTexture.height, baseTexture.width, CvType.CV_8UC3); Mat grayMat = new Mat(); //Convert Texture2d to Matrix Utils.texture2DToMat(baseTexture, mainMat); //copy main matrix to grayMat mainMat.copyTo(grayMat); //Convert color to gray Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_BGR2GRAY); //Blur Imgproc.GaussianBlur(grayMat, grayMat, new Size(25, 25), 0); //contrast Imgproc.threshold(grayMat, grayMat, 0, 255, Imgproc.THRESH_OTSU); //extract edge Imgproc.Canny(grayMat, grayMat, 50, 50); //prepare for the finding contours List <MatOfPoint> contours = new List <MatOfPoint>(); //find the contour from canny edge image Imgproc.findContours(grayMat, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); List <MatOfPoint> tempTargets = new List <MatOfPoint>(); for (int i = 0; i < contours.Count; i++) { MatOfPoint cp = contours[i]; MatOfPoint2f cn = new MatOfPoint2f(cp.toArray()); double p = Imgproc.arcLength(cn, true); MatOfPoint2f approx = new MatOfPoint2f(); //convret to polygon Imgproc.approxPolyDP(cn, approx, 0.03 * p, true); //find a contour with four points and large area int minContourArea = 10000; if (approx.toArray().Length == 4 && Imgproc.contourArea(approx) > minContourArea) { MatOfPoint approxPt = new MatOfPoint(); approx.convertTo(approxPt, CvType.CV_32S); float maxCosine = 0; for (int j = 2; j < 5; j++) { Vector2 v1 = new Vector2((float)(approx.toArray()[j % 4].x - approx.toArray()[j - 1].x), (float)(approx.toArray()[j % 4].y - approx.toArray()[j - 1].y)); Vector2 v2 = new Vector2((float)(approx.toArray()[j - 2].x - approx.toArray()[j - 1].x), (float)(approx.toArray()[j - 2].y - approx.toArray()[j - 1].y)); float angle = Mathf.Abs(Vector2.Angle(v1, v2)); maxCosine = Mathf.Max(maxCosine, angle); } if (maxCosine < 135f) { tempTargets.Add(approxPt); } } } if (tempTargets.Count > 0) { //Get the first contour MatOfPoint approxPt = tempTargets[0]; //Making Source Mat Mat srcPointMat = Converters.vector_Point_to_Mat(approxPt.toList(), CvType.CV_32F); //Making Destination Mat /*change these values*/ List <Point> dstPoints = new List <Point>(); dstPoints.Add(new Point(512, 0)); dstPoints.Add(new Point(0, 0)); dstPoints.Add(new Point(0, 512)); dstPoints.Add(new Point(512, 512)); Mat dstPointMat = Converters.vector_Point_to_Mat(dstPoints, CvType.CV_32F); //Make Perp transform Mat M = Imgproc.getPerspectiveTransform(srcPointMat, dstPointMat); Mat warpedMat = new Mat(mainMat.size(), mainMat.type()); //Crop and warp the image Imgproc.warpPerspective(mainMat, warpedMat, M, new Size(512, 512), Imgproc.INTER_LINEAR); warpedMat.convertTo(warpedMat, CvType.CV_8UC3); //Convert color to gray Imgproc.cvtColor(warpedMat, warpedMat, Imgproc.COLOR_BGR2GRAY); ////Blur //Imgproc.GaussianBlur(warpedMat, warpedMat, new Size(25, 25), 0); //contrast Imgproc.threshold(warpedMat, warpedMat, 0, 255, Imgproc.THRESH_OTSU); //resize Imgproc.resize(warpedMat, warpedMat, new Size(28, 28)); //Create an empty final texture finalTexture = new Texture2D(warpedMat.width(), warpedMat.height(), TextureFormat.RGB24, false); //Convert material to texture2d Utils.matToTexture2D(warpedMat, finalTexture); targetRawImage.texture = finalTexture; } }
void Start() { Mat mainMat = new Mat(baseTexture.height, baseTexture.width, CvType.CV_8UC3); Mat grayMat = new Mat(); sourceRawImage.texture = baseTexture; Utils.texture2DToMat(baseTexture, mainMat); mainMat.copyTo(grayMat); Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_BGR2GRAY); Imgproc.GaussianBlur(grayMat, grayMat, new Size(5, 5), 0); Imgproc.threshold(grayMat, grayMat, 110, 225, Imgproc.THRESH_BINARY); Imgproc.Canny(grayMat, grayMat, 20, 190); List <MatOfPoint> contours = new List <MatOfPoint>(); Imgproc.findContours(grayMat, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); int num = 0; List <MatOfPoint> contours_list = new List <MatOfPoint>(); // new logic // List<MatOfPoint> contours_list = new List<MatOfPoint>(); for (int i = 0; i < contours.Count; i++) { MatOfPoint cp = contours[i]; MatOfPoint2f cn = new MatOfPoint2f(cp.toArray()); double p = Imgproc.arcLength(cn, true); MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(cn, approx, 0.01 * p, true); double area = Imgproc.contourArea(contours[i]); if ((area > 30 && area < 100) && approx.toArray().Length > 8) { // Imgproc.drawContours(mainMat, contours, -1, new Scalar(0, 255, 0), 4); contours_list.Add(contours[i]); num = num + 1; Debug.Log(area); } } // previously working // for(int i =0; i< contours.Count ; i++){ // MatOfPoint cp = contours[i]; // MatOfPoint2f cn = new MatOfPoint2f(cp.toArray()); // double p = Imgproc.arcLength(cn,true); // // fron akshay file // double area = Imgproc.contourArea(contours[i]); // if(area > 50){ // Imgproc.drawContours(mainMat, contours, -1, new Scalar(0, 255, 0), 4); // num = num + 1; // Debug.Log(area); // } // } // for(int i =0; i< contours.Count ; i++){ // double area = Imgproc.contourArea(contours[i]); // if(area > 50){ // // Imgproc.drawContours(mainMat, contours, -1, new Scalar(0, 255, 0), 4); // contours_list.Add(contours[i]); // num = num + 1; // } // } for (int i = 0; i < contours_list.Count; i++) { Imgproc.drawContours(mainMat, contours_list, -1, new Scalar(0, 255, 0), 4); } Debug.Log("Number : " + num); info.text += (num - 1).ToString(); Texture2D finaltexture = new Texture2D(grayMat.cols(), grayMat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(grayMat, finaltexture); sourceRawImage.texture = finaltexture; }
private Mat findPaper(Mat mainMat) { Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_BGR2GRAY); // blur image Imgproc.GaussianBlur(grayMat, grayMat, new Size(5, 5), 0); grayMat.get(0, 0, grayPixels); for (int i = 0; i < grayPixels.Length; i++) { maskPixels[i] = 0; if (grayPixels[i] < 70) { grayPixels[i] = 0; //maskPixels [i] = 1; } else if (70 <= grayPixels[i] && grayPixels[i] < 120) { grayPixels[i] = 100; } else { grayPixels[i] = 255; //maskPixels [i] = 1; } } grayMat.put(0, 0, grayPixels); //thresholding make mage blake and white Imgproc.threshold(grayMat, grayMat, 0, 255, Imgproc.THRESH_OTSU); //extract the edge image Imgproc.Canny(grayMat, grayMat, 50, 50); //prepare for finding contours List <MatOfPoint> contours = new List <MatOfPoint>(); Imgproc.findContours(grayMat, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); List <MatOfPoint> tmpTargets = new List <MatOfPoint>(); for (int i = 0; i < contours.Count; i++) { MatOfPoint cp = contours[i]; MatOfPoint2f cn = new MatOfPoint2f(cp.toArray()); double p = Imgproc.arcLength(cn, true); MatOfPoint2f approx = new MatOfPoint2f(); // lager skew greater 0.03? //convert contours to readable polyagon Imgproc.approxPolyDP(cn, approx, 0.03 * p, true); //find contours with 4 points if (approx.toArray().Length == 4) { MatOfPoint approxPt = new MatOfPoint(); approx.convertTo(approxPt, CvType.CV_32S); float maxCosine = 0; float rate = 0; float min_length = 100000000000000; for (int j = 2; j < 5; j++) { Vector2 v1 = new Vector2((float)(approx.toArray()[j % 4].x - approx.toArray()[j - 1].x), (float)(approx.toArray()[j % 4].y - approx.toArray()[j - 1].y)); Vector2 v2 = new Vector2((float)(approx.toArray()[j - 2].x - approx.toArray()[j - 1].x), (float)(approx.toArray()[j - 2].y - approx.toArray()[j - 1].y)); float v1_length = Mathf.Sqrt(v1.x * v1.x + v1.y * v1.y); float v2_length = Mathf.Sqrt(v2.x * v2.x + v2.y * v2.y); min_length = Mathf.Min(Mathf.Min((float)(v1_length), (float)v2_length), min_length); if (v1_length > v2_length) { rate = v2_length / v1_length; } else { rate = v1_length / v2_length; } float angle = Mathf.Abs(Vector2.Angle(v1, v2)); maxCosine = Mathf.Max(maxCosine, angle); } if (min_length > 100 && maxCosine < 135f)// && rate >= 0.6 maxCosine < 135f && { tmpTargets.Add(approxPt); //Debug.Log("Length -----------" + min_length); //Debug.Log("------------rate" + rate + "---------------"); } } } if (tmpTargets.Count > 0) { // -----------------------DRAW RECTANGLE--------------------------- //MatOfPoint2f approxCurve = new MatOfPoint2f(); //for (int i = 0; i < tmpTargets.Count; i++) //{ // //Convert contours(i) from MatOfPoint to MatOfPoint2f // MatOfPoint2f contour2f = new MatOfPoint2f(tmpTargets[i].toArray()); // //Processing on mMOP2f1 which is in type MatOfPoint2f // double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02; // Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true); // //Convert back to MatOfPoint // MatOfPoint points = new MatOfPoint(approxCurve.toArray()); // // Get bounding rect of contour // OpenCVForUnity.Rect rect = Imgproc.boundingRect(points); // // draw enclosing rectangle (all same color, but you could use variable i to make them unique) // Imgproc.rectangle(mainMat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 130, 255), 3); // Imgproc.rectangle(mainMat, new Point(rect.x, rect.y), new Point(rect.x + 5, rect.y + 5), new Scalar(0, 0, 255), 5); // Imgproc.rectangle(mainMat, new Point(rect.x + rect.width, rect.y), new Point(rect.x + +rect.width + 5, rect.y + 5), new Scalar(0, 0, 255), 5); // Imgproc.rectangle(mainMat, new Point(rect.x + rect.width, rect.y + rect.height), new Point(rect.x + +rect.width + 5, rect.y + rect.height + 5), new Scalar(0, 0, 255), 5); // Imgproc.rectangle(mainMat, new Point(rect.x, rect.y + rect.height), new Point(rect.x + 5, rect.y + rect.height + 5), new Scalar(0, 0, 255), 5); //} // -----------------------DRAW RECTANGLE--------------------------- // get the first contours int largestPaper = findLargestContour(tmpTargets); //Debug.Log(largestPaper); // using the largest one paperCornerMatOfPoint = tmpTargets[largestPaper]; // draw boundary Imgproc.line(mainMat, paperCornerMatOfPoint.toList()[0], paperCornerMatOfPoint.toList()[1], new Scalar(0, 255, 0), 3); Imgproc.line(mainMat, paperCornerMatOfPoint.toList()[0], paperCornerMatOfPoint.toList()[3], new Scalar(0, 255, 0), 3); Imgproc.line(mainMat, paperCornerMatOfPoint.toList()[2], paperCornerMatOfPoint.toList()[3], new Scalar(0, 255, 0), 3); Imgproc.line(mainMat, paperCornerMatOfPoint.toList()[1], paperCornerMatOfPoint.toList()[2], new Scalar(0, 255, 0), 3); // extract target from the frame and adjust some angle.... Mat srcPointsMat = Converters.vector_Point_to_Mat(paperCornerMatOfPoint.toList(), CvType.CV_32F); List <Point> dstPoints = new List <Point>(); dstPoints.Add(new Point(0, 0)); dstPoints.Add(new Point(0, 300)); dstPoints.Add(new Point(200, 300)); dstPoints.Add(new Point(200, 0)); Mat dstPointsMat = Converters.vector_Point_to_Mat(dstPoints, CvType.CV_32F); //Make perspective transform Mat m = Imgproc.getPerspectiveTransform(srcPointsMat, dstPointsMat); Mat warpedMat = new Mat(mainMat.size(), mainMat.type()); Imgproc.warpPerspective(mainMat, warpedMat, m, new Size(200, 300), Imgproc.INTER_LINEAR); warpedMat.convertTo(warpedMat, CvType.CV_8UC3); Texture2D finalTargetTextue = new Texture2D(warpedMat.width(), warpedMat.height(), TextureFormat.RGB24, false); Utils.matToTexture2D(warpedMat, finalTargetTextue); targetRawImage.texture = finalTargetTextue; //Debug.Log(paperCornerMatOfPoint.toList()[0].ToString() + " " + paperCornerMatOfPoint.toList()[1].ToString()+ " " + paperCornerMatOfPoint.toList()[2].ToString()+ " " + paperCornerMatOfPoint.toList()[3].ToString()); } //-------------------------------------------------------- return(mainMat); }
// Update is called once per frame void Update() { Resources.UnloadUnusedAssets(); //Fixes the memory leak //Get new picture from camera imgTexture = new Texture2D(webcamTexture.width, webcamTexture.height); imgTexture.SetPixels(webcamTexture.GetPixels()); imgTexture.Apply(); Mat imgMat = new Mat(imgTexture.height, imgTexture.width, CvType.CV_8UC3); Utils.texture2DToMat(imgTexture, imgMat); Mat maskMat = new Mat(); Mat maskMatOP = new Mat(); Mat grayMat = new Mat(); Imgproc.dilate(imgMat, imgMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 1))); //Grayscale the picture Imgproc.cvtColor(imgMat, grayMat, Imgproc.COLOR_RGB2GRAY); //Blur the picture Imgproc.GaussianBlur(grayMat, grayMat, new Size(3, 3), 1); Imgproc.equalizeHist(grayMat, grayMat); //Find Edges Mat edgesOfPicture = new Mat(); Imgproc.Canny(grayMat, edgesOfPicture, 75, 225); List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(edgesOfPicture, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); MatOfPoint2f matOfPoint2f = new MatOfPoint2f(); MatOfPoint2f approxCurve = new MatOfPoint2f(); List <Rect> rectPre = new List <Rect>(); List <Rect> rectAfter = new List <Rect>(); try { List <MatOfPoint2f> kvadrater = new List <MatOfPoint2f>(); for (int idx = 0; idx >= 0; idx = (int)hierarchy.get(0, idx)[0]) { MatOfPoint contour = contours[idx]; Rect rect = Imgproc.boundingRect(contour); double contourArea = Imgproc.contourArea(contour); matOfPoint2f.fromList(contour.toList()); Imgproc.approxPolyDP(matOfPoint2f, approxCurve, Imgproc.arcLength(matOfPoint2f, true) * 0.02, true); long total = approxCurve.total(); if (total > 0) { kvadrater.Add(approxCurve); ArrayList cos = new ArrayList(); Point[] points = approxCurve.toArray(); for (int j = 2; j < total + 1; j++) { cos.Add(angle(points[(int)(j % total)], points[j - 2], points[j - 1])); } cos.Sort(); Double minCos = (Double)cos[0]; Double maxCos = (Double)cos[cos.Count - 1]; bool isRect = total == 4 && minCos >= -0.1 && maxCos <= 0.3; //List<double[]> Colors = new List<double[]>(); if (isRect) { if (rect.width > 20) { rectPre.Add(rect); } List <Color> Colors = new List <Color>(); List <double[]> colorDoubles = new List <double[]>(); for (int op = 0; op < 9; op++) { if (rectPre.Count == 9) { // print("Pre verify: " + rectPre.ToString()); //rectPre = CoordinateVerifier.Verify(rectPre); Använd inte LINQ !! ! ! ! ! // print("After verify: " + rectPre.ToString()); var punkt = imgTexture.GetPixel(rect.x + (rect.width / 2), rect.y + (rect.height / 2)); Imgproc.putText(imgMat, op.ToString(), new Point(rectPre[op].x + 20, rectPre[op].y + 30), Core.FONT_HERSHEY_DUPLEX, 3, new Scalar(200)); Rgb rgb = new Rgb(punkt.r, punkt.g, punkt.b); // print("rect[" + op + "] was found at" + rect.x.ToString() + "and y: " + rect.y.ToString()); var hsv = rgb.To <Hsv>(); String farg = "Ingen farg"; if (hsv.H >= 45 && hsv.H <= 70) { farg = "Gul"; } if (hsv.H >= 10 && hsv.H <= 45) { farg = "Orange"; } // print(farg); Colors.Clear(); for (int q = 0; q < rectPre.Count; q++) { Color[] blockOfColour = imgTexture.GetPixels(rectPre[q].x + (rectPre[q].width / 2), rectPre[q].y + (rectPre[q].height / 2), rectPre[q].width / 3, rectPre[q].height / 3, 0); float r = 0, g = 0, b = 0; foreach (Color pixelBlock in blockOfColour) { r += pixelBlock.r; g += pixelBlock.g; b += pixelBlock.b; } r = r / blockOfColour.Length; g = g / blockOfColour.Length; b = b / blockOfColour.Length; var eColor = _colorDetection.ColorEnumFromScalarColor(new double[] { r * 255, g * 255, b * 255 }); var color = ColorDetection.UnityColorFromEnum(eColor); Colors.Add(color); } if (Colors.Count == 9) { ColorTracker.Instance.addToTemp(Colors); foreach (Color c in Colors) { // print(c.ToString()); } } } } Imgproc.drawContours(imgMat, contours, idx, new Scalar(255, 100, 155), 4); } } } } catch (ArgumentOutOfRangeException e) { } Texture2D texture = new Texture2D(imgMat.cols(), imgMat.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(imgMat, texture); gameObject.GetComponent <Renderer>().material.mainTexture = texture; }
//public delegate void Process(int[] tgrdeteced); void tagramDetect(Mat t_rgbaMat, Action <TangramResultModel, List <MyShape> > prc) { List <MyShape> lms = new List <MyShape>(); System.Diagnostics.Stopwatch watch = null; long elapsedMs; TangramResultModel trm = null; Observable.Start(() => { mut.WaitOne(); Imgproc.resize(t_rgbaMat, rgbaMat, new Size(nW_goc, nH_goc)); watch = System.Diagnostics.Stopwatch.StartNew(); if (warp != null) { warp.Init(rgbaMat); Mat wMat = warp.warpPerspective(rgbaMat); rgbaMat = wMat.submat(0, nH, 0, nW); } else { rgbaMat = rgbaMat.submat(0, nH, 0, nW); } all_thresh = Mat.zeros(nH, nW, CvType.CV_8UC3); all_thresh_afct = Mat.zeros(nH, nW, CvType.CV_8UC3); dbMat = Mat.zeros(nH, nW, CvType.CV_8UC3); all_thresh_af = Mat.zeros(nH, nW, CvType.CV_8UC3); rgbaMat.copyTo(rgbMat); rgbMat.convertTo(rgbMat2, CvType.CV_8UC3, 0.8, 60); rgbMat2.copyTo(rgbMat2copy); rgbMat.convertTo(rgbMat3, CvType.CV_8UC3, 1, 60); rgbMat.convertTo(rgbMat4, CvType.CV_8UC3, 1.25, 35); rgbMat.convertTo(rgbMat, CvType.CV_8UC3, 1.25, 35); Imgproc.cvtColor(rgbMat, hsvMat, Imgproc.COLOR_RGB2HSV); Imgproc.cvtColor(rgbMat2, hsvMat2, Imgproc.COLOR_RGB2HSV); Imgproc.cvtColor(rgbMat3, hsvMat3, Imgproc.COLOR_RGB2HSV); Imgproc.cvtColor(rgbMat3, hsvMat4, Imgproc.COLOR_RGB2HSV); watch.Stop(); elapsedMs = watch.ElapsedMilliseconds; Mat markers = Mat.zeros(rgbaMat.size(), CvType.CV_32SC1); watch = System.Diagnostics.Stopwatch.StartNew(); for (int obj_i = 0; obj_i < ls_obj.Length; obj_i++) { var obj = ls_obj[obj_i]; if (obj_i == (int)tgr.ORANGE | obj_i == (int)tgr.YELLOW | obj_i == (int)tgr.GREEN) { Core.inRange(hsvMat2, obj.getHSVmin(), obj.getHSVmax(), thresholdMat); } else if (obj_i == (int)tgr.LIGHTBLUE) { Core.inRange(hsvMat, obj.getHSVmin(), obj.getHSVmax(), thresholdMat); } else { Core.inRange(hsvMat, obj.getHSVmin(), obj.getHSVmax(), thresholdMat); } if (obj_i == (int)tgr.RED) { Core.inRange(hsvMat, new Scalar(0, 20, 45), new Scalar(5, 255, 255), thresholdMat2); thresholdMat2.copyTo(thresholdMat, thresholdMat2); } thresholdMatArr[obj_i] = thresholdMat.clone(); } //thresholdMatArr[(int)tgr.LIGHTBLUE].setTo(new Scalar(0), thresholdMatArr[(int)tgr.BLUE]); //thresholdMatArr[(int)tgr.LIGHTBLUE].setTo(new Scalar(0), thresholdMatArr[(int)tgr.GREEN]); for (int obj_i = 0; obj_i < ls_obj.Length; obj_i++) { var obj = ls_obj[obj_i]; all_cts.Clear(); thresholdMat = thresholdMatArr[obj_i]; if (toggle_db[obj_i] == true) { all_thresh.setTo(obj.ColorRGB, thresholdMat); } if (true | obj_i == (int)tgr.PURPLE | obj_i == (int)tgr.YELLOW | obj_i == (int)tgr.RED | obj_i == (int)tgr.GREEN | obj_i == (int)tgr.ORANGE) { Imgproc.erode(thresholdMat, thresholdMat2, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)), new Point(-1, -1), 1); } if (obj_i == (int)tgr.LIGHTBLUE | obj_i == (int)tgr.PURPLE) { Imgproc.erode(thresholdMat, thresholdMat2, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)), new Point(-1, -1), 1); } if (toggle_db[obj_i] == true) { all_thresh_af.setTo(obj.ColorRGB, thresholdMat2); } all_thresh_afct.setTo(new Scalar(obj_i + 1), thresholdMat2); color_filter.Add(thresholdMat2.clone()); Imgproc.findContours(thresholdMat2, all_cts, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); Scalar c = obj.getColor(); for (int ct_i = 0; ct_i < all_cts.Count; ct_i++) { double area = Imgproc.contourArea(all_cts[ct_i]); // if (area < MIN_OBJECT_AREA) if (area < MIN_OBJECT_AREAS[obj_i] * 0.55) { all_cts.RemoveAt(ct_i); ct_i--; } if (area > MAX_OBJECT_AREAS[obj_i] * 1.3) { all_cts.RemoveAt(ct_i); ct_i--; } } MyShape chon = null; MyShape ms = new MyShape(); float dt = 1000000; for (int ct_i = 0; ct_i < all_cts.Count; ct_i++) { var ct = all_cts[ct_i]; var peri = Imgproc.arcLength(new MatOfPoint2f(ct.toArray()), true); var epsilon = 0.1 * peri; if (obj_i == (int)tgr.ORANGE || obj_i == (int)tgr.YELLOW) { epsilon = 0.065 * peri; } Imgproc.approxPolyDP(new MatOfPoint2f(ct.toArray()), approx_ct, epsilon, true); MatOfInt pts_cvh = new MatOfInt(); Imgproc.convexHull(ct, pts_cvh, true); var cvh_numPts = pts_cvh.toArray().Length; Point[] cvh_pts = new Point[cvh_numPts]; var ct_pts = ct.toArray(); for (int i = 0; i < cvh_numPts; i++) { var i1 = pts_cvh.toArray()[i]; var p1 = ct_pts[i1]; cvh_pts[i] = p1; try { if (debug == true) { var i2 = pts_cvh.toArray()[(i + 1) % cvh_numPts]; var p2 = ct_pts[i2]; Imgproc.circle(rgbMat2, p1, 1, c, 2); } } catch (Exception e) { Utilities.LogFormat("Here3:{0},{1},{2}", rgbMat2 == null, p1 == null, c == null); Utilities.Log("Exception is {0}", e.ToString()); Utilities.Log("Trace is {0}", e.StackTrace.ToString()); } } MatOfPoint2f approx_cvh = new MatOfPoint2f(); var epsilon2 = peri * 0.1; if (obj_i == (int)tgr.ORANGE) { epsilon2 = peri * 0.065; } Imgproc.approxPolyDP(new MatOfPoint2f(cvh_pts), approx_cvh, epsilon2, true); var ct_ori = new MatOfPoint(ct.toArray()); MatOfPoint approx_ct2 = new MatOfPoint(approx_ct.toArray()); List <MatOfPoint> approx_cvh2 = new List <MatOfPoint>(); approx_cvh2.Add(new MatOfPoint(approx_cvh.toArray())); var mu = Imgproc.moments(approx_cvh2[0], true); cterTgr.x = mu.m10 / mu.m00; cterTgr.y = mu.m01 / mu.m00; if (approx_ct2.size().height == 3 | approx_ct2.size().height == 4) { var points = approx_cvh2[0].toArray(); var numpoints = points.Length; ms._id = obj_i; ms.ps = new Point[numpoints]; double rat = 1.16; if (obj_i == (int)tgr.PURPLE) { rat = 1.20; } else if (obj_i == (int)tgr.LIGHTBLUE) { rat = 1.20; } else if (obj_i == (int)tgr.RED | obj_i == (int)tgr.BLUE) { rat = 1.09; } else if (obj_i == (int)tgr.YELLOW) { rat = 1.10; } else if (obj_i == (int)tgr.ORANGE) { rat = 1.10; } else if (obj_i == (int)tgr.GREEN) { rat = 1.10; } var ind_huyen = 0; var max = -1d; if (numpoints == 3 || numpoints == 4) { for (int p_i = 0; p_i < numpoints; p_i++) { var p = points[p_i]; var p2 = points[(p_i + 1) % numpoints]; var vect = p - cterTgr; vect = vect * rat; var p_new = cterTgr + vect; points[p_i].x = (int)(p_new.x * 100) / 100f; points[p_i].y = (int)(p_new.y * 100) / 100f; if (numpoints == 4) { ms.ps[p_i] = p_new; } if (numpoints == 3) { var vt = p2 - p; var length = vt.x * vt.x + vt.y * vt.y; if (length > max) { ind_huyen = p_i; max = length; } } } } if (numpoints == 3) { var i_nhon1 = ind_huyen; var i_nhon2 = (ind_huyen + 1) % numpoints; var i_vuong = (ind_huyen + 2) % numpoints; ms.ps[0] = points[i_vuong]; ms.ps[1] = points[i_nhon1]; ms.ps[2] = points[i_nhon2]; } else if (numpoints == 4) { if (obj_i == (int)tgr.ORANGE) { var vt_cheo1 = ms.ps[0] - ms.ps[2]; var vt_cheo2 = ms.ps[1] - ms.ps[3]; var leng_cheo1 = vt_cheo1.x * vt_cheo1.x + vt_cheo1.y * vt_cheo1.y; var leng_cheo2 = vt_cheo2.x * vt_cheo2.x + vt_cheo2.y * vt_cheo2.y; var i_nhon = 0; if (leng_cheo2 > leng_cheo1) { i_nhon = 1; } ms.ps[0] = points[i_nhon]; ms.ps[1] = points[(i_nhon + 1)]; ms.ps[2] = points[(i_nhon + 2)]; ms.ps[3] = points[(i_nhon + 3) % numpoints]; var i_prvNhon = (i_nhon + 4 - 1) % numpoints; var i_aftNhon = i_nhon + 1; var vt_prvNhon = points[i_prvNhon] - points[i_nhon]; var vt_aftNhon = points[i_aftNhon] - points[i_nhon]; var len_prvNhon = vt_prvNhon.x * vt_prvNhon.x + vt_prvNhon.y * vt_prvNhon.y; var len_aftNhon = vt_aftNhon.x * vt_aftNhon.x + vt_aftNhon.y * vt_aftNhon.y; Imgproc.line(dbMat, points[i_prvNhon], points[i_nhon], c, 1); if (len_prvNhon > len_aftNhon) { ms.isFlip = true; Imgproc.putText(dbMat, " IsFLIP", ms.ps[3], 1, 1, c, 1); } else { ms.isFlip = false; Imgproc.putText(dbMat, " IsNOTFLIP", ms.ps[3], 1, 1, c, 1); } } } var centerMat = new Point(rgbMat.width() / 2f, rgbMat.height() / 2f); var vtLech = centerMat - cterTgr; var dt2 = vtLech.x * vtLech.x + vtLech.y * vtLech.y; if (dt2 < dt) { chon = ms; } } try { Imgproc.circle(rgbMat, cterTgr, 1, c, 1); Imgproc.putText(rgbMat, mu.m00.ToString(), cterTgr, 1, 1, c, 1); } catch (Exception e) { Utilities.LogFormat("Here2:{0},{1},{2}", rgbMat == null, cterTgr == null, c == null); Utilities.Log("Exception is {0}", e.ToString()); Utilities.Log("Trace is {0}", e.StackTrace.ToString()); } //if (approx_ct2.size().height == 3 | approx_ct2.size().height == 4) break; } if (chon != null) { lms.Add(chon); var ps = chon.ps; for (int i = 0; i < ps.Length; i++) { var p1 = ps[i]; var p2 = ps[(i + 1) % ps.Length]; try { Imgproc.line(rgbMat2, p1, p2, c, 1); Imgproc.line(all_thresh_afct, p1, p2, new Scalar(255, 255, 255), 1); Imgproc.line(dbMat, p1, p2, c, 1); Imgproc.circle(dbMat, p1, 1, c); } catch (Exception e) { Utilities.LogFormat("Here1:{0},{1},{2}", rgbMat2 == null, p1 == null, p2 == null); Utilities.Log("Exception is {0}", e.ToString()); Utilities.Log("Trace is {0}", e.StackTrace.ToString()); } } } watch.Stop(); elapsedMs = watch.ElapsedMilliseconds; } TangramShape msl = new TangramShape(); msl.datas = lms; var json = JsonUtility.ToJson(msl); watch = System.Diagnostics.Stopwatch.StartNew(); trm = tangramFeatureModelList.Detect(msl.datas.ToArray()); watch.Stop(); elapsedMs = watch.ElapsedMilliseconds; mut.ReleaseMutex(); }).ObserveOnMainThread().Subscribe((rx) => { prc(trm, lms); if (debug == true) { mut.WaitOne(); if (texture != null && debug == true) { Utils.matToTexture2D(dbMat, texture); } if (dbText1 != null && debug == true) { Utils.matToTexture2D(rgbMat2copy, dbText1); } if (dbText2 != null && debug == true) { Utils.matToTexture2D(rgbMat3, dbText2); } if (dbText3 != null && debug == true) { Utils.matToTexture2D(rgbMat4, dbText3); } if (dbText4 != null && debug == true) { Utils.matToTexture2D(rgbMat, dbText4); } all_thresh_afct = all_thresh_afct * 25; Imgproc.cvtColor(rgbMat2, rgbMat2, Imgproc.COLOR_RGBA2RGB); Imgproc.cvtColor(all_thresh, all_thresh, Imgproc.COLOR_RGBA2RGB); Mat a = new Mat(all_thresh.size(), CvType.CV_8UC3); Core.addWeighted(all_thresh, 0.2, rgbMat2, 0.8, 0, a); if (dbText5 != null && debug == true) { Utils.matToTexture2D(a, dbText5); } if (dbText6 != null && debug == true) { Utils.matToTexture2D(all_thresh, dbText6); } if (dbText7 != null && debug == true) { Utils.matToTexture2D(all_thresh_afct, dbText7); } if (dbText8 != null && debug == true) { Utils.matToTexture2D(all_thresh_af, dbText8); } mut.ReleaseMutex(); } }); }
public int getAnswerNumber(Mat align, Rect r) { Mat roi = new Mat(align, r); Mat roi_gray = new Mat(), roi_edges = new Mat(); Imgproc.cvtColor(roi, roi_gray, Imgproc.COLOR_RGB2GRAY); Imgproc.Canny(roi_gray, roi_edges, 200, 200); // Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(2 + 1, 2 + 1), new Point(1, 1)); // Imgproc.dilate(roi_edges, roi_edges, element); //Shape detection List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(roi_edges, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0)); List <MatOfPoint> hulls = new List <MatOfPoint>(); for (int i = 0; i < contours.Count; i++) { MatOfInt hull_temp = new MatOfInt(); Imgproc.convexHull(contours[i], hull_temp); int[] arrIndex = hull_temp.toArray(); Point[] arrContour = contours[i].toArray(); Point[] arrPoints = new Point[arrIndex.Length]; for (int k = 0; k < arrIndex.Length; k++) { arrPoints[k] = arrContour[arrIndex[k]]; } MatOfPoint temp = new MatOfPoint(); temp.fromArray(arrPoints); //Filter outliers if (Imgproc.contourArea(temp) > 40 && Imgproc.contourArea(temp) < 200) { hulls.Add(temp); } } List <MatOfPoint2f> hull2f = new List <MatOfPoint2f>(); for (int i = 0; i < hulls.Count; i++) { MatOfPoint2f newPoint = new MatOfPoint2f(hulls[i].toArray()); hull2f.Add(newPoint); } for (int i = 0; i < hulls.Count; i++) { //Approximate polygon MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(hull2f[i], approx, 0.01 * Imgproc.arcLength(hull2f[i], true), true); List <Point> approx_polygon = approx.toList(); approx_polygon = Scannerproc.filterPolygon(approx_polygon); double area = Imgproc.contourArea(approx); //Center of mass int cx = 0, cy = 0; for (int k = 0; k < approx_polygon.Count; k++) { cx += (int)approx_polygon[k].x; cy += (int)approx_polygon[k].y; } cx /= approx_polygon.Count; cy /= approx_polygon.Count; // Imgproc.circle(roi, new Point(cx, cy), 5, new Scalar(255), -1); // Texture2D tex = new Texture2D(roi.width(), roi.height(), TextureFormat.RGB24, false); // Utils.matToTexture2D(roi, tex); // byte[] bytes1 = tex.EncodeToJPG(); // File.WriteAllBytes("D:/2019/OMR/" + "test.png", bytes1); Point pos1 = new Point((roi.width() * 1) / 10, cy); Point pos2 = new Point((roi.width() * 3) / 10, cy); Point pos3 = new Point((roi.width() * 5) / 10, cy); Point pos4 = new Point((roi.width() * 7) / 10, cy); Point pos5 = new Point((roi.width() * 9) / 10, cy); Point nowPos = new Point(cx, cy); double[] dist = new double[5]; dist[0] = Scannerproc.distanceTwoPoints(pos1, nowPos); dist[1] = Scannerproc.distanceTwoPoints(pos2, nowPos); dist[2] = Scannerproc.distanceTwoPoints(pos3, nowPos); dist[3] = Scannerproc.distanceTwoPoints(pos4, nowPos); dist[4] = Scannerproc.distanceTwoPoints(pos5, nowPos); int id = -1; double min_dist = 999999; for (int t = 0; t < 5; t++) { if (dist[t] < min_dist) { min_dist = dist[t]; id = t; } } return(id + 1); //return plusPoints(tl, new Point(cx, cy)); } return(0); }
string getFeatureTangram(string path) { Mat rgbMat = Imgcodecs.imread(path); var width = rgbMat.width(); var height = rgbMat.height(); var ofsetx = 0; var ofsety = 0; if (width > 4096) { ofsetx = (width - 4096) / 2; } if (height > 4096) { ofsety = (height - 4096) / 2; } var rat = (float)rgbMat.width() / (float)rgbMat.height(); Imgproc.cvtColor(rgbMat, rgbMat, Imgproc.COLOR_RGBA2BGR); Mat rgbMat2 = new Mat(rgbMat.size(), rgbMat.type()); if (debug == true) { mainDebug.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug1.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug2.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug3.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug4.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug5.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug6.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug7.GetComponent <AspectRatioFitter>().aspectRatio = rat; debug8.GetComponent <AspectRatioFitter>().aspectRatio = rat; } Mat hsvMat = new Mat(); Imgproc.cvtColor(rgbMat, hsvMat, Imgproc.COLOR_RGB2HSV); Debug.Log(rgbMat.width()); if (debug == true) { maxHeight = (int)(maxWidth / rat); texture = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt1 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt2 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt3 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt4 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt5 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt6 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt7 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); dbTxt8 = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false); mainDebug.texture = texture; debug1.texture = dbTxt1; debug2.texture = dbTxt2; debug3.texture = dbTxt3; debug4.texture = dbTxt4; debug5.texture = dbTxt5; debug6.texture = dbTxt6; debug7.texture = dbTxt7; debug8.texture = dbTxt8; } if (debug) { Mat a = new Mat(); Imgproc.resize(rgbMat, a, new Size(maxWidth, maxHeight)); Utils.matToTexture2D(a, dbTxt4); } Mat threshold = new Mat(); Mat threshold2 = new Mat(); List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); MatOfPoint2f mop2f = new MatOfPoint2f(); TangramShape blackShape = new TangramShape(); List <MyShape> ls_shapes = new List <MyShape>(); blackShape.datas = ls_shapes; bool[] OK = new bool[7]; for (var obj_i = 0; obj_i < 7; obj_i++) { var obj = ls_obj[obj_i]; Core.inRange(hsvMat, obj.HSVmin, obj.HSVmax, threshold); if (obj_i == (int)tgr.RED) { Core.inRange(hsvMat, obj.lower_HSVMin, obj.lower_HSVMax, threshold2); threshold2.copyTo(threshold, threshold2); } if (obj_i == (int)tgr.YELLOW) { if (debug) { matToTexture(threshold, dbTxt3); } } contours.Clear(); Imgproc.findContours(threshold, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); for (int ct_i = 0; ct_i < contours.Count; ct_i++) { if (Imgproc.contourArea(contours[ct_i]) < MIN_OBJECT_AREA) { contours.RemoveAt(ct_i); ct_i--; } } Scalar c = hsv2rgb(obj.getColor()); for (int ct_i = 0; ct_i < contours.Count; ct_i++) { var ct = contours[ct_i]; var peri = Imgproc.arcLength(new MatOfPoint2f(ct.toArray()), true); Imgproc.approxPolyDP(new MatOfPoint2f(ct.toArray()), mop2f, 0.05 * peri, true); { MyShape ms = new MyShape(); var points = mop2f.toArray(); var index = -1; var max = -1d; var numPoints = points.Length; ms._id = obj_i; ms.ps = new Point[numPoints]; if (numPoints == 3) { OK[obj_i] = true; for (var p_i = 0; p_i < numPoints; p_i++) { //Debug.LogFormat("p1 = {0}, p2 = {1}", p_i % numPoints, (p_i + 1) % numPoints); var p1 = points[p_i % numPoints]; var p2 = points[(p_i + 1) % numPoints]; var vt = p2 - p1; float len = (float)(vt.x * vt.x + vt.y * vt.y); if (len > max) { index = p_i; max = len; } } var i_nhon1 = index; var i_nhon2 = (index + 1) % numPoints; var i_vuong = (index + 2) % numPoints; ms.ps[0] = points[i_vuong]; ms.ps[1] = points[i_nhon1]; ms.ps[2] = points[i_nhon2]; Imgproc.putText(rgbMat2, "1", points[i_nhon1], 1, 20, c, 10); Imgproc.putText(rgbMat2, "2", points[i_nhon2], 1, 20, c, 10); Imgproc.putText(rgbMat2, "0", points[i_vuong], 1, 20, c, 10); } else if (numPoints == 4) { if (obj_i == (int)tgr.YELLOW) { OK[obj_i] = true; Debug.Log("Xin chao the mau vang"); ms.ps[0] = points[0]; ms.ps[1] = points[1]; ms.ps[2] = points[2]; ms.ps[3] = points[3]; } else if (obj_i == (int)tgr.ORANGE) { OK[obj_i] = true; Debug.Log("Xin chao the gioi"); var vt_cheo1 = points[0] - points[2]; var vt_cheo2 = points[1] - points[3]; var len_cheo1 = vt_cheo1.x * vt_cheo1.x + vt_cheo1.y * vt_cheo1.y; var len_cheo2 = vt_cheo2.x * vt_cheo2.x + vt_cheo2.y * vt_cheo2.y; var i_nhon = 0; if (len_cheo2 > len_cheo1) { i_nhon = 1; } ms.ps[0] = points[i_nhon]; ms.ps[1] = points[(i_nhon + 1)]; ms.ps[2] = points[(i_nhon + 2)]; ms.ps[3] = points[(i_nhon + 3) % numPoints]; var i_prvNhon = (i_nhon + 4 - 1) % numPoints; var i_aftNhon = i_nhon + 1; var vt_prvNhon = points[i_prvNhon] - points[i_nhon]; var vt_aftNhon = points[i_aftNhon] - points[i_nhon]; //Imgproc.line(rgbMat2, points[i_prvNhon], points[i_nhon], c, 10); var len_prvNhon = vt_prvNhon.x * vt_prvNhon.x + vt_prvNhon.y * vt_prvNhon.y; var len_aftNhon = vt_aftNhon.x * vt_aftNhon.x + vt_aftNhon.y * vt_aftNhon.y; if (len_prvNhon > len_aftNhon) { ms.isFlip = true; Imgproc.putText(rgbMat2, " IsFLIP", ms.ps[3], 1, 20, c, 10); } else { ms.isFlip = false; Imgproc.putText(rgbMat2, " IsNOTFLIP", ms.ps[3], 1, 20, c, 10); } Debug.Log(ms.ps.Length); Debug.Log((i_nhon + 3) % numPoints); if (debug == true) { Imgproc.putText(rgbMat2, "0", ms.ps[0], 1, 20, c, 10); Imgproc.putText(rgbMat2, "1", ms.ps[1], 1, 20, c, 10); Imgproc.putText(rgbMat2, "2", ms.ps[2], 1, 20, c, 10); Imgproc.putText(rgbMat2, "3", ms.ps[3], 1, 20, c, 10); } } } ls_shapes.Add(ms); } } } for (var ok_i = 0; ok_i < 7; ok_i++) { if (OK[ok_i] == false) { Debug.LogError("Sai mau: " + ok_i); } } if (debug) { Imgproc.circle(rgbMat2, new Point(1851, 3172), 20, yellow.getColor(), 10); Imgproc.circle(rgbMat2, new Point(1245, 2565), 20, yellow.getColor(), 10); Imgproc.circle(rgbMat2, new Point(883, 2925), 20, red.getColor(), 10); Imgproc.circle(rgbMat2, new Point(2100, 1709), 20, red.getColor(), 10); Mat a = new Mat(); Imgproc.resize(rgbMat, a, new Size(maxWidth, maxHeight)); Utils.matToTexture2D(a, texture); Imgproc.resize(hsvMat, a, new Size(maxWidth, maxHeight)); Utils.matToTexture2D(a, dbTxt1); Imgproc.resize(rgbMat2, a, new Size(maxWidth, maxHeight)); Utils.matToTexture2D(a, dbTxt2); } for (int i = 0; i < blackShape.datas.Count; i++) { for (int j = 0; j < blackShape.datas[i].ps.Length; j++) { blackShape.datas[i].ps[j].x -= ofsetx; blackShape.datas[i].ps[j].y -= ofsety; } } var json = JsonUtility.ToJson(blackShape); return(json); }
// Update is called once per frame void Update() { if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame()) { frame = webCamTextureToMatHelper.GetMat(); frame.copyTo(img_orig); drawing = img_orig.clone(); int lowThreshold = 50;// (int)200;// slider.value; const int ratio = 1; const int kernel_size = 3; Imgproc.cvtColor(img_orig, img_lab, Imgproc.COLOR_BGR2Lab); double omrSize = img_orig.cols() * img_orig.rows(); Imgproc.cvtColor(img_orig, img_gray, Imgproc.COLOR_RGBA2GRAY); Imgproc.GaussianBlur(img_gray, img_gray, new Size(15, 15), 1.5, 1.5); //Gaussian blur Imgproc.erode(img_gray, img_gray, new Mat(), new Point(-1, -1), 1); //Erosion // Imgproc.dilate(img_gray, img_gray, new Mat(), new Point(-1, -1), 10, 1, new Scalar(10)); //Dilation Imgproc.Canny(img_gray, img_edges, lowThreshold, lowThreshold * ratio, kernel_size, false); //Shape detection List <MatOfPoint> contours = new List <MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(img_edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0)); //Texture2D tex = new Texture2D(img_edges.width(), img_edges.height(), TextureFormat.RGB24, false); //Utils.matToTexture2D(img_edges, tex); //byte[] bytes1 = tex.EncodeToJPG(); //File.WriteAllBytes("D:/2019/OMR/" + "test213123.png", bytes1); List <MatOfPoint> hulls = new List <MatOfPoint>(); for (int i = 0; i < contours.Count; i++) { MatOfInt hull_temp = new MatOfInt(); Imgproc.convexHull(contours[i], hull_temp); int[] arrIndex = hull_temp.toArray(); Point[] arrContour = contours[i].toArray(); Point[] arrPoints = new Point[arrIndex.Length]; for (int k = 0; k < arrIndex.Length; k++) { arrPoints[k] = arrContour[arrIndex[k]]; } MatOfPoint temp = new MatOfPoint(); temp.fromArray(arrPoints); //Filter outliers if (Imgproc.contourArea(temp) > omrSize / 3 && Imgproc.contourArea(temp) < (omrSize * 4) / 5) { hulls.Add(temp); } } List <MatOfPoint2f> hull2f = new List <MatOfPoint2f>(); for (int i = 0; i < hulls.Count; i++) { MatOfPoint2f newPoint = new MatOfPoint2f(hulls[i].toArray()); hull2f.Add(newPoint); } for (int i = 0; i < hulls.Count; i++) { //Approximate polygon MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(hull2f[i], approx, 0.01 * Imgproc.arcLength(hull2f[i], true), true); List <Point> approx_polygon = approx.toList(); // approx_polygon = Scannerproc.filterPolygon(approx_polygon); // Debug.Log(approx_polygon.Count); if (!Scannerproc.isSquare(approx_polygon)) { continue; } else { nowRectPoints.Clear(); nowRectPoints.AddRange(approx_polygon); perspectiveAlign(); } //Center of mass int cx = 0, cy = 0; for (int k = 0; k < approx_polygon.Count; k++) { cx += (int)approx_polygon[k].x; cy += (int)approx_polygon[k].y; } cx /= approx_polygon.Count; cy /= approx_polygon.Count; Scannerproc.drawShape(drawing, approx_polygon, new Scalar(0, 255, 0)); } if (showTextureOnScreen) { showCurrentTextureOnScreen(); } } }