forums.naturalpoint.com

Discussion and Support for the OptiTrack, SmartNav and TrackIR brands by NaturalPoint

C# SDK - questions about SetOption method

by bradwilkes » Wed Jul 22, 2009 9:24 am

I am a student using the Single Camera C# .NET 3.0 SDK to try and create a simple program used for tracking a single object (eye movements). One of my first goals is to reduce the number of objects that the camera creates while in infrared video mode, so that when I try to write object data as a .csv file (comma separated values, opens in excel), I'm not writing data about a bunch of objects that are really just the fringes of a single object.

In the beginning the CameraView class, several member variables are defined so that they may be used later in the code:
Code: Select all
        private const int NP_OPTION_OBJECT_COLOR_OPTION = 3;
        private const int NP_OPTION_VIDEO_TYPE = 48;
        private const int NP_OPTION_NUMERIC_DISPLAY_ON = 71;

Some of these variables are initialized into values that, as actual NPCamera options, they cannot hold. This is fine... because they will not actually be set to those values when the NPCamera interface calls the method to SetOption()

Most of these options are set during the StartCamera() method in the CameraView class, by referencing
Code: Select all
public OptiTrack.NPCamera Camera

I believe this to be a variable of type NPCamera (referenced through the OptiTrack() method).

So here is the code for the variable Camera:
Code: Select all
        public OptiTrack.NPCamera Camera
        {
            get { return mCamera; }
            set
            {
                if (mCamera == value) return; //== Don't do anything if you're assigning the same camera ==

                if (mCamera != null)
                {
                    //== Shut the selected camera down ==<<

                    if (CameraRunning)
                    {
                        CameraRunning = false;
                        mCamera.Stop();
                        mCamera.FrameAvailable -= FrameAvailable;
                    }
                }

                mCamera = value;

                if (mCamera == null)
                {
                    mNumeric = -1;
                }
                else
                {
                    serialLabel.Content = "Camera "+mCamera.SerialNumber.ToString(); //mNumeric.ToString();
                }



And here is the code for the StartCamera() method:
Code: Select all
public void StartCamera()
        {
            if (Camera != null)
           
            {
                mFrameCounter = 0;
                mDisplayCounter = 0;

            Camera.FrameAvailable += FrameAvailable;
            Camera.SetOption(NP_OPTION_VIDEO_TYPE, 2);
            Camera.SetOption(NP_OPTION_FRAME_DECIMATION,1);
            Camera.SetOption(NP_OPTION_INTENSITY, 0);
            Camera.SetOption(NP_OPTION_EXPOSURE, 10);
            Camera.SetOption(NP_OPTION_THRESHOLD, 50);
            Camera.SetOption(NP_OPTION_OBJECT_COLOR_OPTION, 0);
                 
            SetOverlayOption();
            SetGreyscaleOption();
               
            timer1.Start();
            Camera.Start();
               
            CameraRunning = true;
            this.Numeric = mNumeric;

            startStopButton.Content = "Stop Camera";
            }



Now, I want to edit the camera option NP_OPTION_OBJECT_CAP.
So in the very beginning of the CameraView class I create and define the variable to it's default value (500 max objects).
Code: Select all
private const int NP_OPTION_OBJECT_CAP = 500


Then I try to add this line into the StartCamera() method, right next to all the others.
Code: Select all
Camera.SetOption(NP_OPTION_OBJECT_CAP, 10);


When I do the above, I get an error that says:
XAMLParseException was unhandled

and the details of this error are:
Code: Select all
System.Windows.Markup.XamlParseException was unhandled
  Message="Cannot create instance of 'Window1' defined in assembly 'TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation.  Error in markup file 'Window1.xaml' Line 2 Position 2."
  Source="PresentationFramework"
  LineNumber=2
  LinePosition=2
  StackTrace:
       at System.Windows.Markup.XamlParseException.ThrowException(String message, Exception innerException, Int32 lineNumber, Int32 linePosition, Uri baseUri, XamlObjectIds currentXamlObjectIds, XamlObjectIds contextXamlObjectIds, Type objectType)
       at System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext, Int32 lineNumber, Int32 linePosition, String message, Exception innerException)
       at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException)
       at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
       at System.Windows.Markup.BamlRecordReader.GetElementAndFlags(BamlElementStartRecord bamlElementStartRecord, Object& element, ReaderFlags& flags, Type& delayCreatedType, Int16& delayCreatedTypeId)
       at System.Windows.Markup.BamlRecordReader.BaseReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
       at System.Windows.Markup.BamlRecordReader.ReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
       at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
       at System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
       at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
       at System.Windows.Markup.TreeBuilder.Parse()
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
       at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
       at System.Windows.Application.DoStartup()
       at System.Windows.Application.<.ctor>b__0(Object unused)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at TestProject.App.Main() in C:\Program Files\NaturalPoint\Optitrack\samples\Single_Camera_CSharp_.NET_3.0\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Reflection.TargetInvocationException
       Message="Exception has been thrown by the target of an invocation."
       Source="mscorlib"
       StackTrace:
            at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
            at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
            at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
            at System.Activator.CreateInstance(Type type, Boolean nonPublic)
            at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
       InnerException: System.ArgumentException
            Message="Value does not fall within the expected range."
            Source="Interop.OptiTrack"
            StackTrace:
                 at OptiTrack.NPCameraClass.SetOption(Int32 lOption, Object Val)
                 at TestProject.CameraView.StartCamera() in C:\Program Files\NaturalPoint\Optitrack\samples\Single_Camera_CSharp_.NET_3.0\CameraView.xaml.cs:line 192
                 at TestProject.Window1..ctor() in C:\Program Files\NaturalPoint\Optitrack\samples\Single_Camera_CSharp_.NET_3.0\Window1.xaml.cs:line 28
            InnerException:


I have also tried setting this option the same way as the SetOverlayOption() method is called during the StartCamera() method by creating a SetObjectCap() method, with internal code and created variables that are appropriately mirrored in the format of the SetOverlayOption() method.

Any help on how to actually set the NP_OPTION_OBJECT_CAP would be greatly appreciated as I cannot find any explicit info on how to do this in the OptiTrackAPI document that comes with the SDK.
bradwilkes
 
Posts: 2
Joined: Wed Jul 22, 2009 8:26 am

by Birch » Wed Jul 22, 2009 3:44 pm

SetOption() :

* The first parameter is a #define/const which selects the "option" to be be modified.

* The second parameter is the new value for the selected option.

The option value is not changed by re-assigning the value of NP_OPTION_OBJECT_CAP. It is changed by passing NP_OPTION_OBJECT_CAP to SetOption as the first parameter, and the desired value to SetOption as the second parameter.

NP_OPTION_OBJECT_CAP should always have the value specified in OptiTrack.h, which is :
NP_OPTION_OBJECT_CAP = NP_OPTION_GRAYSCALE_DECIMATION + 1

When you see the following :
public const int NP_OPTION_OBJECT_CAP = 78;

it is just another way of representing the above assignment, since :
public const int NP_OPTION_GRAYSCALE_DECIMATION = 77;


* Revert the following from
private const int NP_OPTION_OBJECT_CAP = 500
* To :
public const int NP_OPTION_GRAYSCALE_DECIMATION = 77;

* Then this line should begin to work :
Camera.SetOption(NP_OPTION_OBJECT_CAP, 10);



All of that aside, if too many objects are being detected where only a small number are desired then it usually means the exposure, lighting and threshold settings and physical tracking environment have not been optimized. We recommend tuning them as an optimal way to reduce the number of unwanted objects in combination with your other changes.
Birch
NaturalPoint Employee
NaturalPoint Employee
 
Posts: 1137
Joined: Thu Jan 30, 2003 5:00 am
Location: Corvallis, Oregon


Return to OptiTrack SDK