Kinect-Matlab: Get joint angle information - matlab

I am a beginner at kinect and I want to use it with matlab. I need joint angle information out of the skeleton data. What is the easiest way to do this?
Thanks.

I am not good with Mat lab, but try to use c# with Visual Studio. Use the SkeletonBasics-WPF in the Microsoft SDK´s as a template to add this code:
public class Angles
{
public double AngleBetweenTwoVectors(Vector3D vectorA, Vector3D vectorB)
{
double dotProduct;
vectorA.Normalize();
vectorB.Normalize();
dotProduct = Vector3D.DotProduct(vectorA, vectorB);
return (double)Math.Acos(dotProduct)/Math.PI*180;
}
public byte[] GetVector(Skeleton skeleton)
{
Vector3D ShoulderCenter = new Vector3D(skeleton.Joints[JointType.ShoulderCenter].Position.X, skeleton.Joints[JointType.ShoulderCenter].Position.Y, skeleton.Joints[JointType.ShoulderCenter].Position.Z);
Vector3D RightShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderRight].Position.X, skeleton.Joints[JointType.ShoulderRight].Position.Y, skeleton.Joints[JointType.ShoulderRight].Position.Z);
Vector3D LeftShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderLeft].Position.X, skeleton.Joints[JointType.ShoulderLeft].Position.Y, skeleton.Joints[JointType.ShoulderLeft].Position.Z);
Vector3D RightElbow = new Vector3D(skeleton.Joints[JointType.ElbowRight].Position.X, skeleton.Joints[JointType.ElbowRight].Position.Y, skeleton.Joints[JointType.ElbowRight].Position.Z);
Vector3D LeftElbow = new Vector3D(skeleton.Joints[JointType.ElbowLeft].Position.X, skeleton.Joints[JointType.ElbowLeft].Position.Y, skeleton.Joints[JointType.ElbowLeft].Position.Z);
Vector3D RightWrist = new Vector3D(skeleton.Joints[JointType.WristRight].Position.X, skeleton.Joints[JointType.WristRight].Position.Y, skeleton.Joints[JointType.WristRight].Position.Z);
Vector3D LeftWrist = new Vector3D(skeleton.Joints[JointType.WristLeft].Position.X, skeleton.Joints[JointType.WristLeft].Position.Y, skeleton.Joints[JointType.WristLeft].Position.Z);
Vector3D UpVector = new Vector3D(0.0, 1.0, 0.0);
double AngleRightElbow = AngleBetweenTwoVectors(RightElbow - RightShoulder, RightElbow - RightWrist);
double AngleRightShoulder = AngleBetweenTwoVectors(UpVector, RightShoulder - RightElbow);
double AngleLeftElbow = AngleBetweenTwoVectors(LeftElbow - LeftShoulder, LeftElbow - LeftWrist);
double AngleLeftShoulder = AngleBetweenTwoVectors(UpVector, LeftShoulder - LeftElbow);
byte[] Angles = {Convert.ToByte(AngleRightElbow), Convert.ToByte(AngleRightShoulder),Convert.ToByte(AngleLeftElbow),Convert.ToByte(AngleLeftShoulder)};
return Angles;
}
}
Insert this at the top. Call the GetVector() method here:
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
}
}
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight));
if (skeletons.Length != 0)
{
foreach (Skeleton skel in skeletons)
{
RenderClippedEdges(skel, dc);
if (skel.TrackingState == SkeletonTrackingState.Tracked)
{
this.DrawBonesAndJoints(skel, dc);
Angles MyAngles = new Angles();
byte[] ReadyAngles = MyAngles.GetVector(skel);
RightElbow.Text = ReadyAngles[0].ToString();
RightShoulder.Text = ReadyAngles[1].ToString();
LeftElbow.Text = ReadyAngles[2].ToString();
LeftShoulder.Text = ReadyAngles[3].ToString();
byte[] SequenceStart = {255};
if (ArduinoPort.IsOpen)
{
ArduinoPort.Write(SequenceStart,0,1);
ArduinoPort.Write(ReadyAngles, 0, 4);
}
}
else if (skel.TrackingState == SkeletonTrackingState.PositionOnly)
{
dc.DrawEllipse(
this.centerPointBrush,
null,
this.SkeletonPointToScreen(skel.Position),
BodyCenterThickness,
BodyCenterThickness);
}
}
}
// prevent drawing outside of our render area
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight));
}
}
As you can see I added 4 textboxes as I am calculating 4 Angles (RS, LF, RE, LE). These Angles are being passed to the textbox in my .xaml file. I hope this works for you.

