Matlab function to import ROIs from ImageJ.
Dylan Muir (2020). ReadImageJROI (https://github.com/DylanMuir/ReadImageJROI), GitHub. Retrieved .
Worked nicely with zip files of ROIs generated using an ImageJ plugin StarDist. Thank you!
Big thanks it helped a lot!
Hi Dapeng, unfortunately I have no idea what a nitfi file is, so I can't help much! Try stepping through your program in the debugger, with a small set of test ROIs (one that works and one that doesn't). See if you can spot when things go wrong.
Thanks for the tool!
I tried it. It works great most of the time. But somehow for some of my nitfi file (.nii), the ROI have x and y inversed in matlab, others don't. I guess it's related to the patient position, but any idea how to fix it?
@Vladimir I've added this function to the repository. Sorry for the inconvenience!
I'm using R2015a and I got Undefined function or variable 'ellipse2mask'. I neither found this function in Matlab nor fileexchange.
I suggest using a morphological operation such as `erode` to shrink down the ROI. If you convert the ROI to a binary image, you should be able to modify it.
Thanks a lot for the code.
I am using it to export some freehand ROIs (drawn with Image J) to matlab to get the specific coordinates of the voxels that remain INSIDE the ROI, but at least in my case what I seem to obtain with the ".mnCoordinates" includes the coordniates that "touch" the ROI from the external boundary plus the ones that remain inside. Do you have any idea of how could I modify that? Thanks again!!
Thank you very much for your code
Thank you so much for your code sir,
could anyone please upload an example using this code, it would be really appreciated
I have just updated the repository with a function that converts ROIs into Matlab regions structures (like that returned from `bwconncomp`. You can then convert these into masks using `labelmatrix` or similar.
Thank you for this code! I have a question though: I have a freehand ROI in ImageJ that I exported into MATLAB using this code. As far as I understand, this is interpreted as a rectangle ROI and the coordinates are given in the vfShapes field. Could you please point me to a document or some other resource which I can use to decode this field?
My aim is to use the coordinate information to create a mask and use this mask for further processing.
Thank you for your work! I have been struggling with freehand ROIs with more than one selection. I found out that the vfShapes vector is specified like this:
• 0 = new shape begins (following starting coordinates)
• 1 = next coordinates of the current shape follow
• 4 = shape ends
With this information it was easy to get all points and plot the freehand shapes of the ROI.
Short answer — yes. Long answer — you will have to trawl through the ImageJ java classes to work out how to write the correct format. This code might help you, since it shows partially where the bits go in the file. But the only "documentation" is the ImageJ source code.
Would it be possible to do the opposite? Generate an ImageJ roi file coordinates/polygons in Matlab?
Works great! Thanks so much!
Awesome! I was looking for a way to find de slice in my point annotations but you just have added it.
This is great, thanks a ton!
It works well.
% Convert ImageJ ROI to a mask.
% 256 is image size.
mask = poly2mask(sROI.mnCoordinates(:,1),sROI.mnCoordinates(:,2), 256, 256);
For freehand ROIs with more than one selection, the ROI shape (strType) is set to "Rectangle" and the ROI subtype (strSubtype) is set to "Shape". Then all the shape coordinates are returned in a vector "vfShapes".
I hope that helps.
Excellent work Dylan. Thanks.
I wrote a code to generate to masks based on freehand ROIs I have. The first problem I encountered was that the masks were larger than the corresponding ones created with the fill tool in ImageJ; extra pixels were on the top and left of the region. I partially solved this by finding and removing these pixels, but when the ROI has very thin internal bulges the extra pixels remain. I am new to MATLAB and my code is simple, but maybe there is proper way to do it.
The second problem is that when the ROI consists of more than 1 selections/areas then the function recognises it as a rectangle instead of freehand, and thus coordinates are missing. I can't solve this!
Information from the "Header 2" field is now read in by ReadImageJROI, in the latest update.
Now you have also channel, slice and frame field in your structure.
Adding it form line 227
if hdr2Offset>0 && ~fseek(fidROI, hdr2Offset+image_size+4, 'bof')
fseek(fidROI, hdr2Offset+c_position, 'bof');
sROI.channel=fread(fidROI, 1, 'uint32');
sROI.slice=fread(fidROI, 1, 'uint32');
sROI.frame=fread(fidROI, 1, 'uint32');
This is great, thanks for making it! I just started using it so haven't put it through its paces. So far so good!
Hi Yousef and Samuel,
Sorry that I missed your comments. I've just uploaded a new version that correctly reads the position field, and returns it for each ROI. Please check and see if it works for you.
Position should be at byte 56 (http://imagej.nih.gov/ij/source/ij/io/RoiDecoder.java), but my function was incorrectly reading it as a 16-bit int instead of a 32-bit int.
Thanks for your feedback,
I would like to follow up on the comment by Samuel - the value of nPosition is important, but fseek(fidROI, 58, 'bof'); doesn't seem correct - any suggestions. thanks Yousef
There appears to be a small bug in reading part of the header. nPosition is read from bytes 57-58 when it should be read from 58-59. Since I don't know what is missing upstream an easy fix is to add the code:
% - Seek to get nPosition (slice)
fseek(fidROI, 58, 'bof');
nPosition = fread(fidROI, 1, 'int16');
This value is not returned but I would suggest returning it as it gives the slice number which is quite important. As far as I can tell it appears to be present in either version >223 or >224 (223 doesn't have it and 225 does).
I think you may have an older version of the function. The current version on this page imports the ROIs with the correct location.
Thanks for your feedback,
Hi! I've used this script to import some free-hand drawn ROIs into MATLAB, but couldn't get them to match the image they where originally drawn on in imageJ.
It seems that there is a small bug in line 363 and 364, which should read:
vnX = vnX + sROI.vnRectBounds(2);
vnY = vnY + sROI.vnRectBounds(1);
The convention of top and left bounds are opposite of MATLABs.
Thanks for a great script - excellent work!
Nevermind! Figured out the problem. I altered slightly how the transformation was done in respect to vnRectBounds and it seems to work flawlessly now!
Thanks for the script!
Can you let me know how I can access the xy coordinates of the roi so I can draw it?
when I say
[roilist] = ReadImageJROI(roiDirectoryCell)
I get a struct within a cell. The only information i can find to reconstruct the roi is vnRectBounds, and I don't understand how to make use of it.
The roi I'm trying to draw is of type 'oval'. could you please explain this in some more detail?
Thanks for the comment; I must have that warning switched off! I'll fix it next version.
Does what it says, and does it right. The function is well documented and cover all ROI types well.
There is just a minor warning coming from line 157, because of the capitalized FILESEP...
Shifted to GIT repository
Now supports reading slice position for point ROIs, as well as sub-pixel locations.
Updated citation and formatting
Removed GNU license statement
Added paper reference.
Added support for reading information from "header 2" metadata.
Updated file to read position field correctly.
Different way of reading zip file contents guarantees that the order of ROIs is always preserved
ROI order is now preserved
Fixed a bug reported by Benjamin Ricca
Fixed the warning about capitalised FILESEP.