static void Main(string[] args) { Mat flow, cflow, gray, prevgray, img_bgr; Point[][] contours; HierarchyIndex[] hierarchy; prevgray = new Mat(); VideoCapture cap = new VideoCapture(); cap.Open(0); int sleepTime = (int)Math.Round(1000 / cap.Fps); using (Window window = new Window("capture")) using (Mat frame = new Mat()) // Frame image buffer { while (true) { cap.Read(frame); if (frame.Empty()) { break; } gray = new Mat(); flow = new Mat(); cflow = new Mat(); img_bgr = new Mat(); Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY); if (prevgray.Empty()) { prevgray = gray; } else { Cv2.CalcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 5, 16, 3, 5, 1.2, OpticalFlowFlags.FarnebackGaussian); Cv2.CvtColor(prevgray, cflow, ColorConversionCodes.GRAY2BGR); drawOptFlowMap(ref flow, ref cflow, 1.5, 16, new Scalar(0, 0, 255)); drawHsv(flow, out img_bgr); Mat gray_bgr = new Mat(); gray_bgr = Mat.Zeros(frame.Rows, frame.Cols, MatType.CV_8UC1); Cv2.CvtColor(img_bgr, gray_bgr, ColorConversionCodes.BGR2GRAY); Cv2.Normalize(gray_bgr, gray_bgr, 0, 255, NormTypes.MinMax, MatType.CV_8UC1); Cv2.Blur(gray_bgr, gray_bgr, new Size(3, 3)); // Detect edges using Threshold Mat img_thresh = new Mat(); img_thresh = Mat.Zeros(frame.Rows, frame.Cols, MatType.CV_8UC1); Cv2.Threshold(gray_bgr, img_thresh, 155, 255, ThresholdTypes.BinaryInv); Cv2.FindContours(img_thresh, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); if (contours.Length == 0) { throw new NotSupportedException("Couldn't find any object in the image."); } for (int i = 0; i < contours.Length; i++) { Rect box = Cv2.BoundingRect(contours[i]); if (box.Width > 50 && box.Height > 50 && box.Width < 900 && box.Height < 680) { Cv2.Rectangle(frame, box.TopLeft, box.BottomRight, new Scalar(0, 255, 0), 4); } } window.Image = frame; Char c = (Char)Cv2.WaitKey(1); if (c == 27) { break; } Swap <Mat>(ref gray, ref prevgray); } } } }
private void Generate() { if (_count < 2 || _tileH < 1) { return; } var tileV = (_count / _tileH) + (((_count % _tileH) > 0) ? 1 : 0); var flows = new Mat[_count]; var flowf32s = new Mat[_count - 1]; for (int i = 0; i < _count - 1; i++) { var index = i; var prevMat = OpenCvUtils.ConvertFromTexture2d(_texture, index % _tileH, index / _tileH, _tileH, tileV); index++; var nextMat = OpenCvUtils.ConvertFromTexture2d(_texture, index % _tileH, index / _tileH, _tileH, tileV); //グレースケール化 Cv2.CvtColor(prevMat, prevMat, ColorConversionCodes.BGRA2GRAY); Cv2.CvtColor(nextMat, nextMat, ColorConversionCodes.BGRA2GRAY); //オプティカルフロー計算 var flow = new Mat(); Cv2.CalcOpticalFlowFarneback(prev: prevMat, next: nextMat, flow: flow, pyrScale: 0.5, levels: 3, winsize: 10, iterations: 3, polyN: 3, polySigma: 1.1, flags: OpticalFlowFlags.FarnebackGaussian); //flags:OpticalFlowFlags.FarnebackGaussian );//0.8, 10, 15, 3, 5, 1.1, 0 ); flowf32s[i] = flow; } var flowStrength = 0.0f; for (int i = 0; i < _count - 1; i++) { var strength = OpenCvUtils.ComputeFlowStrength(flowf32s[i]); if (flowStrength < strength) { flowStrength = strength; } } Debug.Log("FlowStrength:" + flowStrength); for (int i = 0; i < _count - 1; i++) { //F32からU8へ flows[i] = OpenCvUtils.ConvertFlowMap(flowf32s[i], flowStrength, _flipV); } var flowMap = new Texture2D(_texture.width, _texture.height, TextureFormat.ARGB32, false, true); int width = (int)(_texture.width / _tileH); int height = (int)(_texture.height / tileV); for (int i = 0; i < _count - 1; i++) { int ox = (i % _tileH) * width; int oy = ((tileV - 1) - (i / _tileH)) * height; flowMap.SetPixels32(ox, oy, width, height, OpenCvUtils.ConvertToPixels(flows[i]), 0); } //ループしない用なので最後にベクトルが移動しないのを入れる var vzPixels = new Color32[height * width]; for (int i = 0; i < vzPixels.Length; i++) { vzPixels[i] = new Color32(127, 127, 0, 255); } flowMap.SetPixels32((_tileH - 1) * width, 0, width, height, vzPixels, 0); flowMap.Apply(false); var path = "/" + _texture.name + "_flow.png"; var bytes = flowMap.EncodeToPNG(); File.WriteAllBytes(Application.dataPath + path, bytes); AssetDatabase.ImportAsset("Assets" + path, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive | ImportAssetOptions.ForceSynchronousImport); AssetDatabase.Refresh(); //不随パラメータ保存 var paramPath = "Assets/" + _texture.name + "_flowparam.asset"; var param = AssetDatabase.LoadAssetAtPath <OpticalFlowParam>(paramPath); if (param == null) { param = ScriptableObject.CreateInstance <OpticalFlowParam>(); AssetDatabase.CreateAsset(param, paramPath); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive); } param.flowStrength = flowStrength; param.textureMain = _texture; param.textureFlow = AssetDatabase.LoadAssetAtPath <Texture2D>("Assets" + path); param.count = _count; param.tile.Set(_tileH, tileV); EditorUtility.SetDirty(param); AssetDatabase.ImportAsset(paramPath, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive); }