/// <summary> /// Calculate the rotation of an object from image /// </summary> /// <param name="colorBS"></param> /// <param name="currentBlob"></param> /// <param name="viBlobs"></param> /// <returns>angle degree</returns> public static float GetRotation(Image <Bgra, byte> colorBS, BlobObject currentBlob, List <BlobObject> viBlobs) { Image <Bgra, byte> observedImage = UtilitiesImage.CropImage(colorBS, currentBlob.Rect); //observedImage.Save("current.jpg"); float degree = 360; if (viBlobs.Count == 0) { return(degree); } else { VectorOfKeyPoint keypoints1; VectorOfKeyPoint keypoints2; Matrix <float> symMatches; foreach (BlobObject viblob in viBlobs) { //viblob.Image.Save(viblob.Id + ".jpg"); bool isDetect = UtilitiesImage.MatchIsSame(viblob.Image, observedImage.Convert <Gray, byte>(), out keypoints1, out keypoints2, out symMatches); if (isDetect) { degree = UtilitiesImage.GetRotationDiff(symMatches, keypoints1, keypoints2); } } return(degree); } }
public void m_KinectConnector_allFramesReady(object pSource, Image <Bgra, Byte> pColorFrame, Image <Gray, Int16> pDepthFrame) { if (pColorFrame == null || pDepthFrame == null) { return; } OnOrgAllReady(this, pColorFrame, pDepthFrame); Image <Gray, Int16> depthFrameBuffer = pDepthFrame.Copy(); if (m_KinectSettings.Ratio == 0) { m_KinectSettings.Ratio = 2; } Image <Bgra, Byte> colorFrameBuffer = pColorFrame.Resize((int)(pColorFrame.Width / m_KinectSettings.Ratio), (int)(pColorFrame.Height / m_KinectSettings.Ratio), Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR); int xS = (int)(m_KinectSettings.XScale / m_KinectSettings.Ratio); int yS = (int)(m_KinectSettings.YScale / m_KinectSettings.Ratio); int xD = 0; int yD = 0; int xC = 0; int yC = 0; int w = 0; int h = depthFrameBuffer.Height; // depth image // what is the new width? if (xS < 0 && (depthFrameBuffer.Width + xS > colorFrameBuffer.Width)) { // rechts und links raus -- sollte nie vorkommen w = colorFrameBuffer.Width; xD = -xS; xC = 0; } else if (depthFrameBuffer.Width + xS > colorFrameBuffer.Width) { // rechts raus w = colorFrameBuffer.Width - xS; xD = 0; xC = xS; // xS is positive } else if (xS < 0) { // links raus w = depthFrameBuffer.Width + xS; xD = -xS; xC = 0; } else { // drin w = depthFrameBuffer.Width; xD = 0; xC = xS; } // what is the new height? if (yS < 0 && (depthFrameBuffer.Height + yS > colorFrameBuffer.Height)) { // oben und unten raus h = colorFrameBuffer.Height; yD = -yS; yC = 0; } else if (depthFrameBuffer.Height + yS > colorFrameBuffer.Height) { // nur unten raus h = colorFrameBuffer.Height - yS; yD = 0; yC = yS; } else if (yS < 0) { // nur oben raus h = depthFrameBuffer.Height + yS; yD = -yS; yC = 0; } else { // drin h = depthFrameBuffer.Height; yD = 0; yC = yS; } //Ausschnitt Setzen depthFrameBuffer.ROI = new System.Drawing.Rectangle(xD, yD, w, h); colorFrameBuffer.ROI = new System.Drawing.Rectangle(xC, yC, w, h); m_ImageSize = new System.Drawing.Size(w, h); if (colorImg == null || colorImg.Width != w || colorImg.Height != h) { colorImg = new Image <Bgra, Byte>(w, h); } if (m_DepthImg == null || m_DepthImg.Width != w || m_DepthImg.Height != h) { m_DepthImg = new Image <Gray, Int32>(w, h); } colorImg = colorFrameBuffer.Convert <Bgra, Byte>().Copy(); CvInvoke.cvResetImageROI(colorFrameBuffer); colorImgCropped = UtilitiesImage.CropImage(colorImg, m_AssemblyArea); // colorImgCropped = colorImg; Image <Gray, Int32> newDepthImgCropped = UtilitiesImage.CropImage(m_DepthImg, m_AssemblyArea); // Image<Gray, Int32> newDepthImgCropped = m_DepthImg; m_DepthImg = depthFrameBuffer.Convert <Gray, float>().SmoothGaussian(5).Convert <Gray, Int32>(); // m_DepthImg = pDepthFrame.Convert<Gray, float>().Convert<Gray, Int32>(); //Shmoothing if (m_SmoothingOn) { /*this.m_SmoothingFilter.InnerBandThreshold = (int)InnerBandThresholdInput.Value; * this.m_SmoothingFilter.OuterBandThreshold = (int)OuterBandThresholdInput.Value; * this.m_SmoothingAverage.AverageFrameCount = (int)AverageFrameCountInput.Value; * this.m_SmoothingMaximum.MaximumFrameCount = (int)AverageFrameCountInput.Value;*/ //depthImg = this.m_SmoothingFilter.CreateFilteredDepthArray(pDepthFrame, m_KinectConnector.GetDepthFrameDescription().Width, m_KinectConnector.GetDepthFrameDescription().Height); //depthImg = this.m_SmoothingMaximum.CreateMaximumDepthArray(depthPixel, depthFrame.Width, depthFrame.Height); m_DepthImgCropped = this.m_SmoothingAverage.CreateAverageDepthArray(newDepthImgCropped); } else { m_DepthImgCropped = newDepthImgCropped; } OnAllFramesReady(this, colorImg, colorImgCropped, m_DepthImg, m_DepthImgCropped); // event driven update CameraManager.Instance.SetImages(colorImg, colorImgCropped, m_DepthImg, m_DepthImgCropped); CameraManager.Instance.SetOrgImages(pSource, pColorFrame, pDepthFrame.Convert <Gray, Int32>()); }
/// <summary> /// /// </summary> /// <param name="openCVImg"></param> /// <param name="masterBlobs"></param> /// <param name="colorBS"></param> /// <param name="mode"></param> /// <returns></returns> public static List <BlobObject> FindAllBlob(Image <Gray, Int32> openCVImg, List <BlobObject> masterBlobs, Image <Bgra, byte> colorBS, bool mode) { List <BlobObject> retList = new List <BlobObject>(); try { Image <Gray, byte> gray_image = openCVImg.Convert <Gray, byte>(); List <BlobObject> newBlobs = new List <BlobObject>(); if (mode == false) { #region using cvBlob Emgu.CV.Cvb.CvBlobs resultingBlobs = new Emgu.CV.Cvb.CvBlobs(); Emgu.CV.Cvb.CvBlobDetector bDetect = new Emgu.CV.Cvb.CvBlobDetector(); uint numWebcamBlobsFound = bDetect.Detect(gray_image, resultingBlobs); using (MemStorage stor = new MemStorage()) { foreach (Emgu.CV.Cvb.CvBlob targetBlob in resultingBlobs.Values) { if (targetBlob.Area > 200) { var contour = targetBlob.GetContour(stor); MCvBox2D box = contour.GetMinAreaRect(); PointF[] boxCorner = UtilitiesImage.ToPercent(contour.GetMinAreaRect().GetVertices(), gray_image.Width, gray_image.Height); PointF center = UtilitiesImage.ToPercent(contour.GetMinAreaRect().center, gray_image.Width, gray_image.Height); RectangleF rect = UtilitiesImage.ToPercent(targetBlob.BoundingBox, gray_image.Width, gray_image.Height); Image <Gray, byte> newCropImg = UtilitiesImage.CropImage(colorBS.Convert <Gray, byte>(), rect); newBlobs.Add(new BlobObject(newCropImg, null, boxCorner, rect, center, 0, 0, 0 + "")); //stor.Clear(); } } } #endregion } else { #region using contour using (MemStorage storage = new MemStorage()) { //Find contours with no holes try CV_RETR_EXTERNAL to find holes Contour <System.Drawing.Point> contours = gray_image.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, storage); for (int i = 0; contours != null; contours = contours.HNext) { i++; //double area = contours.Area; if (contours.Area > 200) { PointF[] boxCorner = UtilitiesImage.ToPercent(contours.GetMinAreaRect().GetVertices(), gray_image.Width, gray_image.Height); PointF center = UtilitiesImage.ToPercent(contours.GetMinAreaRect().center, gray_image.Width, gray_image.Height); RectangleF rect = UtilitiesImage.ToPercent(contours.BoundingRectangle, gray_image.Width, gray_image.Height); Image <Bgra, byte> newCropImg = UtilitiesImage.CropImage(colorBS, rect); newBlobs.Add(new BlobObject(newCropImg.Convert <Gray, byte>(), null, boxCorner, rect, center, 0, 0, 0 + "")); } } } #endregion } // read objects from database now List <TrackableObject> objects = DatabaseManager.Instance.Objects.ToList(); if (objects.Count == 0) { foreach (BlobObject b in newBlobs) { retList.Add(new BlobObject(b.Image, null, b.CornerPoints, b.Rect, b.Center, 0, 0, 0 + "")); } } else { #region // size and position werden abgeglichen List <Tuple <double, double, int, int> > trackInfo = new List <Tuple <double, double, int, int> >(); for (int newblob = 0; newblob < newBlobs.Count; newblob++) { for (int master = 0; master < masterBlobs.Count; master++) { double d = UtilitiesImage.Distance(newBlobs[newblob].Center, masterBlobs[master].Center); double s = UtilitiesImage.DiffSize(newBlobs[newblob].Rect.Size, masterBlobs[master].Rect.Size); trackInfo.Add(new Tuple <double, double, int, int>(d, s, master, newblob)); } } trackInfo.Sort((x, y) => x.Item1.CompareTo(y.Item1)); List <int> newItem = new List <int>(); if (!m_LastWasCorrupted) { while (trackInfo.Count != 0) { if (trackInfo[0].Item2 < 0.2) { int masterId = trackInfo[0].Item3; int newId = trackInfo[0].Item4; BlobObject newObject = new BlobObject(newBlobs[newId].Image, newBlobs[newId].DepthStructur, newBlobs[newId].CornerPoints, newBlobs[newId].Rect, newBlobs[newId].Center, masterBlobs[masterId].Hits, masterBlobs[masterId].Id, masterBlobs[masterId].Name); retList.Add(newObject); trackInfo.RemoveAll(item => item.Item3 == masterId); trackInfo.RemoveAll(item => item.Item4 == newId); newItem.Add(newId); } else { trackInfo.RemoveAt(0); } } newItem.Sort(); //} // check the images based on their features for (int i = newBlobs.Count - 1; i >= 0; i--) { if (newItem.Count != 0 && i == newItem.Last()) { newItem.RemoveAt(newItem.Count - 1); } else { // set the name according to the recognized object string currentBlobId = RecognizeObject(newBlobs[i], objects); newBlobs[i].Name = currentBlobId; retList.Add(newBlobs[i]); } } } } } catch (CvException e) { Logger.Instance.Log(e.Message, Logger.LoggerState.ERROR); return(retList); } catch (Exception e) { Logger.Instance.Log(e.Message, Logger.LoggerState.ERROR); //mark a flag that the last frame was corrupt m_LastWasCorrupted = true; } #endregion return(retList); }