Skip to main content

Image data formats

List of supported image formats.

  • RAW (BV workbench default)
  • TIFF (standard)
  • GSD/GSH (backward compatibility)
  • RSD (backward compatibility)
tip

Use RAW when possible for best read/write speed.

RAW Version 4 (latest)

File header layout

OffsetField nameTypeSize
0VERSIONInt324
4IMAGE_DATA_OFFSETInt324
8FRAME_COUNTInt324
12SAMPLING_TIMEFloat648
20WIDTHInt324
24HEIGHTInt324
28BIT_DEPTHInt324
32PIXEL_SIZE_XFloat648
40PIXEL_SIZE_YFloat648
48ROI_COUNTInt324
52ROIRectROI_COUNT * 16
...--
IMAGE_DATA_OFFSETBACKGROUNDUInt16WIDTH * HEIGHT * 2
IMAGE_DATA_OFFSET + WIDTH * HEIGHT * 2REF_FRAMEUInt16WIDTH * HEIGHT * 2
IMAGE_DATA_OFFSET + WIDTH * HEIGHT * 4MASKUInt8WIDTH * HEIGHT
IMAGE_DATA_OFFSET + WIDTH * HEIGHT * 4ROI_PIXELSUInt16varies
struct Rect {
int x;
int y;
int width,
int height,
};

Python script to read version 4 files.

import numpy as np
import matplotlib.pyplot as plt

class Rect:
def __init__(self, x : int, y: int, w: int, h: int):
self.x = x
self.y = y
self.w = w
self.h = h
def __str__(self):
return f"X : {x}, Y : {y}, W : {w}, H : {h}"

# open file
f = open("test_v4.raw",'rb')

try:
version = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Version : {version}")

image_data_offset = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Image data offset : {image_data_offset}")

frame_count = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Frame count : {frame_count}")

sampling_time = np.fromfile(f, dtype=np.float64, count=1)[0]
print(f"Sampling rate : {sampling_time/1000} ms ({1/sampling_time} FPS)")

# read image dimensions
width = np.fromfile(f, dtype=np.uint32, count=1)[0]
height = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Image size : {width} x {height}")

bit_depth = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Bit depth : {bit_depth}")

dx = np.fromfile(f, dtype=np.float64, count=1)[0]
dy = np.fromfile(f, dtype=np.float64, count=1)[0]
print(f"Image scale : {dx} x {dy} mm^2/px^2")

# read image region definitions
roi_count = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"ROI count : {roi_count}")

regions = []
for i in range(roi_count):
temp = np.fromfile(f, dtype=np.uint32, count=4)
x = temp[0]
y = temp[1]
w = temp[2]
h = temp[3]
regions.append(Rect(x, y, w, h))

print("Regions : ")
for r in regions:
print(r)

# read background
f.seek(image_data_offset)
background = np.fromfile(f, dtype=np.uint16, count=width*height)
background = background.reshape(height,width)
#plt.figure(0)
#plt.title("background image")
#plt.imshow(background)

# read ref frame
refFrame = np.fromfile(f, dtype=np.uint16, count=width*height)
refFrame = refFrame.reshape(height, width)
#plt.figure(1)
#plt.title("reference image (F0)")
#plt.imshow(refFrame)

# read mask
maskImg = np.fromfile(f, dtype=np.uint8, count=width*height)
maskImg = maskImg.reshape(height,width)
#plt.figure(2)
#plt.title("mask")
#plt.imshow(maskImg)

# read first frame
region0_size = regions[0].w * regions[0].h
frame0_region0 = np.fromfile(f, dtype=np.uint16, count=region0_size)
frame0_region0 = frame0_region0.reshape(regions[0].h, regions[0].w)
plt.figure(3)
plt.title("image 0 region 0")
plt.imshow(frame0_region0)

plt.show()

# If images contain multiple regions, data is ordered as
# frame0_region0,
# frame0_region1,
# ...
# frame0_regionN,
# frame1_region0,
# frame1_region1,
# ...
# frame1_regionN,
# frameN_region0,
# ...

finally:
f.close()

RAW Version 3 (BV Workbench 2)

Python script to read version 3 and earlier files, which had embedded XML.

import numpy as np
import lxml.etree
import matplotlib.pyplot as plt

class Rect:
def __init__(self, x : int, y: int, w: int, h: int):
self.x = x
self.y = y
self.w = w
self.h = h
def __str__(self):
return f"X : {x}, Y : {y}, W : {w}, H : {h}"

f = open("test_v3.raw",'rb')

try:
version = np.fromfile(f, dtype=np.uint32, count=1)[0]
print(f"Version : {version}")

# read metadata size and offset
metadataSize = np.fromfile(f, dtype=np.uint32, count=1)[0]
metadataOffset = 12
if version >= 3:
f.seek(8)
roiDataSize = np.fromfile(f, dtype=np.uint32, count=1)[0]
print ("ROI data size : " + str(roiDataSize))
metadataOffset = 16

#read XML and create element tree
f.seek(metadataOffset)
xmlStr = f.read(metadataSize).decode("utf-8")
root = lxml.etree.fromstring(xmlStr)

# read image dimensions
width = int(root.find('Image/Width').text)
height = int(root.find('Image/Height').text)
print(f"Image size : {width} x {height}")

# read image region definitions
regions = []
for child in root.find('Image/Regions'):
x = int(child.find('X').text)
y = int(child.find('Y').text)
w = int(child.find('Width').text)
h = int(child.find('Height').text)
regions.append(Rect(x, y, w, h))

print("Regions : ")
for r in regions:
print(r)

bit_depth = int(root.find('Image/BitDepth').text)
frame_count = int(root.find('Acquisition/NumberOfFrames').text)
print(f"Bit depth : {bit_depth}")
print(f"Frame count : {frame_count}")

if version <= 2:
f.seek(8)
elif version >= 3:
f.seek(12)

# read image data offset
imgOffset = np.fromfile(f, dtype=np.uint32, count=1)[0]

# read background image to numpy array
f.seek(imgOffset)
background = np.fromfile(f, dtype=np.uint16, count=width*height)
background = background.reshape(height,width)
#plt.figure(0)
#plt.title("background image")
#plt.imshow(background)

if (version >= 2):
# read the reference (F0) frame
refImg = np.fromfile(f, dtype=np.uint16, count=width*height)
refImg = refImg.reshape(height,width)
#plt.figure(1)
#plt.title("reference image")
#plt.imshow(refImg)

# read the binary mask
mask = np.fromfile(f, dtype=np.uint8, count=width*height)
mask = mask.reshape(height,width)
#plt.figure(2)
#plt.title("mask")
#plt.imshow(mask)


region0_size = regions[0].w * regions[0].h
frame0_region0 = np.fromfile(f, dtype=np.uint16, count=region0_size)
frame0_region0 = frame0_region0.reshape(regions[0].h, regions[0].w)
plt.figure(3)
plt.title("image 0 region 0")
plt.imshow(frame0_region0)

plt.show()

# If images contain multiple regions, data is ordered as
# frame0_region0,
# frame0_region1,
# ...
# frame0_regionN,
# frame1_region0,
# frame1_region1,
# ...
# frame1_regionN,
# frameN_region0,
# ...

finally:
f.close()

TIFF

Images can be stored to/read from multi-page TIFF (revision 6.0) files.
When larger than 4GB, the BigTIFF format is used.

GSD

For backward compatibility with BV Analyzer.

  • Images are stored as 14-bit diff values.
  • Analog signals are appended to the end.
    • Only when they are sampled at 20 times the rate of images

RSD (read only)

Coming soon.