// Update is called once per frame void Update() { if (cameraAlignment == null) { Debug.Log("TemporalWarpingStatus requires LeapCameraAlignment reference -> status will be disabled"); gameObject.SetActive(false); return; } if (!cameraAlignment.isActiveAndEnabled) { return; } using (ImageList list = HandController.Main.GetImageFrame().Images){ using (Leap.Image image = list[0]) { float latency = HandController.Main.GetLeapController().Now() - image.Timestamp; _imageLatency.Update(latency, Time.deltaTime); } } _frameDelta.Update(Time.deltaTime, Time.deltaTime); string statusText = "IMAGE LATENCY: " + (_imageLatency.value / 1000f).ToString("#00.0") + " ms\n"; statusText += "FRAME DELTA: " + (_frameDelta.value * 1000).ToString("#00.0") + " ms\n"; statusText += "REWIND ADJUST: " + (cameraAlignment.RewindAdjust).ToString("#00.0") + " ms\n"; textField.text = statusText; }
public static void Main(string[] args) { Controller controller = new Controller(); SampleListener listener = new SampleListener(); listener.TestEvent += imRedu; controller.Connect += listener.OnServiceConnect; controller.Device += listener.OnConnect; //controller.FrameReady += listener.OnFrame; Leap.Image image = new Leap.Image(); controller.StartConnection(); Console.WriteLine("TestCall"); listener.TestCall( ); Console.WriteLine("Is controller connected? " + controller.IsConnected); Frame frame = controller.Frame(); image = controller.RequestImages(frame.Id, Leap.Image.ImageType.DEFAULT); //controller.ImageReady += imRedu; Console.WriteLine("Frame ID: " + frame.Id + ", Is complete? " + image.IsComplete); // Keep this process running until Enter is pressed Console.WriteLine("Press Enter to quit..."); Console.ReadLine(); controller.Dispose(); }
protected void Update(object sender, EventArgs e) { paintCanvas.Strokes.Clear(); windowWidth = (float)this.Width; windowHeight = (float)this.Height; Leap.Frame frame = leap.Frame(); InteractionBox interactionBox = leap.Frame().InteractionBox; try { Leap.Image image = frame.Images[0]; this.DrawRawImages_WriteableBitmap(image.Data, image.Width, image.Height); } catch { } foreach (Pointable pointable in leap.Frame().Pointables) { Finger oFinger = new Finger(pointable); Leap.Vector normalizedPosition = interactionBox.NormalizePoint(pointable.StabilizedTipPosition); float tx = normalizedPosition.x * windowWidth; float ty = windowHeight - normalizedPosition.y * windowHeight; int alpha = 255; if (pointable.TouchDistance > 0 && pointable.TouchZone != Pointable.Zone.ZONENONE) { alpha = 255 - (int)(255 * pointable.TouchDistance); touchIndicator.Color = Color.FromArgb((byte)alpha, 0x0, 0xff, 0x0); } else if (pointable.TouchDistance <= 0) { alpha = -(int)(255 * pointable.TouchDistance); touchIndicator.Color = Color.FromArgb((byte)alpha, 0xff, 0x0, 0x0); } else { alpha = 50; touchIndicator.Color = Color.FromArgb((byte)alpha, 0x0, 0x0, 0xff); } StylusPoint touchPoint = new StylusPoint(tx, ty); StylusPointCollection tips = new StylusPointCollection(new StylusPoint[] { touchPoint }); Stroke touchStroke = new Stroke(tips, touchIndicator); paintCanvas.Strokes.Add(touchStroke); } }
/// <summary> /// 3次元の手の座標をカメラの2次元座標に変換する /// </summary> /// <param name="image"></param> /// <param name="fingers"></param> /// <returns></returns> private static Leap.Vector[] MapCameraToColor(Leap.Image image, FingerList fingers) { var colorPoints = new List <Leap.Vector>(); float cameraOffset = 20; //x-axis offset in millimeters foreach (Finger finger in fingers) { // 3次元座標を2次元座標に変換する var tip = finger.TipPosition; float hSlope = -(tip.x + cameraOffset * (2 * image.Id - 1)) / tip.y; float vSlope = tip.z / tip.y; colorPoints.Add(image.Warp(new Leap.Vector(hSlope, vSlope, 0))); } return(colorPoints.ToArray()); }
private static Leap.Vector[] MapCalibratedCameraToColor(Leap.Image image, FingerList fingers, int targetWidth, int targetHeight) { var colorPoints = new List <Leap.Vector>(); float cameraXOffset = 20; //millimeters foreach (Finger finger in fingers) { var tip = finger.TipPosition; float hSlope = -(tip.x + cameraXOffset * (2 * image.Id - 1)) / tip.y; float vSlope = tip.z / tip.y; var ray = new Leap.Vector(hSlope * image.RayScaleX + image.RayOffsetX, vSlope * image.RayScaleY + image.RayOffsetY, 0); //Pixel coordinates from [0..1] to [0..width/height] colorPoints.Add(new Leap.Vector(ray.x * targetWidth, ray.y * targetHeight, 0)); } return(colorPoints.ToArray()); }
void newFrameHandler(Leap.Frame frame) { try { this.displayID.Content = frame.Id.ToString(); this.displayTimestamp.Content = frame.Timestamp.ToString(); this.displayFPS.Content = frame.CurrentFramesPerSecond.ToString(); this.displayIsValid.Content = frame.IsValid.ToString(); this.displayGestureCount.Content = frame.Gestures().Count.ToString(); this.displayImageCount.Content = frame.Images.Count.ToString(); // Bitmap To BitmapSource方式获取图像 //Leap.Image image = frame.Images[0]; //this.DrawRawImages_Bitmap(image.Data, image.Width, image.Height); //WriteableBitmap方式 Leap.Image image = frame.Images[0]; this.DrawRawImages_WriteableBitmap(image.Data, image.Width, image.Height); } catch (Exception ex) { this.debugText.Text += "Init " + "\r\n"; } }
// 绘制采集到的图像 private void ShowRawImages(Leap.Frame frame) { Leap.Image image = frame.Images[0]; byte[] rawImageData = image.Data; int dWidth = image.Width; int dHeight = image.Height; Dispatcher.BeginInvoke(new Action(delegate() { if (this.CurBitmap == null || this.ImgMain.Source == null) { List <System.Windows.Media.Color> grayscale = new List <System.Windows.Media.Color>(); for (byte i = 0; i < 0xff; i++) { grayscale.Add(System.Windows.Media.Color.FromArgb(0xff, i, i, i)); } BitmapPalette palette = new BitmapPalette(grayscale); this.CurBitmap = new WriteableBitmap(dWidth, dHeight, 72, 72, PixelFormats.Gray8, palette); this.ImgMain.Source = this.CurBitmap; } this.CurBitmap.WritePixels(new Int32Rect(0, 0, dWidth, dHeight), rawImageData, dWidth * this.CurBitmap.Format.BitsPerPixel / 8, 0); })); }
private static BitmapSource ToCalibratedBitmap(int targetWidth, int targetHeight, Leap.Image image) { var buffer = new byte[targetWidth * targetHeight]; //Iterate over target image pixels, converting xy to ray slope for (int y = 0; y < targetHeight; y++) { for (int x = 0; x < targetWidth; x++) { //Normalize from pixel xy to range [0..1] var input = new Leap.Vector(x / (float)targetWidth, y / (float)targetHeight, 0); //Convert from normalized [0..1] to slope [-4..4] input.x = (input.x - image.RayOffsetX) / image.RayScaleX; input.y = (input.y - image.RayOffsetY) / image.RayScaleY; //Use slope to get coordinates of point in image.Data containing the brightness for this target pixel var pixel = image.Warp(input); int bufferIndex = (y * targetWidth) + x; if (pixel.x >= 0 && pixel.x < image.Width && pixel.y >= 0 && pixel.y < image.Height) { int dataIndex = (int)(Math.Floor(pixel.y) * image.Width + Math.Floor(pixel.x)); //xy to buffer index buffer[bufferIndex] = image.Data[dataIndex]; } else { buffer[bufferIndex] = 255; } } } return(BitmapSource.Create(targetWidth, targetHeight, 96, 96, PixelFormats.Gray8, null, buffer, targetWidth)); }
/// <summary> /// カメラ画像を作成する /// </summary> /// <param name="image"></param> /// <returns></returns> private static BitmapSource ToBitmapSource(Leap.Image image) { return(BitmapSource.Create(image.Width, image.Height, 96, 96, PixelFormats.Gray8, null, image.Data, image.Width * image.BytesPerPixel)); }
public override void OnFrame(Controller controller) { controller.SetPolicy(Controller.PolicyFlag.POLICY_IMAGES); controller.SetPolicy(Controller.PolicyFlag.POLICY_BACKGROUND_FRAMES); controller.SetPolicy(Controller.PolicyFlag.POLICYBACKGROUNDFRAMES); Frame frame = controller.Frame(); serializingData = frame.Serialize; foreach (Hand hand in frame.Hands) { foreach (Finger finger in hand.Fingers) { Leap.Image image = frame.Images[0]; Bitmap bitmap = new Bitmap(image.Width, image.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); ColorPalette grayscale = bitmap.Palette; for (int i = 0; i < 255; i++) { grayscale.Entries[i] = Color.FromArgb((int)255, i, i, i); } bitmap.Palette = grayscale; Rectangle lockArea = new Rectangle(0, 0, bitmap.Width, bitmap.Height); BitmapData bitmapData = bitmap.LockBits(lockArea, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); byte[] rawImageData = image.Data; System.Runtime.InteropServices.Marshal.Copy(rawImageData, 0, bitmapData.Scan0, image.Width * image.Height); bitmap.UnlockBits(bitmapData); bitmap.Dispose(); serializingData = image.Data; Bone bone; foreach (Bone.BoneType boneType in (Bone.BoneType[])Enum.GetValues(typeof(Bone.BoneType))) { bone = finger.Bone(boneType); if (hand.IsRight) { t[0] = (int)hand.PalmPosition.x + 300; t[1] = (int)hand.PalmPosition.z + 300; t[2] = (int)hand.PalmPosition.y + 300; h[0] = (int)hand.WristPosition.x + 300; h[1] = (int)hand.WristPosition.y + 300; h[2] = (int)hand.WristPosition.z + 300; px = (int)hand.WristPosition.x + 300; py = (int)hand.WristPosition.z + 300; pz = (int)hand.WristPosition.y + 300; wrist[0] = hand.WristPosition.x + 300; wrist[1] = hand.WristPosition.y + 300; wrist[2] = hand.WristPosition.z + 300; rotation = hand.RotationAngle(frame); if (finger.Type == Finger.FingerType.TYPE_MIDDLE) { if (boneType == Bone.BoneType.TYPE_DISTAL) { cordX = bone.PrevJoint.x + 300; cordY = bone.PrevJoint.z + 300; cordZ = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { cordX1 = bone.NextJoint.x + 300; cordY1 = bone.NextJoint.z + 300; } if (boneType == Bone.BoneType.TYPE_PROXIMAL) { cordX2 = bone.PrevJoint.x + 300; cordY2 = bone.PrevJoint.z + 300; cordZ2 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_METACARPAL) { cordX3 = bone.PrevJoint.x + 300; cordY3 = bone.PrevJoint.z + 300; } } if (finger.Type == Finger.FingerType.TYPE_INDEX) { if (boneType == Bone.BoneType.TYPE_DISTAL) { cordX4 = bone.PrevJoint.x + 300; cordY4 = bone.PrevJoint.z + 300; cordZ4 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { cordX5 = bone.NextJoint.x + 300; cordY5 = bone.NextJoint.z + 300; } if (boneType == Bone.BoneType.TYPE_PROXIMAL) { cordX6 = bone.PrevJoint.x + 300; cordY6 = bone.PrevJoint.z + 300; cordZ6 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_METACARPAL) { cordX7 = bone.PrevJoint.x + 300; cordY7 = bone.PrevJoint.z + 300; } } if (finger.Type == Finger.FingerType.TYPE_PINKY) { if (boneType == Bone.BoneType.TYPE_DISTAL) { cordX8 = bone.PrevJoint.x + 300; cordY8 = bone.PrevJoint.z + 300; cordZ8 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { cordX9 = bone.NextJoint.x + 300; cordY9 = bone.NextJoint.z + 300; } if (boneType == Bone.BoneType.TYPE_PROXIMAL) { cordX10 = bone.PrevJoint.x + 300; cordY10 = bone.PrevJoint.z + 300; cordZ10 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_METACARPAL) { cordX11 = bone.PrevJoint.x + 300; cordY11 = bone.PrevJoint.z + 300; cordZ11 = bone.PrevJoint.y + 300; } } if (finger.Type == Finger.FingerType.TYPE_RING) { if (boneType == Bone.BoneType.TYPE_DISTAL) { cordX12 = bone.PrevJoint.x + 300; cordY12 = bone.PrevJoint.z + 300; cordZ12 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { cordX13 = bone.NextJoint.x + 300; cordY13 = bone.NextJoint.z + 300; cordZ14 = bone.NextJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_PROXIMAL) { cordX14 = bone.PrevJoint.x + 300; cordY14 = bone.PrevJoint.z + 300; cordZ14 = bone.NextJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_METACARPAL) { cordX15 = bone.PrevJoint.x + 300; cordY15 = bone.PrevJoint.z + 300; cordZ15 = bone.PrevJoint.y + 300; } } if (finger.Type == Finger.FingerType.TYPE_THUMB) { if (boneType == Bone.BoneType.TYPE_DISTAL) { cordX16 = bone.PrevJoint.x + 300; cordY16 = bone.PrevJoint.z + 300; cordZ16 = bone.PrevJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { cordX17 = bone.NextJoint.x + 300; cordY17 = bone.NextJoint.z + 300; cordZ17 = bone.NextJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_PROXIMAL) { cordX18 = bone.PrevJoint.x + 300; cordY18 = bone.PrevJoint.z + 300; cordZ18 = bone.NextJoint.y + 300; } if (boneType == Bone.BoneType.TYPE_METACARPAL) { cordX19 = bone.PrevJoint.x + 300; cordZ19 = bone.PrevJoint.y + 300; cordY19 = bone.PrevJoint.z + 300; } } } } } } }
void Update() { if (undistortImage) { renderer.material = new Material(Shader.Find(UNDISTORT_SHADER)); } else { renderer.material = new Material(Shader.Find(NORMAL_SHADER)); } Frame frame = leap_controller_.Frame(); if (frame.Images.Count == 0) { image_misses_++; if (image_misses_ == IMAGE_WARNING_WAIT) { Debug.LogWarning("Can't find any images. " + "Make sure you enabled 'Allow Images' in the Leap Motion Settings, " + "you are on tracking version 2.1+ and " + "your Leap Motion device is plugged in."); } return; } // Check main texture dimensions. Leap.Image image = frame.Images[imageIndex]; int image_width = image.Width; int image_height = image.Height; if (image_width == 0 || image_height == 0) { Debug.LogWarning("No data in the image texture."); return; } if (image_width != main_texture_.width || image_height != main_texture_.height) { SetMainTextureDimensions(image_width, image_height); } // Check distortion texture dimensions. // Divide by two 2 because there are floats per pixel. int distortion_width = image.DistortionWidth / 2; int distortion_height = image.DistortionHeight; if (distortion_width == 0 || distortion_height == 0) { Debug.LogWarning("No data in the distortion texture."); return; } if (distortion_width != distortionX_.width || distortion_height != distortionX_.height) { SetDistortionDimensions(distortion_width, distortion_height); } // Load image texture data. image_data_ = image.Data; distortion_data_ = image.Distortion; LoadMainTexture(); if (undistortImage) { EncodeDistortion(); } ApplyDataToTextures(); renderer.material.mainTexture = main_texture_; renderer.material.SetColor("_Color", imageColor); renderer.material.SetFloat("_GammaCorrection", gammaCorrection); renderer.material.SetInt("_BlackIsTransparent", blackIsTransparent ? 1 : 0); if (undistortImage) { renderer.material.SetTexture("_DistortX", distortionX_); renderer.material.SetTexture("_DistortY", distortionY_); renderer.material.SetFloat("_RayOffsetX", image.RayOffsetX); renderer.material.SetFloat("_RayOffsetY", image.RayOffsetY); renderer.material.SetFloat("_RayScaleX", image.RayScaleX); renderer.material.SetFloat("_RayScaleY", image.RayScaleY); } }
protected void Update(object sender, EventArgs e) { Dispatcher.BeginInvoke(new Action(delegate() { Leap.Frame frame = leap.Frame(); //Draw Camera Images try { Leap.Image image = frame.Images[0]; this.DrawRawImages_WriteableBitmap(image.Data, image.Width, image.Height); } catch { } if (!frame.Hands.IsEmpty) { DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); InteractionBox interactionBox = frame.InteractionBox; // Draw Hand Center Hand oHand = frame.Hands.FirstOrDefault(); Leap.Vector handNormalizePos = interactionBox.NormalizePoint(oHand.StabilizedPalmPosition); Point handPos = this.ToScreen(handNormalizePos); drawingContext.DrawEllipse(this.BrushBlue, new Pen(), new Point(handPos.X, handPos.Y), 20, 20); // Draw finger tip and update Palm State foreach (Finger oFinger in oHand.Fingers) { // Draw Bones this.DrawFingerBones(oFinger, interactionBox, drawingContext); Leap.Vector fingerNormalizePos = interactionBox.NormalizePoint(oFinger.StabilizedTipPosition); //Point fingerPos = this.ToScreen(fingerNormalizePos); //drawingContext.DrawEllipse(this.BrushRed, new Pen(), new Point(fingerPos.X, fingerPos.Y), 6, 6); this.PalmPlane.UpdatePalmState(oFinger, fingerNormalizePos, handNormalizePos); } // Update Palm Location this.PalmPlane.X = handPos.X - this.PalmPlane.Width / 2d; this.PalmPlane.Y = handPos.Y - this.PalmPlane.Height / 2d; drawingContext.Close(); RenderTargetBitmap rtb = new RenderTargetBitmap((int)CvMain.ActualWidth, (int)this.CvMain.ActualHeight, 96, 96, PixelFormats.Pbgra32); rtb.Render(drawingVisual); this.ImgMain.Source = rtb; } else { if (this.PalmPlane != null) { this.PalmPlane.X = -300; this.PalmPlane.Y = -300; this.PalmPlane.RevertFingerState(); } this.ImgMain.Source = null; } })); }
//Boolean initialize = true; private void newFrameHandler(Frame frame) { //The image at index 0 is the left camera; the image at index 1 is the right camera Leap.Image imageLeft = frame.Images[0]; Leap.Image imageRight = frame.Images[1]; if (imageLeft.IsValid) { imageL = frame.Images[0]; //將 Bitmap 鎖定在系統記憶體內,BitmapData 指定 Bitmap 的屬性,例如大小、像素格式、像素資料在記憶體中的起始位址,以及每條掃描線 (分散) 的長度。 BitmapData bitmapData = bitmapLeft.LockBits(lockArea, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); byte[] rawImageData = imageLeft.Data; //byte[] destination = new byte[640 * 240]; ////define needed variables outside the inner loop //double calibrationX, calibrationY; //double weightX, weightY; //double dX, dX1, dX2, dX3, dX4; //double dY, dY1, dY2, dY3, dY4; //int x1, x2, y1, y2; //int distortionWidth = imageLeft.DistortionWidth; //float[] distortion_buffer = imageLeft.Distortion; //for (int i = 0; i < 640; i++) //{ // for (int j = 0; j < 240; j++) // { // //Calculate the position in the calibration map (still with a fractional part) // calibrationX = 63.0f * (double)i / 640; // calibrationY = 62.0f * (1.0f - (double)j / 240); // The y origin is at the bottom // weightX = calibrationX - (double)((int)calibrationX); // weightY = calibrationY - (double)((int)calibrationY); // //Get the x,y coordinates of the closest calibration map points to the target pixel // x1 = (int)calibrationX; //Note truncation to int // y1 = (int)calibrationY; // x2 = x1 + 1; // y2 = y1 + 1; // //Look up the x and y values for the 4 calibration map points around the target // dX1 = distortion_buffer[x1 * 2 + y1 * distortionWidth]; // dX2 = distortion_buffer[x2 * 2 + y1 * distortionWidth]; // dX3 = distortion_buffer[x1 * 2 + y2 * distortionWidth]; // dX4 = distortion_buffer[x2 * 2 + y2 * distortionWidth]; // dY1 = distortion_buffer[x1 * 2 + y1 * distortionWidth + 1]; // dY2 = distortion_buffer[x2 * 2 + y1 * distortionWidth + 1]; // dY3 = distortion_buffer[x1 * 2 + y2 * distortionWidth + 1]; // dY4 = distortion_buffer[x2 * 2 + y2 * distortionWidth + 1]; // //Bilinear interpolation of the looked-up values: // // X value // dX = dX1 * (1 - weightX) * (1 - weightY) + // dX2 * weightX * (1 - weightY) + // dX3 * (1 - weightX) * weightY + // dX4 * weightX * weightY; // // Y value // dY = dY1 * (1 - weightX) * (1 - weightY) + // dY2 * weightX * (1 - weightY) + // dY3 * (1 - weightX) * weightY + // dY4 * weightX * weightY; // // Reject points outside the range [0..1] // if ((dX >= 0) && (dX <= 1) && (dY >= 0) && (dY <= 1)) // { // //look up the brightness value for the target pixel // if ((rawImageData[(int)((dX * imageLeft.Width) + (int)(dY * imageLeft.Height) * imageLeft.Width)]) < 255) // destination[i + (int)(640 * j)] = (byte)(rawImageData[(int)((dX * imageLeft.Width) + (int)(dY * imageLeft.Height) * imageLeft.Width)]); // else // destination[i + (int)(640 * j)] = 255; // } // } //} //Copy the image values back to the bitmap. bitmapData.Scan0 is the address of the first line. System.Runtime.InteropServices.Marshal.Copy(rawImageData, 0, bitmapData.Scan0, imageLeft.Width * imageLeft.Height); //從系統記憶體解除鎖定這個 Bitmap bitmapLeft.UnlockBits(bitmapData); //show image in the picturebox picboxLeapLeft.Image = bitmapLeft; /* if (initialize) { dx_L = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv32F, 1); dy_L = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv32F, 1); this.initDistortionMat(imageLeft, dx_L, dy_L); initialize = false; } else { //將LeapMotion影像資料轉成OpenCV的影像格式 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*mat(rows, columns, type, channels) **type is of the type CvEnum.DepthType, which is the depth of the image, you can pass CvEnum.DepthType.Cv32F which stands for 32bit depth images, other possible values are of the form CvEnum.DepthType.Cv{x}{t}, where {x} is any value of the set {8,16,32,64} and {t} can be Sfor Single or F for Float. **channels depend on the type of image **Depthtype : Member name Value Description Default -1 default Cv8U 0 Byte Cv8S 1 SByte Cv16U 2 UInt16 Cv16S 3 Int16 Cv32S 4 Int32 Cv32F 5 float Cv64F 6 double */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*Mat opencvImg = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv8U, 1); opencvImg.SetTo(imageLeft.Data); //remap to undistorted image Mat undistortedImg = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv8U, 1); Mat dx = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv8U, 1); Mat dy = new Mat(imageLeft.Height, imageLeft.Width, DepthType.Cv8U, 1); CvInvoke.ConvertMaps(dx_L, dy_L, dx, dy, DepthType.Cv8U, 1); CvInvoke.Remap(opencvImg, undistortedImg, dx, dy, Inter.Linear); picboxLeapLeft.Image = undistortedImg.ToImage<Gray, Byte>().ToBitmap(); }*/ } if (imageRight.IsValid) { imageR = frame.Images[1]; //將 Bitmap 鎖定在系統記憶體內,BitmapData 指定 Bitmap 的屬性,例如大小、像素格式、像素資料在記憶體中的起始位址,以及每條掃描線 (分散) 的長度。 BitmapData bitmapData = bitmapRight.LockBits(lockArea, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); byte[] rawImageData = imageRight.Data; //Copy the image values back to the bitmap. bitmapData.Scan0 is the address of the first line. System.Runtime.InteropServices.Marshal.Copy(rawImageData, 0, bitmapData.Scan0, imageRight.Width * imageRight.Height); //從系統記憶體解除鎖定這個 Bitmap bitmapRight.UnlockBits(bitmapData); //show image in the picturebox picboxLeapRight.Image = bitmapRight; } //get leap motion camera current frame per second float fps = frame.CurrentFramesPerSecond; txtLeapFPS.Text = fps.ToString(); }