Skip to content

Commit

Permalink
2.0.0 QuPath ROI Bioformats Arm64.
Browse files Browse the repository at this point in the history
  • Loading branch information
BiologyTools committed Feb 2, 2024
1 parent 88a18d2 commit ded2283
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ packages
*.v2
*.v2
*.v2
.vs/ProjectEvaluation/biolib.metadata.v7.bin
*.bin
Binary file modified .vs/ProjectEvaluation/biolib.metadata.v7.bin
Binary file not shown.
Binary file modified .vs/ProjectEvaluation/biolib.projects.v7.bin
Binary file not shown.
26 changes: 13 additions & 13 deletions BioLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,31 @@
<PackageIcon>banner.jpg</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/BiologyTools/BioLib</RepositoryUrl>
<AssemblyVersion>1.9.0</AssemblyVersion>
<FileVersion>1.9.0</FileVersion>
<PackageVersion>1.9.0</PackageVersion>
<AssemblyVersion>2.0.0</AssemblyVersion>
<FileVersion>2.0.0</FileVersion>
<PackageVersion>2.0.0</PackageVersion>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://biologytools.github.io/</PackageProjectUrl>
<PackageTags>Biology; ImageJ; Bio-Formats; Image-Stacks; Microscopy; Whole-Slide-Image;</PackageTags>
<PackageReleaseNotes>Added asynchronous methods, updated Bioformats to 7.1.0</PackageReleaseNotes>
<PackageReleaseNotes>QuPath GeoJson ROI support, Bioformats Arm64 Support.</PackageReleaseNotes>
<Authors>Erik Repo</Authors>
</PropertyGroup>
<ItemGroup>
<Content Include="LICENSE" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AForgeBio" Version="1.4.3" />
<PackageReference Include="BioFormats.NET6" Version="7.1.0.1" />
<PackageReference Include="AForgeBio" Version="1.5.0" />
<PackageReference Include="BioFormats.NET6" Version="7.1.0.2" />
<PackageReference Include="BitMiracle.LibTiff.NET" Version="2.4.649" />
<PackageReference Include="CS-Script" Version="4.8.13" />
<PackageReference Include="CS-Script" Version="4.8.14" />
<PackageReference Include="NetVips" Version="2.4.0" />
<PackageReference Include="NetVips.Native" Version="8.15.0" />
<PackageReference Include="NetVips.Native.linux-arm64" Version="8.15.0" />
<PackageReference Include="NetVips.Native.linux-x64" Version="8.15.0" />
<PackageReference Include="NetVips.Native.osx-arm64" Version="8.15.0" />
<PackageReference Include="NetVips.Native.osx-x64" Version="8.15.0" />
<PackageReference Include="NetVips.Native.win-x64" Version="8.15.0" />
<PackageReference Include="NetVips.Native" Version="8.15.1" />
<PackageReference Include="NetVips.Native.linux-arm64" Version="8.15.1" />
<PackageReference Include="NetVips.Native.linux-x64" Version="8.15.1" />
<PackageReference Include="NetVips.Native.osx-arm64" Version="8.15.1" />
<PackageReference Include="NetVips.Native.osx-x64" Version="8.15.1" />
<PackageReference Include="NetVips.Native.win-x64" Version="8.15.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.8.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
265 changes: 265 additions & 0 deletions Source/QuPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using AForge;