You would need the Image Acquisition Toolbox, which includes support for Kinect including skeleton data.

Related

Detect color pages or BW pages in PDF

Is there any way that I can detect color pages in a PDF file?
For example I have a PDF file with 5 pages, and the first and last page are in color. How can I detect the color pages? Can iText do it?
Now my solution is to convert PDF to images and then detect images color or black&white, but it takes too long time to do it, I need a fast way.
Convert pdf to image by Adobe Acrobat Code as fellows
public static void ConvertPDF2Image(string pdfInputPath, string imageOutputPath,
string imageName, int startPageNum, int endPageNum, ImageFormat imageFormat, double resolution)
{
Acrobat.CAcroPDDoc pdfDoc = null;
Acrobat.CAcroPDPage pdfPage = null;
Acrobat.CAcroRect pdfRect = null;
Acrobat.CAcroPoint pdfPoint = null;
// Create the document (Can only create the AcroExch.PDDoc object using late-binding)
// Note using VisualBasic helper functions, have to add reference to DLL
pdfDoc = (Acrobat.CAcroPDDoc)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.PDDoc", "");
// validate parameter
if (!pdfDoc.Open(pdfInputPath)) { throw new FileNotFoundException(); }
if (!Directory.Exists(imageOutputPath)) { Directory.CreateDirectory(imageOutputPath); }
if (startPageNum <= 0) { startPageNum = 1; }
if (endPageNum > pdfDoc.GetNumPages() || endPageNum <= 0) { endPageNum = pdfDoc.GetNumPages(); }
if (startPageNum > endPageNum) { int tempPageNum = startPageNum; startPageNum = endPageNum; endPageNum = startPageNum; }
if (imageFormat == null) { imageFormat = ImageFormat.Jpeg; }
if (resolution <= 0) { resolution = 1; }
// start to convert each page
for (int i = startPageNum; i <= endPageNum; i++)
{
pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(i - 1);
pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();
pdfRect = (Acrobat.CAcroRect)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");
int imgWidth = (int)((double)pdfPoint.x * resolution);
int imgHeight = (int)((double)pdfPoint.y * resolution);
pdfRect.Left = 0;
pdfRect.right = (short)imgWidth;
pdfRect.Top = 0;
pdfRect.bottom = (short)imgHeight;
// Render to clipboard, scaled by 100 percent (ie. original size)
// Even though we want a smaller image, better for us to scale in .NET
// than Acrobat as it would greek out small text
pdfPage.CopyToClipboard(pdfRect, 0, 0, (short)(100 * resolution));
IDataObject clipboardData = Clipboard.GetDataObject();
if (clipboardData.GetDataPresent(DataFormats.Bitmap))
{
Bitmap pdfBitmap = (Bitmap)clipboardData.GetData(DataFormats.Bitmap);
pdfBitmap.Save(Path.Combine(imageOutputPath, imageName) + i.ToString() + "." + imageFormat.ToString(), imageFormat);
pdfBitmap.Dispose();
}
}
pdfDoc.Close();
Marshal.ReleaseComObject(pdfPage);
Marshal.ReleaseComObject(pdfRect);
Marshal.ReleaseComObject(pdfDoc);
Marshal.ReleaseComObject(pdfPoint);
}
////detect image Color or black and white as fellows
Bitmap box1 = new Bitmap(PictureBox1.Image);
Color c = new Color()
int rr, gg, bb;
for(int i=0;i<PictureBox1.Width;i++){
for(int j=0;j<PictureBox1.Height;j++){
c= box1.GetPixel(i,j);
rr= c.R; gg=c.g;bb=c.B;
if(c ==Color.Black||c= Color.White){
MessageBox.Show("black and white dot")
}
else {
if(rr==gg==bb){
MessageBox.Show("Gray dot");
}
else {
MessageBOx.Show("Color dot");
}
}
}
}

Taking snapshots of a image in Unity

