-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
88a18d2
commit ded2283
Showing
5 changed files
with
280 additions
and
13 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,5 @@ packages | |
*.v2 | ||
*.v2 | ||
*.v2 | ||
.vs/ProjectEvaluation/biolib.metadata.v7.bin | ||
*.bin |
Binary file not shown.
Binary file not shown.
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
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
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(); | ||
} | ||
} | ||
} |