Last active
December 16, 2020 07:50
-
-
Save luispedro/3437255 to your computer and use it in GitHub Desktop.
Read ImageJ's ROI files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# UPDATE IN 2020 | |
# You almost always will want to use the version at | |
# https://github.com/luispedro/imread, which is | |
# up-to-date and works with Python 3 | |
# Copyright: Luis Pedro Coelho <luis@luispedro.org>, 2012 | |
# License: MIT | |
import numpy as np | |
def read_roi(fileobj): | |
''' | |
points = read_roi(fileobj) | |
Read ImageJ's ROI format | |
''' | |
# This is based on: | |
# http://rsbweb.nih.gov/ij/developer/source/ij/io/RoiDecoder.java.html | |
# http://rsbweb.nih.gov/ij/developer/source/ij/io/RoiEncoder.java.html | |
SPLINE_FIT = 1 | |
DOUBLE_HEADED = 2 | |
OUTLINE = 4 | |
OVERLAY_LABELS = 8 | |
OVERLAY_NAMES = 16 | |
OVERLAY_BACKGROUNDS = 32 | |
OVERLAY_BOLD = 64 | |
SUB_PIXEL_RESOLUTION = 128 | |
DRAW_OFFSET = 256 | |
pos = [4] | |
def get8(): | |
pos[0] += 1 | |
s = fileobj.read(1) | |
if not s: | |
raise IOError('readroi: Unexpected EOF') | |
return ord(s) | |
def get16(): | |
b0 = get8() | |
b1 = get8() | |
return (b0 << 8) | b1 | |
def get32(): | |
s0 = get16() | |
s1 = get16() | |
return (s0 << 16) | s1 | |
def getfloat(): | |
v = np.int32(get32()) | |
return v.view(np.float32) | |
magic = fileobj.read(4) | |
if magic != 'Iout': | |
raise IOError('Magic number not found') | |
version = get16() | |
# It seems that the roi type field occupies 2 Bytes, but only one is used | |
roi_type = get8() | |
# Discard second Byte: | |
get8() | |
if not (0 <= roi_type < 11): | |
raise ValueError('roireader: ROI type %s not supported' % roi_type) | |
if roi_type != 7: | |
raise ValueError('roireader: ROI type %s not supported (!= 7)' % roi_type) | |
top = get16() | |
left = get16() | |
bottom = get16() | |
right = get16() | |
n_coordinates = get16() | |
x1 = getfloat() | |
y1 = getfloat() | |
x2 = getfloat() | |
y2 = getfloat() | |
stroke_width = get16() | |
shape_roi_size = get32() | |
stroke_color = get32() | |
fill_color = get32() | |
subtype = get16() | |
if subtype != 0: | |
raise ValueError('roireader: ROI subtype %s not supported (!= 0)' % subtype) | |
options = get16() | |
arrow_style = get8() | |
arrow_head_size = get8() | |
rect_arc_size = get16() | |
position = get32() | |
header2offset = get32() | |
if options & SUB_PIXEL_RESOLUTION: | |
getc = getfloat | |
points = np.empty((n_coordinates, 2), dtype=np.float32) | |
else: | |
getc = get16 | |
points = np.empty((n_coordinates, 2), dtype=np.int16) | |
points[:,1] = [getc() for i in xrange(n_coordinates)] | |
points[:,0] = [getc() for i in xrange(n_coordinates)] | |
points[:,1] += left | |
points[:,0] += top | |
points -= 1 | |
return points | |
def read_roi_zip(fname): | |
import zipfile | |
with zipfile.ZipFile(fname) as zf: | |
return [read_roi(zf.open(n)) | |
for n in zf.namelist()] |
The above code does not work in python 3.6.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have the same question. Any one knows how to write ROI? I want to generate some region and go back to image J to edit. Thanks!