I am trying to take snapshots of materials I used in my application in Unity. I simply add a directional light and a camera and in a perspective mode. Then I render the result to a texture and save it as a .png file. The result is good but there is a strange gizmo like figure in the middle of image. Here it is :
Camera and light is far enough from the object. Also I disabled light to see if it is caused by directional light. But didn't solve. Anyone knows what cause this elliptic figure? Thanks in advance.
Edit. Here is the code
public static Texture2D CreateThumbnailFromMaterial(Material _material, string _name, string _path)
{
GameObject sphereObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphereObj.name = _name;
sphereObj.GetComponent<Renderer>().material = _material;
Texture2D thumbnailTexture = CreateThumbnailFromModel(sphereObj, _path);
sphereObj.GetComponent<Renderer>().material = null;
Object.DestroyImmediate(sphereObj.gameObject);
return thumbnailTexture;
}
public static Texture2D CreateThumbnailFromModel(GameObject _gameObject, string _path)
{
Texture2D thumbnailTexture = new Texture2D(textureSize, textureSize);
thumbnailTexture.name = _gameObject.name.Simplify();
GameObject cameraObject = Object.Instantiate(Resources.Load("SceneComponent/SnapshotCamera") as GameObject);
Camera snapshotCamera = cameraObject.GetComponent<Camera>();
if (snapshotCamera)
{
GameObject sceneObject = GameObject.Instantiate(_gameObject) as GameObject;
sceneObject.transform.Reset();
sceneObject.transform.position = new Vector3(1000, 0, -1000);
sceneObject.hideFlags = HideFlags.HideAndDontSave;
// Create render texture
snapshotCamera.targetTexture = RenderTexture.GetTemporary(textureSize, textureSize, 24);
RenderTexture.active = snapshotCamera.targetTexture;
// Set layer
foreach (Transform child in sceneObject.GetComponentsInChildren<Transform>(true))
{
child.gameObject.layer = LayerMask.NameToLayer("ObjectSnapshot");
}
// Calculate bounding box
Bounds bounds = sceneObject.GetWorldSpaceAABB();
float maxBoundValue = 0f;
if (bounds.IsValid())
{
maxBoundValue = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z);
}
double fov = Mathf.Deg2Rad * snapshotCamera.GetComponent<Camera>().fieldOfView;
float distanceToCenter = (maxBoundValue) / (float)System.Math.Tan(fov);
cameraObject.transform.LookAt(bounds.center);
cameraObject.transform.position = bounds.center - (snapshotCamera.transform.forward * distanceToCenter);
cameraObject.transform.SetParent(sceneObject.transform);
snapshotCamera.Render();
thumbnailTexture.ReadPixels(new Rect(0, 0, textureSize, textureSize), 0, 0);
thumbnailTexture.Apply();
sceneObject.transform.Reset();
snapshotCamera.transform.SetParent(null);
RenderTexture.active = null;
GameObject.DestroyImmediate(sceneObject);
GameObject.DestroyImmediate(cameraObject);
// Save as .png
IO.IOManager.Instance.SaveAsPNG(_path + thumbnailTexture.name, thumbnailTexture);
}
return thumbnailTexture;
}
And here is my camera properties

Emgucv Image to texture2d on Unity

