I'm Using Kinect v1 with SDK 1.8. I need to pass my data to faceTracker.Track() method.
But in constructor of track() is asking Skeleton parameter at the end.
But cannot take directly skeleton data to skeleton object. It provides as an data array.
How can I pass data to this faceTracker.Track() method as the track method requested?
The following is the way I tried.
using (SkeletonFrame skeletonFrame = allFramesReadyEventArgs.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletonData != null) // check that a frame is available
{
skeletonData = new Skeleton [newSensor.SkeletonStream.FrameSkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(this.skeletonData); // get the skeletal information in this frame
this.skeletonData = new Skeleton[this.newSensor.SkeletonStream.FrameSkeletonArrayLength];
}
}
track method
if (faceTracker == null)
{
try
{
faceTracker = new FaceTracker(sensorChooser.Kinect);
}
catch (InvalidOperationException)
{
//write something
}
if (faceTracker != null)
{
FaceTrackFrame frame = faceTracker.Track(
sensorChooser.Kinect.ColorStream.Format,
colorImageData,
sensorChooser.Kinect.DepthStream.Format,
colorPixels,
skeletonData);
}
}
i defined Skeleton [] skeletonData ;as this
and follwing is the track method given in Kinect SDK
public FaceTrackFrame Track(
ColorImageFormat colorImageFormat,
byte[] colorImage,
DepthImageFormat depthImageFormat,
short[] depthImage,
Skeleton skeletonOfInterest)
{
return this.Track(colorImageFormat, colorImage, depthImageFormat, depthImage, skeletonOfInterest, Rect.Empty);
}
foreach (Skeleton skeleton in this.skeletonData)
{
if (skeleton.TrackingState == SkeletonTrackingState.Tracked
|| skeleton.TrackingState == SkeletonTrackingState.PositionOnly)
{
// We want keep a record of any skeleton, tracked or untracked.
if (!this.trackedSkeletons.ContainsKey(skeleton.TrackingId))
{
this.trackedSkeletons.Add(skeleton.TrackingId, new SkeletonFaceTracker());
}
// Give each tracker the upated frame.
SkeletonFaceTracker skeletonFaceTracker;
if (this.trackedSkeletons.TryGetValue(skeleton.TrackingId, out skeletonFaceTracker))
{
skeletonFaceTracker.OnFrameReady(this.Kinect, colorImageFormat, colorImage, depthImageFormat, depthImage, skeleton);
skeletonFaceTracker.LastTrackedFrame = skeletonFrame.FrameNumber;
}
}
}
I solved it as above with the help of kinect toolkit 1.8 the project FaceTrackingBasics-WPF application.
Related
I'm using the https://github.com/Ruslan-B/FFmpeg.AutoGen library to connect to an rtsp camera stream and save the frames as png images.
Testing with the FFMPEG.Autogen's example project present in the GitHub repository with no changes I've noticed that the memory usage seems to constantly grow in infinitely. I've made sure to dispose of all bitmaps, pointers etc after use but am unable to pinpoint the source of the issue.
It seems to be coming from their VideoStreamDecoder.TryDecodeNextFrame method as shown below:
public bool TryDecodeNextFrame(out AVFrame frame)
{
ffmpeg.av_frame_unref(_pFrame);
ffmpeg.av_frame_unref(_receivedFrame);
int error;
do
{
try
{
do
{
error = ffmpeg.av_read_frame(_pFormatContext, _pPacket);
if (error == ffmpeg.AVERROR_EOF)
{
frame = *_pFrame;
return false;
}
else if(error < 0)
{
}
error.ThrowExceptionIfError();
} while (_pPacket->stream_index != _streamIndex);
ffmpeg.avcodec_send_packet(_pCodecContext, _pPacket).ThrowExceptionIfError();
}
finally
{
ffmpeg.av_packet_unref(_pPacket);
}
error = ffmpeg.avcodec_receive_frame(_pCodecContext, _pFrame);
} while (error == ffmpeg.AVERROR(ffmpeg.EAGAIN));
error.ThrowExceptionIfError();
if (_pCodecContext->hw_device_ctx != null)
{
ffmpeg.av_hwframe_transfer_data(_receivedFrame, _pFrame, 0).ThrowExceptionIfError();
frame = *_receivedFrame;
}
else
{
frame = *_pFrame;
}
return true;
}
I am using a OverlapSphere to detect all colliders within a certain radius of my object. I then filter out a few I don't care about. With the remaining few, I attempt to send a message to those objects to update their render color. Whenever it sends the message, unity freezes. I tried to do some research and the best thing i could find is that infinite loops can freeze it. But i don't see a potential for that. Here is the code:
Object to send the message:
void sendmyMessage(bool status)
{
Collider[] tiles = Physics.OverlapSphere(gameObject.transform.position, 10);
int i = 0;
while (i < tiles.Length)
{
if(tiles[i].tag == "Tile")
{
//turn light on
if (status == true)
{
tiles[i].SendMessage("Highlight", true);
i++;
}
//turn light off
if (status == false)
{
tiles[i].SendMessage("Highlight", false);
i++;
}
}
}
}
Object Receiving Message:
void Highlight(bool status)
{
//turn light on
if(status == true)
{
gameObject.GetComponent<Renderer>().material.color = new Color(0, 0, 0);
}
//turn light off
if(status == false)
{
gameObject.GetComponent<Renderer>().material.color = new Color(1, 1, 1);
}
}
Any help is much appreciated!
It freezes because of logic if(tiles[i].tag == "Tile") here's your answer. Now imagine that object that you collide with has tag "not a tile"? then the loop never ends.
foreach(var tile in tiles) {
if (tile.tag == "Tile") {
tiles[i].SendMessage("Highlight", status);
}
}
while (i < tiles.Length)
{
if(tiles[i].tag == "Tile")
{
//snip
}
// else - loop forever?
}
Here's your problem. If the tag != "Tile" then you never increment i.
I have been searching this issue in the web and have gone trough the documentation,however was not successful in finding a solution.
In my code I have created a MasterPane and utilize 13 GraphPanes,The problem is that if there are many graphs, the details become indistinguishable,hence I want to select(by clicking) a graph and enlarge it.Is there a specific function to realize this goal.If not,which steps are to be followed.
Thank you in advance
Even late,i hope it'll will help others.
The idea is to use the MasterPan PaneList collection.
I added a few buttons to the Window and do the control from them, another way
is to use FindPane method in the MasterPan class and do this by clicking.
I'll show both ways.
The code follows:
// graphSystem Class
MasterPane masterPane;
PaneList plist = new PaneList();
private void InitGraphs()
{
//Zedgraph control
var zgc = Apprefs.Zedgraph;
//MasterPan
masterPane = zgc.CreateMasterPan(Title, System.Drawing.Color.White);
// CreateMultiGraph is my own API to create Graph
zgc.CreateMultiGraph("Graph1", 1, "G1xtitle", "G1ytitle", false);
zgc.CreateMultiGraph("Graph2", 1, "G2xtitle", "G2ytitle", false);
zgc.CreateMultiGraph("Graph3", 1, "G3xtitle", "G3ytitle", false);
// save the Pans
foreach (GraphPane graph in masterPane.PaneList)
plist.Add(graph);
}
//---------------------------------------------------------------------------
public void Englare(RichButton button)
{
var graph = Apprefs.Zedgraph2.graph;
if (button.Name == "Show1")
{
ShowOneGraph(0);
}
else if (button.Name == "Show2")
{
ShowOneGraph(1);
}
else if (button.Name == "ShowAll")
{
ShowAllGraphs();
}
}
//---------------------------------------------------------------------------
private void ShowOneGraph(int Graphindex)
{
if (masterPane == null) return;
var graph = Apprefs.Zedgraph.graph;
if (Graphindex >= 0 && Graphindex < plist.Count)
{
masterPane.PaneList.Clear();
masterPane.PaneList.Add(plist[Graphindex]);
Layout();
}
}
//---------------------------------------------------------------------------
private void ShowAllGraphs()
{
if (masterPane == null) return;
var graph = Apprefs.Zedgraph.graph;
masterPane.PaneList.Clear();
foreach (GraphPane gr in plist)
masterPane.PaneList.Add(gr);
Layout();
}
//---------------------------------------------------------------------------
private void Layout()
{
var graph = Apprefs.Zedgraph2.graph;
using (Graphics g = graph.CreateGraphics())
{
masterPane.SetLayout(g, PaneLayout.SingleColumn);
graph.AxisChange();
graph.Refresh();
}
}
//---------------------------------------------------------------------------
way2: englare by click On Graph:
Add this method:
//---------------------------------------------------------------------------
GraphPane lastpan;
public void UCclicked(PointF mousePt)
{
GraphPane pan= masterPane.FindPane(mousePt);
if (pan != null)
{
if (pan == lastpan)
{
ShowAllGraphs();
lastpan = null;
}
else
{
ShowOneGraph(plist.IndexOf(pan));
lastpan = pan;
}
} }
Also register to the click event:
zgcGraph.MouseDoubleClick += new MouseEventHandler(zgcGraph_MouseDoubleClick);
And finally:
void zgcGrzgcGraph_MouseDoubleClick(object source, System.Windows.Forms.MouseEventArgs e)
{
if (Apprefs.graphSystem != null)
{
System.Drawing.PointF mousePt = new System.Drawing.PointF(e.X, e.Y);
Apprefs.graphSystem.UCclicked(mousePt);
}
}
thats it!
I am trying to get my Kinect's SkeletonStream to feedback a data that tells me that nobody is detected. I can get feed if my skeleton is detected but I am unable to get any notification if there is nobody there. Is there a way to get the kinect to tell me if no skeletons are picked up?
private void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame frame = e.OpenSkeletonFrame())
{
if (frame == null)
{
return;
}
frame.GetSkeletons(ref allSkeletons);
if (allSkeletons.All(s => s.TrackingState == SkeletonTrackingState.NotTracked))
return;
foreach (var skeleton in allSkeletons)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
{
continue;
}
if (skeleton.TrackingState == SkeletonTrackingState.NotTracked)
{
}
foreach (Joint joint in skeleton.Joints)
{
if (joint.TrackingState != JointTrackingState.Tracked)
continue;
if (joint.JointType == JointType.HipCenter)
{
hipCenter = joint.Position;
AdvanceFunction();
}
}
sdm.Draw(frame.GetSkeletons(), false);
}
}
}
There is nothing that will simply tell you that no skeletons are currently being tracked. You will need to look through the skeleton frames to determine if there are any users.
Your foreach loop steps through all the skeletons...
foreach (var skeleton in allSkeletons)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
{
continue;
}
....
}
In the first if statement -- if the current skeleton is not being actively tracked then the loop will move on to the next skeleton. You'll want to add a flag if any skeletons have been found. For example, you could do something like...
bool hasActivePlayer = false;
foreach (var skeleton in allSkeletons)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
{
continue;
}
hasActivePlayer = true;
....
}
if (hasActivePlayer == false)
{
// you aren't tracking anyone, deal with it
}
You may also be interested in checking SkeletonTrackingState.PositionOnly. In this case the Kinect knows someone is there, but it is not actively tracking their skeleton. You can update the ckeck in the foreach loop if you want to look for it as well.
Hello, I get a NullReferenceException when running this:
void newSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
Skeleton first = GetFirstSkeleton(e);
if (first == null)
{
return;
}
/**
* #TODO
* obsluzyc wyjatek null reference na wypadek gdy gubi szkielet
*/
long timestamp = e.OpenSkeletonFrame().Timestamp;
it is in the line of long timestamp
It occurse while 10-15 seconds if same action. For example I'm logging some data standing still. I log them in every frame. After few seconds I get the NullReferenceException.
What is the problem?
Ok so I fouund answer for my problem. It is very simple.
Whe my system/machine is overloaded or it slows down from any other reason frames ain`t analyzed as fast as they sould. That whey when this lag occurs I can't open a frame. Thats why I get null.
Bellow solution of the problem
bool haveSkeletonData = false;
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
if ((this.skeletonData == null) || (this.skeletonData.Length != skeletonFrame.SkeletonArrayLength))
{
this.skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
}
skeletonFrame.CopySkeletonDataTo(skeletonData);
haveSkeletonData = true;
}
else
{
haveSkeletonData = false;
}
}
if (haveSkeletonData)
{
// here i can put code that is using my timestamp
}
That way I'll be safe from null and I'll be able to use my timestamp as I need to :)