// Use this for initialization void Run() { //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console. Utils.setDebugMode(true); Mat img = Imgcodecs.imread(image_filepath, Imgcodecs.IMREAD_COLOR); if (img.empty()) { Debug.LogError(image_filepath + " is not loaded. Please see \"StreamingAssets/dnn/setup_dnn_module.pdf\". "); img = new Mat(368, 368, CvType.CV_8UC3, new Scalar(0, 0, 0)); } //Adust Quad.transform.localScale. gameObject.transform.localScale = new Vector3(img.width(), img.height(), 1); Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation); float imageWidth = img.width(); float imageHeight = img.height(); float widthScale = (float)Screen.width / imageWidth; float heightScale = (float)Screen.height / imageHeight; if (widthScale < heightScale) { Camera.main.orthographicSize = (imageWidth * (float)Screen.height / (float)Screen.width) / 2; } else { Camera.main.orthographicSize = imageHeight / 2; } Net detector = null; Net recognizer = null; if (string.IsNullOrEmpty(detectionmodel_filepath) || string.IsNullOrEmpty(recognitionmodel_filepath)) { Debug.LogError(detectionmodel_filepath + " or " + recognitionmodel_filepath + " is not loaded. Please see \"StreamingAssets/dnn/setup_dnn_module.pdf\". "); } else { detector = Dnn.readNet(detectionmodel_filepath); recognizer = Dnn.readNet(recognitionmodel_filepath); } if (detector == null || recognizer == null) { Imgproc.putText(img, "model file is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false); Imgproc.putText(img, "Please read console message.", new Point(5, img.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false); } else { TickMeter tickMeter = new TickMeter(); List <Mat> outs = new List <Mat>(); List <string> outNames = new List <string>(); outNames.Add("feature_fusion/Conv_7/Sigmoid"); outNames.Add("feature_fusion/concat_3"); // Create a 4D blob from a frame. Size inpSize = new Size(inpWidth > 0 ? inpWidth : img.cols(), inpHeight > 0 ? inpHeight : img.rows()); Mat blob = Dnn.blobFromImage(img, 1.0, inpSize, new Scalar(123.68, 116.78, 103.94), true, false); // blobFromImage(frame, blob, 1.0, Size(inpWidth, inpHeight), Scalar(123.68, 116.78, 103.94), true, false); // Run detection model. detector.setInput(blob); tickMeter.start(); detector.forward(outs, outNames); tickMeter.stop(); Mat scores = outs[0]; Mat geometry = outs[1]; // Decode predicted bounding boxes. List <RotatedRect> boxes = new List <RotatedRect>(); List <float> confidences = new List <float>(); decodeBoundingBoxes(scores, geometry, confThreshold, boxes, confidences); // Apply non-maximum suppression procedure. MatOfRotatedRect boxesMat = new MatOfRotatedRect(boxes.ToArray()); MatOfFloat confidencesMat = new MatOfFloat(confidences.ToArray()); MatOfInt indicesMat = new MatOfInt(); Dnn.NMSBoxesRotated(boxesMat, confidencesMat, confThreshold, nmsThreshold, indicesMat); List <int> indices = indicesMat.toList(); Point ratio = new Point(img.cols() / inpWidth, img.rows() / inpHeight); // Render text. for (int i = 0; i < indices.Count; ++i) { RotatedRect box = boxes[indices[i]]; Point[] vertices = new Point[4]; box.points(vertices); for (int j = 0; j < 4; ++j) { vertices[j].x *= ratio.x; vertices[j].y *= ratio.y; } for (int j = 0; j < 4; ++j) { Imgproc.line(img, vertices[j], vertices[(j + 1) % 4], new Scalar(0, 255, 0), 1); } if (recognizer != null) { Mat cropped = new Mat(); fourPointsTransform(img, vertices, cropped); //Debug.Log(cropped); Imgproc.cvtColor(cropped, cropped, Imgproc.COLOR_BGR2GRAY); Mat blobCrop = Dnn.blobFromImage(cropped, 1.0 / 127.5, new Size(), Scalar.all(127.5)); recognizer.setInput(blobCrop); //Debug.Log(blobCrop); tickMeter.start(); Mat result = recognizer.forward(); tickMeter.stop(); string wordRecognized; decodeText(result, out wordRecognized); Imgproc.putText(img, wordRecognized, vertices[1], Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(255, 0, 0), 1, Imgproc.LINE_AA, false); Debug.Log(wordRecognized); cropped.Dispose(); blobCrop.Dispose(); result.Dispose(); } } Debug.Log("Inference time, ms: " + tickMeter.getTimeMilli()); for (int i = 0; i < outs.Count; i++) { outs[i].Dispose(); } blob.Dispose(); detector.Dispose(); recognizer.Dispose(); } Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB); Texture2D texture = new Texture2D(img.cols(), img.rows(), TextureFormat.RGBA32, false); Utils.matToTexture2D(img, texture); gameObject.GetComponent <Renderer>().material.mainTexture = texture; Utils.setDebugMode(false); }