@@ -21,6 +21,21 @@ public class UclaMiniscopeV4CameraData : Source<UclaMiniscopeV4CameraFrame>
2121 [ Category ( DeviceFactory . ConfigurationCategory ) ]
2222 public string DeviceName { get ; set ; }
2323
24+ /// <summary>
25+ /// Gets or sets the data type used to represent pixel intensity values.
26+ /// </summary>
27+ /// <remarks>
28+ /// The UCLA Miniscope V4 uses a 10-bit image sensor. To capture images that use the full
29+ /// ADC resolution, this value can be set to <see cref="UclaMiniscopeV4ImageDepth.U10"/>.
30+ /// This comes at the cost of limited codec support and larger file sizes. If <see
31+ /// cref="UclaMiniscopeV4ImageDepth.U8"/> is selected, the two least significant bits of
32+ /// each pixel sample will be discarded, which greatly increases codec options and reduces
33+ /// file sizes.
34+ /// </remarks>
35+ [ Description ( "The bit-depth used to represent pixel intensity values." ) ]
36+ [ Category ( DeviceFactory . ConfigurationCategory ) ]
37+ public UclaMiniscopeV4ImageDepth DataType { get ; set ; } = UclaMiniscopeV4ImageDepth . U8 ;
38+
2439 /// <summary>
2540 /// Generates a sequence of <see cref="UclaMiniscopeV4CameraFrame"/>s at a rate determined by <see
2641 /// cref="ConfigureUclaMiniscopeV4Camera.FrameRate"/>.
@@ -33,13 +48,15 @@ public unsafe override IObservable<UclaMiniscopeV4CameraFrame> Generate()
3348 var device = deviceInfo . GetDeviceContext ( typeof ( UclaMiniscopeV4 ) ) ;
3449 var passthrough = device . GetPassthroughDeviceContext ( typeof ( DS90UB9x ) ) ;
3550 var scopeData = device . Context . GetDeviceFrames ( passthrough . Address ) ;
36-
51+ var dataType = DataType ;
52+
3753 return Observable . Create < UclaMiniscopeV4CameraFrame > ( observer =>
3854 {
3955 var sampleIndex = 0 ;
4056 var imageBuffer = new short [ UclaMiniscopeV4 . SensorRows * UclaMiniscopeV4 . SensorColumns ] ;
4157 var hubClockBuffer = new ulong [ UclaMiniscopeV4 . SensorRows ] ;
4258 var clockBuffer = new ulong [ UclaMiniscopeV4 . SensorRows ] ;
59+ var sampleRect = new Rect ( 0 , 1 , UclaMiniscopeV4 . SensorColumns , UclaMiniscopeV4 . SensorRows - 1 ) ;
4360
4461 var frameObserver = Observer . Create < oni . Frame > (
4562 frame =>
@@ -48,16 +65,33 @@ public unsafe override IObservable<UclaMiniscopeV4CameraFrame> Generate()
4865
4966 // Wait for first row
5067 if ( sampleIndex == 0 && ( payload ->ImageRow [ 0 ] & 0x8000 ) == 0 )
51- return ;
68+ return ;
5269
5370 Marshal . Copy ( new IntPtr ( payload ->ImageRow ) , imageBuffer , sampleIndex * UclaMiniscopeV4 . SensorColumns , UclaMiniscopeV4 . SensorColumns ) ;
5471 hubClockBuffer [ sampleIndex ] = payload ->HubClock ;
5572 clockBuffer [ sampleIndex ] = frame . Clock ;
5673 if ( ++ sampleIndex >= UclaMiniscopeV4 . SensorRows )
5774 {
58- var imageData = Mat . FromArray ( imageBuffer , UclaMiniscopeV4 . SensorRows , UclaMiniscopeV4 . SensorColumns , Depth . U16 , 1 ) ;
59- CV . ConvertScale ( imageData . GetRow ( 0 ) , imageData . GetRow ( 0 ) , 1.0f , - 32768.0f ) ; // Get rid first row's mark bit
60- observer . OnNext ( new UclaMiniscopeV4CameraFrame ( clockBuffer , hubClockBuffer , imageData . GetImage ( ) ) ) ;
75+
76+ var imageData = Mat . FromArray ( imageBuffer , UclaMiniscopeV4 . SensorRows , UclaMiniscopeV4 . SensorColumns , Depth . U16 , 1 ) ;
77+ CV . ConvertScale ( imageData . GetRow ( 0 ) , imageData . GetRow ( 0 ) , 1.0f , - 32768f ) ; // Get rid first row's mark bit
78+
79+ switch ( dataType )
80+ {
81+ case UclaMiniscopeV4ImageDepth . U8 :
82+ {
83+ var eightBitImageData = new Mat ( imageData . Size , Depth . U8 , 1 ) ;
84+ CV . ConvertScale ( imageData , eightBitImageData , 0.25 ) ;
85+ observer . OnNext ( new UclaMiniscopeV4CameraFrame ( clockBuffer , hubClockBuffer , eightBitImageData . GetImage ( ) ) ) ;
86+ break ;
87+ }
88+ case UclaMiniscopeV4ImageDepth . U10 :
89+ {
90+ observer . OnNext ( new UclaMiniscopeV4CameraFrame ( clockBuffer , hubClockBuffer , imageData . GetImage ( ) ) ) ;
91+ break ;
92+ }
93+ }
94+
6195 hubClockBuffer = new ulong [ UclaMiniscopeV4 . SensorRows ] ;
6296 clockBuffer = new ulong [ UclaMiniscopeV4 . SensorRows ] ;
6397 sampleIndex = 0 ;
@@ -70,5 +104,20 @@ public unsafe override IObservable<UclaMiniscopeV4CameraFrame> Generate()
70104 } ) ;
71105 } ) ;
72106 }
107+
108+ /// <summary>
109+ /// Specifies the bit-depth used to represent pixel intensity values.
110+ /// </summary>
111+ public enum UclaMiniscopeV4ImageDepth
112+ {
113+ /// <summary>
114+ /// 8-bit pixel values encoded as bytes.
115+ /// </summary>
116+ U8 ,
117+ /// <summary>
118+ /// 10-bit pixel values encoded as unsigned 16-bit integers
119+ /// </summary>
120+ U10
121+ }
73122 }
74123}
0 commit comments