public class testEmguCV : MonoBehaviour
{
private Capture capture;
void Start()
{
capture = new Capture();
}
void Update()
{
Image<Gray, Byte> currentFrame = capture.QueryGrayFrame();
Bitmap bitmapCurrentFrame = currentFrame.ToBitmap();
MemoryStream m = new MemoryStream();
bitmapCurrentFrame.Save(m, bitmapCurrentFrame.RawFormat);
Texture2D camera = new Texture2D(400, 400);
if (currentFrame != null)
{
camera.LoadImage(m.ToArray());
renderer.material.mainTexture = camera;
}
}
}
I used above code to convert between camera feed from emgucv camera to texture2d in unity but i am having problem with bitmapCurrentFrame.Save(m, bitmapCurrentFrame.RawFormat);
it is giving following errors
ArgumentNullException: Argument cannot be null. Parameter name:
encoder System.Drawing.Image.Save (System.IO.Stream stream,
System.Drawing.Imaging.ImageCodecInfo encoder,
System.Drawing.Imaging.EncoderParameters encoderParams)
System.Drawing.Image.Save (System.IO.Stream stream,
System.Drawing.Imaging.ImageFormat format) (wrapper
remoting-invoke-with-check) System.Drawing.Image:Save
(System.IO.Stream,System.Drawing.Imaging.ImageFormat)
WebcamUsingEmgucv.Update () (at Assets/WebcamUsingEmgucv.cs:51)
After several hours of thinking and searching i dont know what is going on please help
I used your example in our project, thanks! But i modified it to :
void Update()
{
if(capture == null)
{
Debug.LogError("Capture is null");
return;
}
Image<Gray, Byte> currentFrame = capture.QueryGrayFrame();
MemoryStream m = new MemoryStream();
currentFrame.Bitmap.Save(m, currentFrame.Bitmap.RawFormat);
Texture2D camera = new Texture2D(400, 400);
if (currentFrame != null)
{
camera.LoadImage(m.ToArray());
renderer.material.mainTexture = camera;
}
}
And it is work! Fps average ~30-35. Good luck!
Try to use this:
https://github.com/neutmute/emgucv/blob/3ceb85cba71cf957d5e31ae0a70da4bbf746d0e8/Emgu.CV/PInvoke/Unity/TextureConvert.cs
it has something like this:
public static Texture2D ImageToTexture2D<TColor, TDepth>(Image<TColor, TDepth> image, bool correctForVerticleFlip)
where TColor : struct, IColor
where TDepth : new()
{
Size size = image.Size;
if (typeof(TColor) == typeof(Rgb) && typeof(TDepth) == typeof(Byte))
{
Texture2D texture = new Texture2D(size.Width, size.Height, TextureFormat.RGB24, false);
byte[] data = new byte[size.Width * size.Height * 3];
GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
using (Image<Rgb, byte> rgb = new Image<Rgb, byte>(size.Width, size.Height, size.Width * 3, dataHandle.AddrOfPinnedObject()))
{
rgb.ConvertFrom(image);
if (correctForVerticleFlip)
CvInvoke.cvFlip(rgb, rgb, FLIP.VERTICAL);
}
dataHandle.Free();
texture.LoadRawTextureData(data);
texture.Apply();
return texture;
}
else //if (typeof(TColor) == typeof(Rgba) && typeof(TDepth) == typeof(Byte))
{
Texture2D texture = new Texture2D(size.Width, size.Height, TextureFormat.RGBA32, false);
byte[] data = new byte[size.Width * size.Height * 4];
GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
using (Image<Rgba, byte> rgba = new Image<Rgba, byte>(size.Width, size.Height, size.Width * 4, dataHandle.AddrOfPinnedObject()))
{
rgba.ConvertFrom(image);
if (correctForVerticleFlip)
CvInvoke.cvFlip(rgba, rgba, FLIP.VERTICAL);
}
dataHandle.Free();
texture.LoadRawTextureData(data);
texture.Apply();
return texture;
}
//return null;
}
If You don't want tuo use an InterOp You can use also something like
cameraframe.Convert<Rgb,byte>().Data.Cast<byte>().ToArray<byte>()
and use it instead of section using interOp
Both solutions worked for me. Just remember to destroy the texture before replacing it. I had memory leak issues before I did that.

How do I switch the components from a character motor to a character controller?

I am trying to code some underwater functionality for my Unity game, but I am having trouble switching the CharacterMotor components to the CharacterController ones. This is my code:
#pragma strict
var waterLevel : float;
var myParticles : ParticleSystem;
private var isUnderwater : boolean;
private var normalColor : Color;
private var underwaterColor : Color;
private var charcontroller:CharacterController;
function Start ()
{
normalColor = new Color (0.5f, 0.5f, 0.5f, 0.5f);
underwaterColor = new Color (0.22f, 0.65f, 0.77f, 0.5f);
charcontroller = GetComponent(CharacterController);
myParticles.Stop();
GameObject.Find("Blob Light Projector").GetComponent(Projector).enabled = false;
}
function Update ()
{
if ((transform.position.y < waterLevel) != isUnderwater)
{
isUnderwater = transform.position.y < waterLevel;
if (isUnderwater) SetUnderwater ();
if (!isUnderwater) SetNormal ();
}
if(isUnderwater && Input.GetKey(KeyCode.E))
{
constantForce.relativeForce = Vector3(0,-200, 0);
}
else
{
constantForce.relativeForce = Vector3(0, 0, 0);
}
if(isUnderwater && Input.GetKey(KeyCode.Q))
{
constantForce.relativeForce = Vector3(0, 200, 0);
}
}
function SetNormal ()
{
RenderSettings.fogColor = normalColor;
RenderSettings.fogDensity = 0.05f;
GameObject.Find("Blob Light Projector").GetComponent(Projector).enabled = false;
}
**function SetUnderwater ()
{
RenderSettings.fogColor = underwaterColor;
RenderSettings.fogDensity = 0.08f;
charcontroller.Move.gravity = 2;
charcontroller.Move.maxFallSpeed = 5;
charcontroller.Move.maxForwardSpeed = 4;
charcontroller.Move.maxSidewaysSpeed = 4;
myParticles.Play();
GameObject.Find("Blob Light Projector").GetComponent(Projector).enabled = true;
}**
The bolded code is where the error is coming from. Here is a snapshot of the errors I'm getting:
Any help would be really appreciated! Thanks!
You're trying to set properties on CharacterController.Move, which is a function. It doesn't reflect the "movement" property of CharacterMotor.
Check out the script reference and manual to see how to use CharacterController. Specifically, you'll be calling Move with a simple Vector3, and relying on the physics system to take care of the rest.