namespace BioLib
{
public class QuPath
{
public class GeoJsonFeatureCollection
{
public string type { get; set; }
public List<GeoJsonFeature> features { get; set; }
}

public class GeoJsonFeature
{
public string type { get; set; }
public GeoJsonGeometry geometry { get; set; }
public IDictionary<string, object> properties { get; set; }
}

public class GeoJsonGeometry
{
public class GeoJsonPlane
{
public int c { get; set; }
public int z { get; set; }
public int t { get; set; }
}
public string type { get; set; }
public GeoJsonPlane plane { get; set; }
public object coordinates { get; set; }

public ZCT GetZCT()
{
if (plane.c < 0)
return new ZCT(plane.z,0,plane.t);
else
return new ZCT(plane.z,plane.c,plane.t);
}
}

public class GeoJsonPoint
{
public class GeoJsonPlane
{
public int c { get; set; }
public int z { get; set; }
public int t { get; set; }
}
public string type { get; set; }
public double[] coordinates { get; set; }
public GeoJsonPlane plane { get; set; }
public static GeoJsonPoint FromROI(ROI roi, BioImage b)
{
GeoJsonPoint g = new GeoJsonPoint();
PointD p = b.ToImageSpace(roi.PointsD[0]);
g.coordinates = new double[2] { p.X, p.Y };
g.type = "Point";
g.plane = new GeoJsonPlane();
g.plane.z = roi.coord.Z;
g.plane.c = roi.coord.C;
g.plane.t = roi.coord.T;
return g;
}
}
public static PointD[] GetPoints(GeoJsonGeometry p,BioImage b)
{
if (p.type == "Point")
{
List<PointD> points = new List<PointD>();
double[] gs = JsonConvert.DeserializeObject<double[]>(p.coordinates.ToString());
points.Add(new PointD(gs[0], gs[1]));
for (int i = 0; i < points.Count; i++)
{
points[i] = new PointD(b.StageSizeX + (points[i].X / b.SizeX) * b.Volume.Width, b.StageSizeY + (points[i].Y / b.SizeY) * b.Volume.Height);
}
return points.ToArray();
}
else if(p.type == "Polygon")
{
List<PointD> points = new List<PointD>();
double[][][] gs = JsonConvert.DeserializeObject<double[][][]>(p.coordinates.ToString());
foreach (double[] item in gs[0])
{
points.Add(new PointD(item[0], item[1]));
}
for (int i = 0; i < points.Count; i++)
{
points[i] = new PointD(b.StageSizeX + (points[i].X / b.SizeX)*b.Volume.Width, b.StageSizeY + (points[i].Y / b.SizeY) * b.Volume.Height);
}
return points.ToArray();
}
else
{
List<PointD> points = new List<PointD>();
double[][] gs = JsonConvert.DeserializeObject<double[][]>(p.coordinates.ToString());
foreach (double[] item in gs)
{
points.Add(new PointD(item[0], item[1]));
}
for (int i = 0; i < points.Count; i++)
{
points[i] = new PointD(b.StageSizeX + (points[i].X / b.SizeX) * b.Volume.Width, b.StageSizeY + (points[i].Y / b.SizeY) * b.Volume.Height);
}
return points.ToArray();
}
}
public class GeoJsonLineString
{
public class GeoJsonPlane
{
public int c { get; set; }
public int z { get; set; }
public int t { get; set; }
}
public string type { get; set; }
public double[][] coordinates { get; set; }
public GeoJsonPlane plane { get; set; }
public static GeoJsonLineString FromROI(ROI roi, BioImage b)
{
GeoJsonLineString g = new GeoJsonLineString();
double[][] ds = new double[roi.PointsD.Count][];
for (int i = 0; i < roi.PointsD.Count; i++)
{
PointD po = b.ToImageSpace(roi.PointsD[i]);
ds[i] = new double[2] { po.X, po.Y };
}
g.coordinates = ds;
g.type = "LineString";
g.plane = new GeoJsonPlane();
g.plane.z = roi.coord.Z;
g.plane.c = roi.coord.C;
g.plane.t = roi.coord.T;
return g;
}
}

public class GeoJsonPolygon
{
public class GeoJsonPlane
{
public int c { get; set; }
public int z { get; set; }
public int t { get; set; }
}
public string type { get; set; }
public double[][][] coordinates { get; set; }
public GeoJsonPlane plane { get; set; }
public static GeoJsonPolygon FromROI(ROI roi, BioImage b)
{
int pc = roi.PointsD.Count;
if (roi.PointsD.Last() != roi.PointsD.First())
pc = roi.PointsD.Count + 1;
GeoJsonPolygon g = new GeoJsonPolygon();
double[][][] dds = new double[1][][];
double[][] ds = new double[pc][];
for (int i = 0; i < pc; i++)
{
if (i >= roi.PointsD.Count)
{
PointD po = b.ToImageSpace(roi.PointsD[0]);
ds[i] = new double[2] { (int)po.X, (int)po.Y };
}
else
{
PointD po = b.ToImageSpace(roi.PointsD[i]);
ds[i] = new double[2] { (int)po.X, (int)po.Y };
}
}

dds[0] = ds;
g.coordinates = dds;
g.type = "Polygon";
g.plane = new GeoJsonPlane();
g.plane.z = roi.coord.Z;
g.plane.c = roi.coord.C;
g.plane.t = roi.coord.T;
return g;
}
}

public class Properties
{
public string ObjectType { get; set; }
public bool IsLocked { get; set; }
}

public static void Save(string file, BioImage b)
{
string j = "{ \"type\":\"FeatureCollection\",\"features\":[";
int i = 0;
foreach (ROI roi in b.Annotations)
{
if(i==0)
j += "{\"type\":\"Feature\",\"geometry\":";
else
j += ",{\"type\":\"Feature\",\"geometry\":";
if (roi.type == ROI.Type.Point)
{
GeoJsonPoint p = GeoJsonPoint.FromROI(roi,b);
j+= JsonConvert.SerializeObject(p);
}
else if (roi.type == ROI.Type.Rectangle || (roi.type == ROI.Type.Polygon && roi.closed) || roi.type == ROI.Type.Freeform)
{
GeoJsonPolygon p = GeoJsonPolygon.FromROI(roi, b);
j += JsonConvert.SerializeObject(p);
}
else if (roi.type == ROI.Type.Polyline || roi.type == ROI.Type.Line || roi.type == ROI.Type.Polygon)
{
GeoJsonLineString p = GeoJsonLineString.FromROI(roi, b);
j += JsonConvert.SerializeObject(p);
}

j += ",\"properties\":{\"object_type\":\"annotation\",\"isLocked\":false}}";
i++;
}
j += "]}";
File.WriteAllText(file,j);
}

public static ROI[] ReadROI(string filePath, BioImage b)
{
List<ROI> rois = new List<ROI>();
string st = File.ReadAllText(filePath);
GeoJsonFeatureCollection gs = JsonConvert.DeserializeObject<GeoJsonFeatureCollection>(st);

foreach (GeoJsonFeature f in gs.features)
{
ROI r = new ROI();
if(f.geometry.type == "Polygon")
{
r.type = ROI.Type.Polygon;
r.closed = true;
r.AddPoints(GetPoints(f.geometry,b));
if(f.geometry.plane != null)
r.coord = f.geometry.GetZCT();
}
else if(f.geometry.type == "LineString")
{
r.type = ROI.Type.Line;
r.AddPoints(GetPoints(f.geometry, b));
if (r.PointsD.Count > 2)
r.type = ROI.Type.Polyline;
if (f.geometry.plane != null)
r.coord = f.geometry.GetZCT();
}
else
{
r.type = ROI.Type.Point;
r.AddPoints(GetPoints(f.geometry, b));
if (f.geometry.plane != null)
r.coord = f.geometry.GetZCT();
}
rois.Add(r);
}
return rois.ToArray();
}
}
}

0 comments on commit ded2283

Please sign in to comment.