Beispiel #1
0
 /// <summary>
 /// Updates list of tracks based on current blobs.
 /// </summary>
 /// <param name="blobs">List of blobs</param>
 /// <param name="thDistance">Distance Max distance to determine when a track and a blob match</param>
 /// <param name="thInactive">Inactive Max number of frames a track can be inactive</param>
 /// <param name="thActive">Active If a track becomes inactive but it has been active less than thActive frames, the track will be deleted.</param>
 public void Update(CvBlobs blobs, double thDistance, uint thInactive, uint thActive)
 {
     CvInvoke.cvbCvUpdateTracks(blobs, _ptr, thDistance, thInactive, thActive);
 }
        public static WriteableBitmap DrawBlobBoundingBoxsCV(WriteableBitmap writeableBitmap, WriteableBitmap gradientBitmapRef, WriteableBitmap realBitmapRef)
        {
            Bitmap normalBitmap = BitmapFromWriteableBitmap(writeableBitmap);
               var cvImage = new Image<Gray, byte>(new Bitmap(normalBitmap));

               //var classifications = ClassifyBitmap( writeableBitmap, cvImage );
               if (cvImage != null)
               {
               // This takes our nice looking color png and converts it to black and white
               Image<Gray, byte> greyImg = cvImage.Convert<Gray, byte>();

               // We again threshold it based on brightness...BUT WE INVERT THE PNG. BLOB DETECTOR DETECTS WHITE NOT BLACK
               // this will esentially eliminate the color differences
               // you could also do cool things like threshold only certain colors here for a color based blob detector
               Image<Gray, Byte> greyThreshImg = greyImg.ThresholdBinaryInv(new Gray(150), new Gray(255));

               Emgu.CV.Cvb.CvBlobs resultingImgBlobs = new Emgu.CV.Cvb.CvBlobs();
               Emgu.CV.Cvb.CvBlobDetector bDetect = new Emgu.CV.Cvb.CvBlobDetector();
               uint numWebcamBlobsFound = bDetect.Detect(greyThreshImg, resultingImgBlobs);

               // This is a simple way of just drawing all blobs reguardless of their size and not iterating through them
               // It draws on top of whatever you input. I am inputting the threshold image. Specifying an alpha to draw with of 0.5 so its half transparent.
               //Emgu.CV.Image<Bgr, byte> blobImg = bDetect.DrawBlobs(webcamThreshImg, resultingWebcamBlobs, Emgu.CV.Cvb.CvBlobDetector.BlobRenderType.Default, 0.5);

               // Here we can iterate through each blob and use the slider to set a threshold then draw a red box around it
               Image<Rgb, byte> blobImg = greyThreshImg.Convert<Rgb, byte>();
               Rgb red = new Rgb(255, 0, 0);

               int blobNumber = 0;

               // Lets try and iterate the blobs?
               foreach (Emgu.CV.Cvb.CvBlob targetBlob in resultingImgBlobs.Values)
               {
                   int imageArea = blobImg.Width*blobImg.Height;
                   int blobArea = targetBlob.Area;
                   int blobBoundingBoxArea = targetBlob.BoundingBox.Width*targetBlob.BoundingBox.Height;

                   // Only use blobs with area greater than some threshold
                   // If the blob bounding rect is basically size of the whole image ignore it for now
                   if (blobArea > 200.0 && blobBoundingBoxArea < (imageArea*0.99))
                   {
                       Rectangle rectangle = targetBlob.BoundingBox;

                       int CentroidX = (int)targetBlob.Centroid.X;
                       int CentroidY = (int)targetBlob.Centroid.Y;

                       int croppedWidth = rectangle.Width + 50;
                       int croppedHeight = rectangle.Height + 50;

                       int CroppedX = CentroidX - (int)(croppedWidth / 2.0);
                       int CroppedY = CentroidY - (int)(croppedHeight / 2.0);

                       var croppedBlobBitmap = writeableBitmap.Crop(CroppedX, CroppedY, croppedWidth, croppedHeight);
                       var croppedGradientBlobBitmap = gradientBitmapRef.Crop(CroppedX, CroppedY, croppedWidth, croppedHeight);
                       var croppedRealBitmapRef = realBitmapRef.Crop(CroppedX, CroppedY, croppedWidth, croppedHeight);

                       double blobAngle = -RadianToDegree(CalculateBlobAngle(targetBlob));

                       CroppedX = (int) (croppedWidth/2.0);
                       CroppedY = (int) (croppedHeight/2.0);

                       var rotatedandCroppedBlobBitmap = RotateWriteableBitmap(croppedBlobBitmap, blobAngle);
                       var rotatedGradientBlobBitmap = RotateColorWriteableBitmap(croppedGradientBlobBitmap, blobAngle);
                       var rotatedRealBitmapRef = RotateColorWriteableBitmap(croppedRealBitmapRef, blobAngle);

                       var refinedBitmap = DrawBlobBoundingBoxsAroundCroppedBitmap(rotatedandCroppedBlobBitmap, rotatedGradientBlobBitmap, rotatedRealBitmapRef, 1);
                       rotatedGradientBlobBitmap = DrawBlobBoundingBoxsAroundCroppedBitmap(rotatedandCroppedBlobBitmap, rotatedGradientBlobBitmap, rotatedRealBitmapRef, 2);
                       rotatedRealBitmapRef = DrawBlobBoundingBoxsAroundCroppedBitmap(rotatedandCroppedBlobBitmap, rotatedGradientBlobBitmap, rotatedRealBitmapRef, 3);

                       var areaCheck = refinedBitmap.PixelHeight*refinedBitmap.PixelWidth;

                       if (areaCheck >= 200)
                       {
                           blobNumber++;

                           var thresholded = refinedBitmap.Clone();
                           ThresholdBitmap(thresholded, 10, false);
                           BitmapColorer.ColorBitmap(thresholded);

                           System.Windows.Media.Color blobColor = PixelColorOfCentralBlob(thresholded);
                           BitmapColorer.EraseAllButCertainColorandWhite(thresholded, blobColor);

                           var shouldFlip = shouldFlipThresholdedBitmap(thresholded, blobColor);

                           if (shouldFlip)
                           {
                               thresholded = thresholded.Rotate(180);
                               rotatedGradientBlobBitmap = rotatedGradientBlobBitmap.Rotate(180);
                               rotatedRealBitmapRef = rotatedRealBitmapRef.Rotate(180);
                           }

                           var orientedBitmap = NormalizeBitmapSize(thresholded);
                           var orientedGradientBitmap = NormalizeBitmapSize(rotatedGradientBlobBitmap);
                           var orientedRealBitmap = NormalizeBitmapSize(rotatedRealBitmapRef);

                           ApplyBlobMaskToOtherBitmaps(orientedBitmap, orientedGradientBitmap, orientedRealBitmap, blobColor);

                           string fileName1 = saveDirectory + "\\croppedBlob" + blobNumber + ".png";

                           ExtensionMethods.Save(orientedRealBitmap, fileName1);
                       }
                   }
               }
               }

               return writeableBitmap;
        }
        /// <summary>
        /// 图漾粗略找合适的轮廓
        /// </summary>
        /// <param name="point_3d">三维点</param>
        public static void getContours(float[] point_3d)
        {
            GLB.TitleStr = "";
            int AREA = GLB.BUFW * GLB.BUFH;                //总面积
            var gray = GLB.MyFrame.Convert <Gray, Byte>(); //灰度化

            Emgu.CV.Cvb.CvBlobs        myBlobs = new Emgu.CV.Cvb.CvBlobs();
            Emgu.CV.Cvb.CvBlobDetector bd      = new Emgu.CV.Cvb.CvBlobDetector();
            uint n = bd.Detect(gray, myBlobs);//发现区块

            ////遍历各区块:
            for (uint i = 1; i <= myBlobs.Count; i++)
            {
                int         area   = myBlobs[i].Area;                                                  //获取面积
                RotatedRect rect   = CvInvoke.MinAreaRect(new VectorOfPoint(myBlobs[i].GetContour())); //最小矩形
                float       width  = rect.Size.Width;                                                  //像素宽
                float       height = rect.Size.Height;                                                 //像素长
                if (height < width)
                {
                    float temp = height;
                    height = width;
                    width  = temp;
                }
                float H2W = height / width;
                if (area > 0.02 * AREA && area < 0.75 * AREA && H2W > 1 && H2W < 2)//通过面积 长宽比 初略筛选
                {
                    if (getProduceInfo(myBlobs[i], point_3d) == true)
                    {
                        if (ProduceMacth() == true)//匹配成功
                        {
                            //////#########################################队列求均值--获取中心坐标#################################################
                            //GLB.avgCameraPoint3.Enqueue(new Point3(GLB.camera_device_point.X, GLB.camera_device_point.Y, GLB.camera_device_point.Z));
                            //if (GLB.avgCameraPoint3.Count > 5)
                            //{
                            //    GLB.avgCameraPoint3.Dequeue();
                            //}
                            //else
                            //{
                            //    return ;
                            //}
                            //GLB.camera_device_point.Z = (int)GLB.avgCameraPoint3.Average(o => o.Z);//中心点的深度//Z
                            //GLB.camera_device_point.Y = (int)GLB.avgCameraPoint3.Average(o => o.Y);//Y
                            //GLB.camera_device_point.X = (int)GLB.avgCameraPoint3.Average(o => o.X);//X
                            //RotatedRect boxCenter = new RotatedRect(new PointF((float )GLB.obj.jd.Average(o => o.X), (float)GLB.obj.jd.Average(o => o.Y)), new Size(8, 8), 0);
                            //CvInvoke.Ellipse(GLB.MyFrame, boxCenter, new MCvScalar(255, 0, 0), 4);//在中心画一个小圆
                            //CvInvoke.PutText(GLB.MyFrame, "x:" + (float)GLB.obj.jd.Average(o => o.X) + "y:" + (float)GLB.obj.jd.Average(o => o.Y) + "XC=" + GLB.obj.xCenter + "YC=" + GLB.obj.yCenter + "Depth=" + GLB.obj.Depth, new System.Drawing.Point((int)GLB.obj.jd.Average(o => o.X) - 176, (int)GLB.obj.jd.Average(o => o.Y) + 25), Emgu.CV.CvEnum.FontFace.HersheyDuplex, .75, new MCvScalar(255, 255, 255), 2);//深度显示

                            ////////队列求均值
                            //GLB.avgAngle.Enqueue((float)GLB.obj.Angle);
                            //if (GLB.avgAngle.Count > 5)
                            //{
                            //    GLB.avgAngle.Dequeue();
                            //}
                            //else
                            //{
                            //    return ;
                            //}
                            //GLB.obj.Angle = GLB.avgAngle.Average();//旋转角
                            //CvInvoke.PutText(GLB.MyFrame, "Angl=" + GLB.obj.Angle, new System.Drawing.Point((int)GLB.obj.jd[3].X, (int)GLB.obj.jd[3].Y), Emgu.CV.CvEnum.FontFace.HersheyDuplex, .75, new MCvScalar(0, 0, 255), 2);


                            ////#########################################坐标换算#################################################
                            GLB.robot_device_point.X = GLB.MatTuYangCam[0] * GLB.camera_device_point.X + GLB.MatTuYangCam[1] * GLB.camera_device_point.Y + GLB.MatTuYangCam[2];
                            GLB.robot_device_point.Y = GLB.MatTuYangCam[3] * GLB.camera_device_point.X + GLB.MatTuYangCam[4] * GLB.camera_device_point.Y + GLB.MatTuYangCam[5];
                            GLB.robot_device_point.Z = 2818 - GLB.camera_device_point.Z;
                            GLB.device_angl         += -2.6f;//相机与机器人夹角2.6度
                            GLB.device_angl          = (float)(GLB.device_angl * Math.PI / 180f);
                            //限定范围
                            if (GLB.robot_device_point.X < -600 || GLB.robot_device_point.X > 600 ||
                                GLB.robot_device_point.Y < -2200 || GLB.robot_device_point.Y > -800 ||
                                GLB.robot_device_point.Z < 280 || GLB.robot_device_point.Z > 1100)
                            {
                                GLB.Match_success = false;
                                GLB.TitleStr     += ",但是超出范围";
                            }
                            else
                            {
                                GLB.Match_success = true;
                            }
                        }
                        else
                        {
                            GLB.Match_success = false;
                        }
                    }
                }
            }
        }
        public static WriteableBitmap DrawBlobBoundingBoxsAroundCroppedBitmap(WriteableBitmap writeableBitmap,
           WriteableBitmap gradientBitmapRef, WriteableBitmap realBitmapRef, int returnBitmapIndex)
        {
            Bitmap normalBitmap = BitmapFromWriteableBitmap(writeableBitmap);
               var cvImage = new Image<Gray, byte>(new Bitmap(normalBitmap));

               if (cvImage != null)
               {
               Image<Gray, byte> greyImg = cvImage.Convert<Gray, byte>();

               Image<Gray, Byte> greyThreshImg = greyImg.ThresholdBinaryInv(new Gray(150), new Gray(255));

               Emgu.CV.Cvb.CvBlobs resultingImgBlobs = new Emgu.CV.Cvb.CvBlobs();
               Emgu.CV.Cvb.CvBlobDetector bDetect = new Emgu.CV.Cvb.CvBlobDetector();
               uint numWebcamBlobsFound = bDetect.Detect(greyThreshImg, resultingImgBlobs);

               Image<Rgb, byte> blobImg = greyThreshImg.Convert<Rgb, byte>();
               Rgb red = new Rgb(255, 0, 0);

               int blobNumber = 0;

               foreach (Emgu.CV.Cvb.CvBlob targetBlob in resultingImgBlobs.Values)
               {
                   int imageArea = blobImg.Width*blobImg.Height;
                   int blobArea = targetBlob.Area;
                   int blobBoundingBoxArea = targetBlob.BoundingBox.Width*targetBlob.BoundingBox.Height;

                   if (blobArea > 200.0 && blobBoundingBoxArea < (imageArea*0.99))
                   {
                       blobNumber++;
                       Rectangle rectangle = targetBlob.BoundingBox;
                       Rect convertedRect = new Rect(rectangle.X - 10, rectangle.Y - 10, rectangle.Width + 20,
                           rectangle.Height + 20);
                       //BitmapColorer.DrawRectangle(writeableBitmap, convertedRect);

                       writeableBitmap = writeableBitmap.Crop(rectangle.X - 10, rectangle.Y - 10, rectangle.Width + 20,
                           rectangle.Height + 20);
                       gradientBitmapRef = gradientBitmapRef.Crop(rectangle.X - 10, rectangle.Y - 10,
                           rectangle.Width + 20, rectangle.Height + 20);
                       realBitmapRef = realBitmapRef.Crop(rectangle.X - 10, rectangle.Y - 10, rectangle.Width + 20,
                           rectangle.Height + 20);
                   }
               }
               }
               if (returnBitmapIndex == 1)
               {
               return writeableBitmap;
               }
               else if (returnBitmapIndex == 2)
               {
               return gradientBitmapRef;
               }
               else
               {
               return realBitmapRef;
               }
        }