I have one simple application for Kinect but it seems it consumes a lot of resources. It works normally for a 1-2 minutes and then lag becomes unbearable.
This is my configuration:
Intel Core i3 CPU M330 2.13 GHz
4 GB RAM
ATI Radeon HD 4570
This is code for application window:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.WindowState = System.Windows.WindowState.Maximized;
}
private void StopKinect(KinectSensor sensor)
{
if (sensor != null)
{
if (sensor.IsRunning)
{
//stop sensor
sensor.Stop();
//stop audio if not null
if (sensor.AudioSource != null)
{
sensor.AudioSource.Stop();
}
}
}
}
private void Window_Closing_1(object sender, System.ComponentModel.CancelEventArgs e)
{
StopKinect(Generics.GlobalKinectSensorChooser.Kinect);
}
}
This is code for main menu (first screen):
public partial class MainMenu : Page
{
#region "Kinect"
private KinectSensorChooser sensorChooser;
#endregion
public MainMenu()
{
this.InitializeComponent();
if (Generics.GlobalKinectSensorChooser == null)
{
// initialize the sensor chooser and UI
this.sensorChooser = new KinectSensorChooser();
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
this.sensorChooser.Start();
Generics.GlobalKinectSensorChooser = this.sensorChooser;
}
else
{ // initialize the sensor chooser and UI
this.sensorChooser = new KinectSensorChooser();
this.sensorChooser = Generics.GlobalKinectSensorChooser;
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
this.sensorChooserUi.KinectSensorChooser = sensorChooser;
}
// Bind the sensor chooser's current sensor to the KinectRegion
var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);
}
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
bool error = false;
if (args.OldSensor != null)
{
try
{
args.OldSensor.DepthStream.Range = DepthRange.Default;
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
args.OldSensor.DepthStream.Disable();
args.OldSensor.SkeletonStream.Disable();
args.OldSensor.ColorStream.Disable();
}
catch (InvalidOperationException)
{
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
error = true;
}
}
if (args.NewSensor != null)
{
try
{
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
args.NewSensor.SkeletonStream.Enable();
}
catch (InvalidOperationException)
{
error = true;
}
}
if (!error)
kinectRegion.KinectSensor = args.NewSensor;
}
private void Screen1ButtonOnClick(object sender, RoutedEventArgs e)
{
this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
(Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("Depth.xaml", UriKind.Relative);
}
}
And this code for screen1:
public partial class Depth : Page
{
#region "Kinect"
private KinectSensorChooser sensorChooser;
#endregion
const float MaxDepthDistance = 4095; // max value returned
const float MinDepthDistance = 850; // min value returned
const float MaxDepthDistanceOffset = MaxDepthDistance - MinDepthDistance;
public Depth()
{
this.InitializeComponent();
// initialize the sensor chooser and UI
this.sensorChooser = new KinectSensorChooser();
//Assign the sensor chooser with the sensor chooser from the mainwindow.
//We are reusing the sensorchoosing declared in the first window that can in contact with kinect
this.sensorChooser = Generics.GlobalKinectSensorChooser;
//subscribe to the sensorChooserOnKinectChanged event
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
//Assign Kinect Sensorchooser to the sensorchooser we got from our static class
this.sensorChooserUi.KinectSensorChooser = sensorChooser;
// Bind the sensor chooser's current sensor to the KinectRegion
var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);
}
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
bool error = false;
if (args.OldSensor != null)
{
try
{
args.OldSensor.DepthStream.Range = DepthRange.Default;
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
args.OldSensor.DepthStream.Disable();
args.OldSensor.SkeletonStream.Disable();
args.OldSensor.ColorStream.Disable();
}
catch (InvalidOperationException)
{
error = true;
}
}
if (args.NewSensor != null)
{
try
{
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
args.NewSensor.SkeletonStream.Enable();
}
catch (InvalidOperationException)
{
error = true;
}
}
if (!error)
kinectRegion.KinectSensor = args.NewSensor;
}
private void MenuButtonOnClick(object sender, RoutedEventArgs e)
{
//Unsubscribe to the sensorchooser's event SensorChooseronkinectChanged
this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
(Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("MainScreen.xaml", UriKind.Relative);
}
}
There are a couple of more screens, I choosed this screen where I'm using KinectDepthViewer from WpfViewers. This screen has the worst lag, application is unusable almost instantly. Other screens where I have just buttons don't have a lag at the beginning but they get it after 2-3 minutes of usage.
I don't know am I doing something wrong in initialization maybe. I hope someone has some advice. I've read that people didn't have problems with development on even weaker configurations so I hope it's not because of that.
Thank you!
your graphics adapter suggests you're using a notebook computer. While there might be something in your code that could be improved, I really think the problem is your hardware. Notebooks with the specs you listed will have trouble running something as CPU intensive as what you're trying to do with the Kinect.
Related
I'm developing another sample where Messaging Center send status messages not coupled from device code to my view models.
At this point I used:
A alert message;
Label in my view;
A method by dependency injection from native code(interfaced and created before).
To notice the events before try in View models... etc
For it I used a static view instance in my share application constructor (App.xaml) where in view constructor I Subscript the status.
App (shared)
public partial class App : Application
{
public static ConnectViewModel CVM { get; set; }// Connection View Model
#region MasterDetailPage
public static MasterDetailPage MDP;
public static NavigationPage NAV = null;
public static MainView _mainpage;
#endregion
public App ()
{
InitializeComponent();
InitializeApplication();
NAV = new NavigationPage(new StarterView()) { BarBackgroundColor = Color.FromHex("701424"), BarTextColor = Color.White }; ;
MDP = new MasterDetailPage();
MDP.BackgroundColor = Xamarin.Forms.Color.FromHex("701424");
_mainpage = new MainView();
MDP.Master = _mainpage;
MDP.Detail = NAV;
MainPage = MDP;
MainPage.Title = "H2X";
}
private void InitializeApplication()
{
if (CVM == null)
{
CVM = new ConnectViewModel();
}
}
(View shared)
public MainView ()
{
InitializeComponent ();
string a="Test";
#region MessegeCenter
MessagingCenter.Subscribe<string,string>("APP", "Message_Received", async (sender,arg) =>
{
string b = a;
a = $"{arg}";
try
{
* await DisplayAlert(App.BM_Status, "Ok", "OK");*
}catch(Exception e)
{
string a = e.Message;
}
* generic_label_of_my_view = generic_label_of_my_view + "+";//It's not async one*
*string test = App.CVM.All_conn.Msg_Reciever();//Injection - It's not async one*
});
#endregion
}
Into the specific platform code (Device - UWP):
I create a timer that sends messages after some time instanced in mainpage constructor.
A HID device that notice me when some msg comes from USB.
The dispatcherTimer
void dispatcherTimer_Tick(object sender, object e)
{
DateTimeOffset time = DateTimeOffset.Now;
TimeSpan span = time - lastTime;
lastTime = time;
//Time since last tick should be very very close to Interval
TimerLog.Text += timesTicked + "\t time since last tick: " + span.ToString() + "\n";
timesTicked++;
if (timesTicked > timesToTick)
{
MessagingCenter.Send<string,string>("APP","Message_Received","MR");
}
}
The HIDInit and HID InputReport event
public async void HID_Init()
{
var selector = HidDevice.GetDeviceSelector(a_Id, b_Id, c_ID, d_ID);
var devices = await DeviceInformation.FindAllAsync(selector);
if (devices.Any())
{
// At this point the device is available to communicate with
// So we can send/receive HID reports from it generically
console_text = "HID devices found: " + devices.Count;
device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id, FileAccessMode.ReadWrite);
if (device != null)
{
// At this point the device is available to communicate with
// create my input caller/event
device.InputReportReceived += inputReportReceived;//invoke caller
deviceWatcher = DeviceInformation.CreateWatcher(selector);
deviceWatcher.Removed += deviceRemovedEventHandler;//checa se nada foi removido
deviceWatcher.Start();
}
else
{
// There were no HID devices that met the selector criteria
throw new Exception("MUTT HID device not found");
}
}
else
{
// There were no HID devices that met the selector criteria
console_text = "HID device not found";
}
}
private void inputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
{
var bbytes = new byte[10];
wait_streaming = true;
DataReader dataReader = DataReader.FromBuffer(args.Report.Data);
dataReader.ReadBytes(bbytes);
console_text += System.Text.Encoding.ASCII.GetString(bbytes, 2, bbytes[1]);
is_read = false;
wait_streaming = false;
MessagingCenter.Send<string,string>("App","Message_Received","MR");
}
When I run any case with Dispatchertimer "works".
When I run by the Hidinputreport event with the alertmessage creates a system.exception in alertmessege line.
This is the "System.Exception"
if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
endif
When I run by the Hidinputreport event with the Label a marshalled interface crash with other thread in my call from messegingCenter in native code.
System.Exception: 'The application call a marshalled interface for another thread.
(Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))'
When I run the injection, works but I'm afraid that this Thread troubles make some semantical bug in my project cause I need to call INofifyPropertyChanged in shared code to print in my view the message but ...
Can I call it into the sender into Messeging Center Subscripte ?
How can I correct the other troubles with Threads ? Manual Reset Events ? EventWaitHandle ? (Inheritance:Object->MarshalByRefObject->WaitHandle->EventWaitHandle) ... so invasive way :/
I'm sorry if I ask some stupid question or show stupit code here ... but I don't know how to organize it WELL
Thank you in advance
Guilherme
I'm trying to plot the data read from a serial port using zedgraph. I'm still learing to code so I couldn't deduce why the plot does not work. Please have a look at the code and advice;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
string t;
SerialPort sp;
Thread m_thread;
bool m_running = false;
ManualResetEvent m_event = new ManualResetEvent(true);
bool m_pause = false;
private GraphPane myPane;
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
// User can already search for ports when the constructor of the FORM1 is calling
// And let the user search ports again with a click
// Searching for ports function
SearchPorts();
CreateZedGraph(); //error : Severity Code Description Project File Line Suppression State
//Error CS7036 There is no argument given that corresponds to the required formal parameter
//'w' of 'Form1.DrawPoint(ZedGraphControl, int, PointPair)'
}
// start button
private void btnStart_Click(object sender, EventArgs e)
{
if (m_thread == null || m_thread.IsAlive == false)
{
ClearGraph();
m_thread = new Thread(Process);
m_thread.Start();
}
}
void Process()
{
PointPair point = new PointPair();
btnStart.Enabled = false;
btnStop.Enabled = true;
m_running = true;
while (m_running == true)
{
m_event.WaitOne();
point.Y = Convert.ToDouble(serialPort1);
point.X++; //time instance of measurement??
DrawPoint(zed1, point);
ssData.Value = point.Y.ToString();
RefresheZedGraphs(zed1);
Thread.Sleep(700);
}
btnStart.Enabled = true;
}
private void CreateZedGraph(object sender, SerialDataReceivedEventArgs e, ZedGraphControl zgc)
{
myPane = zgc.GraphPane;
// axes stuff
myPane.Title.Text = "FRDM-KW40z serial Test";
myPane.XAxis.Title.Text = "Time";
myPane.YAxis.Title.Text = "Voltage";
myPane.XAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.XAxis.MinorGrid.IsVisible = true;
myPane.YAxis.MinorGrid.IsVisible = true;
// data from serial port
PointPairList list = new PointPairList();
zed1.GraphPane.AddCurve("Test", list, Color.Red);
}
To open and read from a serial port, I use a combox and a couple of buttons (and then later I try to save it to a text file);
private void button2_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
SearchPorts();
}
void SearchPorts()
{
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
comboBox1.Items.Add(port);
}
}
private void button3_Click(object sender, EventArgs e)
{
// Catch exception if it will be thrown so the user will see it in a message box
OpenCloseSerial();
}
void OpenCloseSerial()
{
try
{
if (sp == null || sp.IsOpen == false)
{
t = comboBox1.Text.ToString();
sErial(t);
button3.Text = "Close Serial port"; // button text
}
else
{
sp.Close();
button3.Text = "Connect and wait for inputs"; // button text
}
}
catch (Exception err) // catching error message
{
MessageBox.Show(err.Message); // displaying error message
}
}
void sErial(string Port_name)
{
try
{
sp = new SerialPort(Port_name, 115200, Parity.None, 8, StopBits.One); // serial port parameters
sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
sp.Open();
}
catch (Exception err)
{
throw (new SystemException(err.Message));
}
}
private void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{
// This below line is not need , sp is global (belongs to the class!!)
//SerialPort sp = (SerialPort)sender;
if (e.EventType == SerialData.Chars)
{
if (sp.IsOpen)
{
string w = sp.ReadExisting();
if (w != String.Empty)
{
Invoke(new Action(() => Control.Update(w)));
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (sp == null || sp.IsOpen == false)
{
OpenCloseSerial();
}
}
The plot does not update! I can't quite guess why. Please tell me if there's mistakes in my approach or the code.
I get an error at : Invoke(new Action(() => Control.Update(w))); when trying to update the graph so that I can save after that.
I again have an error at: DrawPoint(zed1, point);
Thank you all for your time. Good day.
Cheers,
Ram.
To update the chart, you need to call the Invalidate method.
When you receive data from serial port, you need to convert it to double[] and add those points to your PointPairList.
PointPairList list = new PointPairList();
zed1.GraphPane.AddCurve("Test", list, Color.Red);
//Convert the received data to double array
double[] serialPortData = ....
//You may want to clear list first, by list.Clear();
list.Add(serialPortData);
//Invalidate the ZedGraphControl to update
zed1.Invalidate();
I am facing trouble in calling events in Zkemkeeper.dll. I have succesfully established the connection however on putting the finger on sensor no event is fired. Infact no realtime event is being triggered.
Any help would be appreciated following is my code;
private void button2_Click(object sender, EventArgs e)
{
string s = "";
int Val = 0;
bool bIsConnected = false;
try {
//zkemkeeper.CZKEMClass axczkem1 = new zkemkeeper.CZKEMClass();
// bIsConnected = axczkem1.Connect_USB(1);
bIsConnected = axczkem1.Connect_Com(6,1,115200);
if(bIsConnected==true){
Cursor = Cursors.Default;
bool asa= axczkem1.EnableDevice(1, true);
if (axczkem1.RegEvent(1, 65535))
{
axczkem1.OnFinger += new zkemkeeper._IZKEMEvents_OnFingerEventHandler(axczkem1_OnFinger);
axczkem1.OnKeyPress += new zkemkeeper._IZKEMEvents_OnKeyPressEventHandler(axczkem1_OnKeyPress);
axczkem1.OnConnected += new _IZKEMEvents_OnConnectedEventHandler(axCZKEM1_OnConnected);
axczkem1.OnVerify += new zkemkeeper._IZKEMEvents_OnVerifyEventHandler(axCZKEM1_OnVerify);
}
MessageBox.Show("Connection established!!!");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
And following are the event methods:
private void axCZKEM1_OnVerify(int UserID)
{
label2.Text = "Verify";
}
private void axCZKEM1_OnConnected()
{
label1.Text = "Connected";
}
private void axczkem1_OnKeyPress(int Key)
{
MessageBox.Show(Key.ToString());
}
private void axczkem1_OnFinger()
{
MessageBox.Show("Connection");
}
if this is a windows form application . If program have long running process event doesn't work . For example loop (while,for) . And also Thread.sleep() .
If you want to trigger work your program do nothing .
If this is not a windows form see this link enter link description here
Please someone can access to a ip camera with emgucv in c# visual studio in other post share the code
capture = new Emgu.CV.CvInvoke.cvCreateFileCapture("Url ip camera");
when i run the code say"the tipe cvCreateFileCapture does not exist in CvInvoke"
someone know other form to access an ip camera with emgucv but working...thanks!
this is my exmaple, it works with me, I a using EmguCV V3
public partial class Form1 : Form
{
private Capture _capture = null;
private bool _captureInProgress;
public Form1()
{
InitializeComponent();
CvInvoke.UseOpenCL = false;
try
{
_capture = new Capture("http://webcam.st-malo.com/axis-cgi/mjpg/video.cgi?");//
_capture.ImageGrabbed += ProcessFrame;
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
private void ProcessFrame(object sender, EventArgs arg)
{
Mat frame = new Mat();
_capture.Retrieve(frame, 0);
captureImageBox.Image = frame;
}
private void captureButton_Click(object sender, EventArgs e)
{
if (_capture != null)
{
if (_captureInProgress)
{ //stop the capture
captureButton.Text = "Start Capture";
_capture.Pause();
}
else
{
//start the capture
captureButton.Text = "Stop";
_capture.Start();
}
_captureInProgress = !_captureInProgress;
}
}
}
I want to make an ap that turn on the flash when i press the On button, and turn off when I press the Off Button. This is my code :
protected AudioVideoCaptureDevice Device { get; set; }
private async void Button_Click_TurnOn(object sender, RoutedEventArgs e)
{
var sensorLocation = CameraSensorLocation.Back;
try
{
// get the AudioViceoCaptureDevice
var avDevice = await AudioVideoCaptureDevice.OpenAsync(sensorLocation,
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(sensorLocation).First());
// turn flashlight on
var supportedCameraModes = AudioVideoCaptureDevice
.GetSupportedPropertyValues(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchMode);
if (supportedCameraModes.ToList().Contains((UInt32)VideoTorchMode.On))
{
avDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.On);
// set flash power to maxinum
avDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchPower,
AudioVideoCaptureDevice.GetSupportedPropertyRange(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchPower).Max);
}
else
{
//ShowWhiteScreenInsteadOfCameraTorch();
}
}
catch (Exception ex)
{
// Flashlight isn't supported on this device, instead show a White Screen as the flash light
// ShowWhiteScreenInsteadOfCameraTorch();
}
}
private void Button_Click_TurnOff(object sender, RoutedEventArgs e)
{
var sensorLocation = CameraSensorLocation.Back;
try
{
// turn flashlight on
var supportedCameraModes = AudioVideoCaptureDevice
.GetSupportedPropertyValues(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchMode);
if (this.Device != null && supportedCameraModes.ToList().Contains((UInt32)VideoTorchMode.Off))
{
this.Device.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.Off);
}
else
{
//turnWhiteScreen(false);
}
}
catch (Exception ex)
{
// Flashlight isn't supported on this device, instead show a White Screen as the flash light
//turnWhiteScreen(false);
}
}
I copied it from another question at stackoverflow, but I dont know why this code doesnt work for me. Tested on Lumia 820.
Please help me, thank you very much :)
async private void FlashlightOn_Click(object sender, RoutedEventArgs e)
{
// turn flashlight on
CameraSensorLocation location = CameraSensorLocation.Back;
if (this.audioCaptureDevice == null)
{
audioCaptureDevice = await AudioVideoCaptureDevice.OpenAsync(location,
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(location).First());
}
FlashOn(location, VideoTorchMode.On);
}
private void FlashlightOff_Click(object sender, RoutedEventAgrs e)
{
// turn flashlight off
var sensorLocation = CameraSensorLocation.Back;
FlashOn(sensorLocation, VideoTorchMode.Off);
}
public bool FlashOn(CameraSensorLocation location, VideoTorchMode mode)
{
// turn flashlight on/off
var supportedCameraModes = AudioVideoCaptureDevice
.GetSupportedPropertyValues(location, KnownCameraAudioVideoProperties.VideoTorchMode);
if ((audioCaptureDevice != null) && (supportedCameraModes.ToList().Contains((UInt32)mode)))
{
audioCaptureDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, mode);
return true;
}
return false;
}