Unityのスクリプトでthreadクラスを用いてサブスレッドを立てサブスレッド中でウェブカメラの画像処理をしているのですが,アプリを終了してもう一度Playボタンを押すとウェブカメラの画像が表示されなくなる問題が発生しています.Editerを起動し直してPlayすると問題ないのですが二回目から表示されなくなるので,終了したときにメモリの開放がうまくいってないのかと考えています.
原因と対策を教えていただけると助かります
言語:C#,OS:Win10,Unity:2018.2.2f1
コード using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Threading; using OpenCvSharp; using OpenCvSharp.Blob; using System; using System.IO; public class sdaaasdf : MonoBehaviour { private Thread _thread; private int i = 0; private Mat gameview; private Camera ConvertCamera; private Vector3 ScreenPt =new Vector3(0f,0f,0f); private Vector3 WorldPoint; private Vector3 MousePoint; void Start() { ConvertCamera = Camera.main; _thread = new Thread(Video); _thread.Start(); } void Video() { var frame = new Mat(); var frame2 = new Mat(); var gray = new Mat(); var gray2 = new Mat(); var binary = new Mat(); var binary2 = new Mat(); var diff = new Mat(); var find = new Mat(); var contours = new Mat[]{}; var hierarchy = new Mat(); var contours2 = new Mat[]{}; var video0 = new VideoCapture(0); // var video1 = new VideoCapture(1); while (true) { //webカメラ画像読み込み video0.Read(frame); //画像処理 binary = ImageProcessing(frame, 180); // ラベリング実行(必要な領域以外は排除) CvBlobs blobs = new CvBlobs(binary); //blobs.FilterByArea(2000, 7000); //for (int i = 1; i < blobs.Count; i++) //{ // var cvContour = blobs[i].Contour; // var L = cvContour.Perimeter(); // var area = blobs[i].Area; // var circularity = 4 * Math.PI * (area / (L * L)); // if (0.4 < circularity && circularity < 0.9) // { // blobs.FilterByLabel(i); // Debug.Log(circularity); // } //} // ラベリング結果の描画 var render = new Mat(frame.Rows, frame.Cols, MatType.CV_8UC3, 3); blobs.RenderBlobs(frame, render); //切り抜き CvBlob maxBlob = blobs.LargestBlob(); render = render[maxBlob.Rect]; //ここまでウェブカメラ画像の処理 //同様にしてゲームビュー画像の処理 binary2 = ImageProcessing(gameview, 50); CvBlobs blobs2 = new CvBlobs(binary2); var render2 = new Mat(gameview.Rows, gameview.Cols, MatType.CV_8UC3, 3); blobs2.RenderBlobs(gameview, render2); CvBlob maxBlob2 = blobs2.LargestBlob(); render2 = render2[maxBlob2.Rect]; //画像拡大縮小 Cv2.Resize(render, render, new OpenCvSharp.Size(render2.Width, render2.Height), 0, 0, InterpolationFlags.Cubic); //画像の差分計算 Cv2.Absdiff(render, render2, diff); //実影の認識 var binarydiff = ImageProcessing(diff, 150); CvBlobs diffblobs = new CvBlobs(binarydiff); var maxdiffblob = diffblobs.LargestBlob(); //var realshadow= diff[maxBlob.Rect]; //バウンディングボックス描画 binarydiff.FindContours(out contours, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone); for (int i = 0; i < contours.Length; i++) { var Rect = Cv2.BoundingRect(contours[i]); Cv2.Rectangle(binarydiff, new Point(Rect.X, Rect.Y), new Point(Rect.X + Rect.Width, Rect.Y + Rect.Height), Scalar.Blue, 2); } //比率変換の係数計算 var TransportWidth = (double)(Screen.width / binarydiff.Width); var TransportHeight = (double)(Screen.height / binarydiff.Height); Debug.Log("幅の比率:" + TransportWidth); Debug.Log("高さの比率:" + TransportHeight); Debug.Log(maxdiffblob.Area); if (maxdiffblob.Area > 10000) { var pt = maxdiffblob.Centroid; Debug.Log("実影の座標" + pt.X + "," + pt.Y); ScreenPt= new Vector3((float)(pt.X * TransportWidth), (float)(Screen.height - (pt.Y * TransportHeight)), 10.0f); } else { ScreenPt = new Vector3(-100f, -100f, -100f); Debug.Log("aaa"); } //結果の表示 using (new Window("binary", binary)) ; using (new Window("render", render)) ; using (new Window("render2", render2)) ; using (new Window("diff", diff)) ; using (var win = new Window("binarydiff", binarydiff)) ; //using (new Window("realshadow", realshadow)); //キー入力処理 int key = Cv2.WaitKey(100); if (key == 27) break; if (i == 1) { break; } } return; } //画像処理の関数(引数は画像,閾値k(0~255)) Mat ImageProcessing(Mat frame, int k) { var render = new Mat(frame.Rows, frame.Cols, MatType.CV_8UC3, 3); var gray = new Mat(); var binary = new Mat(); //グレースケール変換 Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY); //平滑化 Cv2.Blur(gray, gray, new Size(5, 5)); //二値化 binary = gray.Threshold(k, 255, ThresholdTypes.Binary); return binary; } //実影のオブジェクト移動,描画 void RealShadowMove() { ScreenCapture.CaptureScreenshot("image4.png"); gameview = new Mat(@"image4.png"); Vector3 MousePos = Input.mousePosition; MousePos.z = 10.0f; Debug.Log("マウスの位置" + MousePos); Debug.Log("screen画面での実影の座標" + ScreenPt); WorldPoint = ConvertCamera.ScreenToWorldPoint(ScreenPt); MousePoint = ConvertCamera.ScreenToWorldPoint(MousePos); WorldPoint.y *= -1; MousePoint.y *= -1; //this.gameObject.transform.position = MousePoint; this.gameObject.transform.position = WorldPoint; iTween.MoveTo(this.gameObject, WorldPoint, (float)0.1); Debug.Log("実影のワールド座標" + WorldPoint); Debug.Log("マウスのワールド座標" + MousePoint); } // Update is called once per frame void Update(){ RealShadowMove(); } private void OnApplicationQuit() { if (_thread != null) { i = 1; } } }
回答1件
あなたの回答
tips
プレビュー