コード例 #1
0
ファイル: MainForm.cs プロジェクト: dengqizhou30/AIAssist
        //显示检测结果后台线程
        private void backgroundWorker_showimg_DoWork(object sender, DoWorkEventArgs e)
        {
            var bgWorker = (BackgroundWorker)sender;

            //在后台线程中循环显示检测结果
            DetectionResult result = new DetectionResult();

            while (!bgWorker.CancellationPending)
            {
                try
                {
                    if (imgQueue.TryTake(out result, 100))
                    {
                        //持续获取并处理检测结果
                        if (result.frameMat != null && !result.frameMat.Empty())
                        {
                            this.objectDetection.ShowPicture(result.frameMat, result.objectPosRects,
                                                             result.detectionResult4Rect.maxConfidencePos, result.toltalMillis);

                            //对于检测对象的图像对象,需要手工释放资源
                            if (!result.frameMat.IsDisposed)
                            {
                                result.frameMat.Dispose();
                            }
                        }
                    }
                    //bgWorker.ReportProgress(0, null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
コード例 #2
0
ファイル: MainForm.cs プロジェクト: dengqizhou30/AIAssist
        //屏幕检测后台线程
        private void backgroundWorker_detection_DoWork(object sender, DoWorkEventArgs e)
        {
            var bgWorker = (BackgroundWorker)sender;

            //在后台线程中循环检测屏幕对象
            while (!bgWorker.CancellationPending)
            {
                try
                {
                    //objectDetection.CopyScreenTest();
                    DetectionResult detectionResult = objectDetection.DetectionScreen();
                    //检测结果放到异步队列中,在其他线程中执行
                    if (detectionResult.detectionResult4Rect.maxConfidencePos.confidence > 0)
                    {
                        if (posQueue.Count < 10)
                        {
                            posQueue.Add(detectionResult.detectionResult4Rect);
                        }
                    }
                    if (detectionResult.frameMat != null && !detectionResult.frameMat.Empty())
                    {
                        if (imgQueue.Count < 10)
                        {
                            imgQueue.Add(detectionResult);
                        }
                        else
                        {
                            //没有加入处理队列的对象,手工释放资源
                            if (detectionResult.frameMat != null && !detectionResult.frameMat.IsDisposed)
                            {
                                detectionResult.frameMat.Dispose();
                            }
                        }
                    }
                    //bgWorker.ReportProgress(0, null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
コード例 #3
0
        //使用AI模型检测屏幕,识别人员及位置
        public DetectionResult DetectionScreen()
        {
            long toltalMillis = 0;
            long startTicks   = DateTime.Now.Ticks;

            //保存所有检测对象及最大置信度对象的位置
            DetectionResult      detectionResult  = new DetectionResult();
            List <ObjectPosRect> objectPosRects   = new List <ObjectPosRect>();
            ObjectPosRect        maxConfidencePos = new ObjectPosRect();

            maxConfidencePos.setValues(0, 0, 0, 0, 0, 0);

            //拷贝需要检测屏幕区域的图像
            //c#中处理图形,需要注意手动释放资源,及线程不安全的问题。
            //System.Drawing.Bitmap bitmap = new Bitmap(this.detectionRect.w, this.detectionRect.h);
            //System.Drawing.Graphics graphics = Graphics.FromImage(bitmap);
            this.detectGraphics.CopyFromScreen(this.detectionRect.x, this.detectionRect.y, 0, 0, new System.Drawing.Size(this.detectionRect.w, this.detectionRect.h), CopyPixelOperation.SourceCopy);

            try
            {
                //注意这里不用using语句,因为会隐式释放图像对象,导致外面其他函数使用对象时无法访问。
                Mat frameMat = BitmapConverter.ToMat(this.detectBitmap);
                if (frameMat != null && !frameMat.Empty())
                {
                    //屏幕截图和视频截图格式不一样,需要进行图像格式转换
                    Cv2.CvtColor(frameMat, frameMat, ColorConversionCodes.RGBA2RGB);

                    // Convert Mat to batch of images
                    var frameWidth  = frameMat.Cols;
                    var frameHeight = frameMat.Rows;

                    //注意转换位输入数据时,最好保持原图大小,或者按比例缩放,相对于不按比例缩放,可以让识别准确率大幅提升。
                    //注意scaleFactor和scalemean参数设置,涉及模型输入数据归一化,严重影响模型准确率。
                    //using (var inputBlob = CvDnn.BlobFromImage(frameMat, 0.008, new OpenCvSharp.Size(320, 320), new Scalar(104, 117, 123), true, false))
                    //using (var inputBlob = CvDnn.BlobFromImage(frameMat, 0.008, new OpenCvSharp.Size(320, 320), new Scalar(103.939, 116.779, 123.68), true, false))
                    //using (var inputBlob = CvDnn.BlobFromImage(frameMat, 0.008, new OpenCvSharp.Size(frameWidth, frameHeight), new Scalar(103.939, 116.779, 123.68), true, false))
                    using (var inputBlob = CvDnn.BlobFromImage(frameMat, 1.0 / 127.5, new OpenCvSharp.Size(frameWidth, frameHeight), new Scalar(127.5, 127.5, 127.5), true, false))
                    //using (var inputBlob = CvDnn.BlobFromImage(frameMat, 1.0 / 255, new OpenCvSharp.Size(frameWidth, frameHeight), new Scalar(123.7, 116.3, 103.5), true, false))
                    {
                        //使用AI模型推理检测图像
                        detectionNet.SetInput(inputBlob);
                        var output = detectionNet.Forward();

                        //分析检测结果
                        var detectionMat = new Mat(output.Size(2), output.Size(3), MatType.CV_32F, output.Ptr(0));
                        for (int i = 0; i < detectionMat.Rows; i++)
                        {
                            float confidence = detectionMat.At <float>(i, 2);

                            if (confidence > 0.60)
                            {
                                int classid = (int)detectionMat.At <float>(i, 1);
                                //判断识别的类型,这个应用场景只显示识别的人,提升处理效率
                                //if (classid < this.labelNames.Length &&  (classid == 1 || classid != 1))
                                //if (classid < this.labelNames.Length && (classid == 1))
                                if (classid < this.labelNames.Length && (classid == 1))
                                {
                                    int x1 = (int)(detectionMat.At <float>(i, 3) * frameWidth);
                                    int y1 = (int)(detectionMat.At <float>(i, 4) * frameHeight);
                                    int x2 = (int)(detectionMat.At <float>(i, 5) * frameWidth);
                                    int y2 = (int)(detectionMat.At <float>(i, 6) * frameHeight);

                                    ObjectPosRect objectPosRect = new ObjectPosRect();
                                    objectPosRect.setValues(classid, confidence, x1, y1, x2, y2);
                                    objectPosRects.Add(objectPosRect);

                                    //判断是否是最大人员模型;
                                    //为避免处理逻辑太复杂,最大模型宽度设置为一个常量;
                                    //if ((objectPosRect.x2 - objectPosRect.x1) < this.detectionRect.w / 3 &&
                                    //    (this.maxPersonPos.x2 - this.maxPersonPos.x1 < objectPosRect.x2 - objectPosRect.x1))
                                    //    this.maxPersonPos.setValues(objectPosRect);

                                    //为保障项目,排除太大或者太小的模型
                                    if ((objectPosRect.x2 - objectPosRect.x1) <= 200 && (objectPosRect.x2 - objectPosRect.x1) >= 10 &&
                                        (objectPosRect.y2 - objectPosRect.y1) <= 280 && (objectPosRect.y2 - objectPosRect.y1) >= 10)
                                    {
                                        //判断是否是游戏操作人,模型位置为屏幕游戏者位置
                                        //游戏者的位置在屏幕下方靠左一点,大概 860/1920处
                                        //另外游戏中左右摇摆幅度较大,所以x轴的兼容值要设置大一些。
                                        if (Math.Abs(objectPosRect.x1 + (objectPosRect.x2 - objectPosRect.x1) / 2 - this.playerCentX) <= 100 &&
                                            objectPosRect.y1 > this.detectionRect.h * 1 / 2 &&
                                            Math.Abs(this.detectionRect.h - objectPosRect.y2) <= 10)
                                        {
                                            //排除游戏者自己
                                            //var testi = 0;
                                        }
                                        else
                                        {
                                            //保存置信度最大的人员的位置,同时排除屏幕下方正中的游戏者自己
                                            if (objectPosRect.confidence > maxConfidencePos.confidence)
                                            {
                                                maxConfidencePos.setValues(objectPosRect);
                                            }
                                        }
                                    }

                                    long endTicks = DateTime.Now.Ticks;
                                    toltalMillis = (endTicks - startTicks) / 10000;
                                }
                            }
                        }
                    }
                    detectionResult.setValues(this.rawDetectionRect, this.detectionRect, frameMat, objectPosRects, maxConfidencePos, this.maxPersonW, toltalMillis);
                    //图像显示放到其他线程中处理
                    //this.ShowPicture(frameMat, objectPosRects, maxConfidencePos, toltalMillis);
                }

                //Thread.Sleep(100);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            //使用类属性,只创建了一个对象,不能手工释放
            //graphics.Dispose();
            //bitmap.Dispose();

            return(detectionResult);
        }