示例#1
0
        private static int TutorialDeveloperThread1()
        {
            try
            {
                OpenPose.Log("Starting OpenPose demo...", Priority.High);
                var timeBegin = new Stopwatch();
                timeBegin.Start();

                // ------------------------- INITIALIZATION -------------------------
                // Step 1 - Set logging level
                // - 0 will output all the logging messages
                // - 255 will output nothing
                OpenPose.Check(0 <= Flags.LoggingLevel && Flags.LoggingLevel <= 255, "Wrong logging_level value.");
                ConfigureLog.PriorityThreshold = (Priority)Flags.LoggingLevel;
                // Step 2 - Read GFlags (user defined configuration)
                // cameraSize
                var cameraSize = OpenPose.FlagsToPoint(Flags.CameraResolution, "-1x-1");
                // outputSize
                var outputSize = OpenPose.FlagsToPoint(Flags.OutputResolution, "-1x-1");
                // producerType
                var tie                    = OpenPose.FlagsToProducer(Flags.ImageDir, Flags.Video, Flags.IpCamera, Flags.Camera, Flags.FlirCamera, Flags.FlirCameraIndex);
                var producerType           = tie.Item1;
                var producerString         = tie.Item2;
                var displayProducerFpsMode = Flags.ProcessRealTime ? ProducerFpsMode.OriginalFps : ProducerFpsMode.RetrievalFps;
                using (var producerSharedPtr = OpenPose.CreateProducer(producerType,
                                                                       cameraSize,
                                                                       producerString,
                                                                       Flags.CameraParameterPath,
                                                                       Flags.FrameUndistort,
                                                                       Flags.Views3D))
                {
                    producerSharedPtr.Get().SetProducerFpsMode(displayProducerFpsMode);
                    OpenPose.Log("", Priority.Low);
                    // Step 3 - Setting producer
                    //var videoSeekSharedPtr = std::make_shared<std::pair<std::atomic<bool>, std::atomic<int>>>();
                    //videoSeekSharedPtr->first = false;
                    //videoSeekSharedPtr->second = 0;
                    // Step 4 - Setting thread workers && manager
                    // Note:
                    // nativeDebugging may occur crash
                    using (var threadManager = new ThreadManager <Datum>())
                    {
                        // Step 5 - Initializing the worker classes
                        // Frames producer (e.g., video, webcam, ...)
                        using (var datumProducer = new StdSharedPtr <DatumProducer <Datum> >(new DatumProducer <Datum>(producerSharedPtr)))
                            using (var wDatumProducer = new StdSharedPtr <WDatumProducer <Datum> >(new WDatumProducer <Datum>(datumProducer)))
                            {
                                // GUI (Display)
                                using (var gui = new StdSharedPtr <Gui>(new Gui(outputSize, Flags.FullScreen, threadManager.GetIsRunningSharedPtr())))
                                    using (var wGui = new StdSharedPtr <WGui <Datum> >(new WGui <Datum>(gui)))
                                    {
                                        // ------------------------- CONFIGURING THREADING -------------------------
                                        // In this simple multi-thread example, we will do the following:
                                        // 3 (virtual) queues: 0, 1, 2
                                        // 1 real queue: 1. The first and last queue ids (in this case 0 and 2) are not actual queues, but the
                                        // beginning and end of the processing sequence
                                        // 2 threads: 0, 1
                                        // wDatumProducer will generate frames (there is no real queue 0) and push them on queue 1
                                        // wGui will pop frames from queue 1 and process them (there is no real queue 2)
                                        var threadId = 0UL;
                                        var queueIn  = 0UL;
                                        var queueOut = 1UL;
                                        threadManager.Add(threadId++, wDatumProducer, queueIn++, queueOut++); // Thread 0, queues 0 -> 1
                                        threadManager.Add(threadId++, wGui, queueIn++, queueOut++);           // Thread 1, queues 1 -> 2

                                        // Equivalent single-thread version (option a)
                                        // const auto threadId = 0ull;
                                        // auto queueIn = 0ull;
                                        // auto queueOut = 1ull;
                                        // threadManager.add(threadId, wDatumProducer, queueIn++, queueOut++);       // Thread 0, queues 0 -> 1
                                        // threadManager.add(threadId, wGui, queueIn++, queueOut++);                 // Thread 0, queues 1 -> 2

                                        // Equivalent single-thread version (option b)
                                        // const auto threadId = 0ull;
                                        // const auto queueIn = 0ull;
                                        // const auto queueOut = 1ull;
                                        // threadManager.add(threadId, {wDatumProducer, wGui}, queueIn, queueOut);     // Thread 0, queues 0 -> 1

                                        // ------------------------- STARTING AND STOPPING THREADING -------------------------
                                        OpenPose.Log("Starting thread(s)...", Priority.High);
                                        // Two different ways of running the program on multithread environment
                                        // Option a) Using the main thread (this thread) for processing (it saves 1 thread, recommended)
                                        threadManager.Exec();
                                        // Option b) Giving to the user the control of this thread
                                        // // VERY IMPORTANT NOTE: if OpenCV is compiled with Qt support, this option will not work. Qt needs the main
                                        // // thread to plot visual results, so the final GUI (which uses OpenCV) would return an exception similar to:
                                        // // `QMetaMethod::invoke: Unable to invoke methods with return values in queued connections`
                                        // // Start threads
                                        // threadManager.start();
                                        // // Keep program alive while running threads. Here the user could perform any other desired function
                                        // while (threadManager.isRunning())
                                        //     std::this_thread::sleep_for(std::chrono::milliseconds{33});
                                        // // Stop and join threads
                                        // op::log("Stopping thread(s)", op::Priority::High);
                                        // threadManager.stop();
                                    }
                            }
                    }
                }

                // ------------------------- CLOSING -------------------------
                // Measuring total time
                timeBegin.Stop();
                var totalTimeSec = timeBegin.ElapsedMilliseconds / 1000d;
                var message      = $"OpenPose demo successfully finished. Total time: {totalTimeSec} seconds.";
                OpenPose.Log(message, Priority.High);

                // Return successful message
                return(0);
            }
            catch (Exception e)
            {
                OpenPose.Error(e.Message, -1, nameof(TutorialDeveloperThread1));
                return(-1);
            }
        }