How to find the four coordinates and erase drawing of an rubberband rectangle in C#

Hi I have tried to draw an rubberband rectangle on a form using the mouse in C#.
Problems
1) After the mouse release the rectangle disappears. [I want it to stay on the form]
2) I also need to find the coordinates of the four points of the drawn rectangle
3) I also need to erase the rectangle to draw a new one when necessary
Form :
CODE
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace rubberbandrectangle
{
public partial class Form1 : Form
{
Boolean bHaveMouse;
Point ptOriginal = new Point();
Point ptLast = new Point();
public Form1()
{
InitializeComponent();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
bHaveMouse = true;
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
ptLast.X = -1;
ptLast.Y = -1;
}
private void MyDrawReversibleRectangle(Point p1, Point p2)
{
Rectangle rc = new Rectangle();
p1 = PointToScreen(p1);
p2 = PointToScreen(p2);
if (p1.X < p2.X)
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if (p1.Y < p2.Y)
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
ControlPaint.DrawReversibleFrame(rc,
Color.Red, FrameStyle.Dashed);
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
bHaveMouse = false;
if (ptLast.X != -1)
{
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Point ptCurrent = new Point(e.X, e.Y);
if (bHaveMouse)
{
if (ptLast.X != -1)
{
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
ptLast = ptCurrent;
MyDrawReversibleRectangle(ptOriginal, ptCurrent);
}
}
private void Form1_Load(object sender, EventArgs e)
{
MouseDown += new MouseEventHandler(Form1_MouseDown);
MouseUp += new MouseEventHandler(Form1_MouseUp);
MouseMove += new MouseEventHandler(Form1_MouseMove);
bHaveMouse = false;
}
}
}
Thanks for reading
1) After the mouse release the rectangle disappears. [I want it to stay on the form]
You need to override the form's OnPaint method in order to continually draw your rectangle. Right now, you draw it when the mouse moves, but it needs to be drawn afterwards, as well.
2) I also need to find the coordinates of the four points of the drawn rectangle
These should be in your ptOriginal and ptLast variables - What more do you need?
3) I also need to erase the rectangle to draw a new one when necessary
Just stop drawing the rectangle, and draw the new one in the OnPaint.
I was looking for a similar thing but was amazed by the solution I found!
You have the coordinates right?
You can just use VisualBasic PowerPacks, it is included with my version of Visual Studio 2008
Here's a sample code that will draw a rectangle over a TextBox, i.e. I am giving it a custom border
[code]
Dim x = TextBox1.Location.X
Dim y = TextBox1.Location.Y
Dim width = TextBox1.Width
Dim height = TextBox1.Height
Dim ShapeContainer1 As New Microsoft.VisualBasic.PowerPacks.ShapeContainer
Me.Controls.Add(ShapeContainer1)
Dim RectangleShape1 As New Microsoft.VisualBasic.PowerPacks.RectangleShape
ShapeContainer1.Shapes.AddRange(New Microsoft.VisualBasic.PowerPacks.Shape() {RectangleShape1})
RectangleShape1.Location = New System.Drawing.Point(x - 1, y - 1)
RectangleShape1.Size = New System.Drawing.Size(width + 1, height + 1)
RectangleShape1.BorderColor = Color.MistyRose
ShapeContainer1.Refresh()
Code is self describing but if you'd have any problem, just leave a message...
Yes, if you want to remove the rectangle, just dispose the controls(either the Rectangle or the ShapeContainer in whole), no painting, no hassle!