Skip to content

Commit d991510

Browse files
committed
Add 8-bit or 10-bit image format options to UclaMiniscopeV4Data
- 8-bit data is much easier to save, especially in bonsai - 10-bit is available if people want it.
1 parent ace5451 commit d991510

File tree

1 file changed

+54
-5
lines changed

1 file changed

+54
-5
lines changed

OpenEphys.Onix1/UclaMiniscopeV4CameraData.cs

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)