Closed Michael-L-Miller closed 2 years ago
Hi Michael,
I'm not sure I have exactly understood your question, but see if this helps...
Shapes are considered 'attachments'. This means they are associated with a particular modality, i.e., you have some annotations made on modality 1 and you want them projected to modality 2 through wsireg
's registration.
I have modified the demo code from the github splash readme to add an attachment shape, and then transform it at the end of the run. This will produce a new geojson at the end of the registration. I've broken up the code sections a bit for visibility.
from wsireg.wsireg2d import WsiReg2D
# initialize registration graph
reg_graph = WsiReg2D("my_reg_project", "./project_folder")
# add registration images (modalities)
reg_graph.add_modality(
"modality_fluo",
"./data/im1.tiff",
image_res=0.65,
channel_names=["DAPI", "eGFP", "DsRed"],
channel_colors=["blue", "green", "red"],
prepro_dict={
"image_type": "FL",
"ch_indices": [1],
"as_uint8": True,
"contrast_enhance": True,
},
)
reg_graph.add_modality(
"modality_brightfield",
"./data/im2.tiff",
image_res=1,
prepro_dict={"image_type": "BF", "as_uint8": True, "inv_int_opt": True},
)
# new line to add "attachment" shapes to data
reg_graph.add_attachment_shapes("modality_fluo", "fluo_annotations", "./data/fluo_anno.geojson")
reg_graph.add_reg_path(
"modality_fluo",
"modality_brightfield",
thru_modality=None,
reg_params=["rigid", "affine"],
)
reg_graph.register_images()
reg_graph.save_transformations()
# new line to transform shapes to a new geojson
reg_graph.transform_shapes()
reg_graph.transform_images(file_writer="ome.tiff")
If you exported the geojson that was transformed from QuPath v0.3.0 or higher (you can do this by going to File -> Object data... -> Export as geojson), you will need to change the file extension from ".json" to ".geojson" (This is a thing that predates QP v0.3.0, I will fix in current wsireg
now that you brought to my attention just now, thanks!) and then you can drag and drop it onto the QP canvas and it should load up. All the metadata is maintained: detections should be loaded as detections, annotations as annotations and any measurements should be there, but bear in mind that these are measurements from the previous modality... wsireg
simply replaces the coordinate data.
If you are still having issues with drag and drop, this groovy script will prompt you for a file path and then read in the selected geojson. You can run it in the QuPath script editor.
// Import GeoJson into QuPath
// Author : Nathan Heath Patterson, heath.patterson@vanderbilt.edu
// import libraries
import qupath.lib.io.GsonTools
// instantiate tools
def gson=GsonTools.getInstance(true);
// prepare template
def type = new com.google.gson.reflect.TypeToken<List<qupath.lib.objects.PathObject>>() {}.getType();
def json_fp = promptForFile(null)
// read annotations
bufferedReader = new BufferedReader(new FileReader(json_fp));
deserializedAnnotations = gson.fromJson(bufferedReader.text, type);
// add to dataset
addObjects(deserializedAnnotations);
Thanks. This is helpful. I'll give it a try right now.
Hi Nathan.
Thanks again for your help.
When I execute the code, there seems to be an error with the geojson file. I exported this file from QuPath (File > Object Data > Export as GeoJSON). I used the default export options ("as Feature Collection") but also tried with this option unselected.
Time spent on saving the results, applying the final transform etc.: 0 ms.
transforming shape set polygons associated with modality_HE to modality_mGT
Traceback (most recent call last):
File "wsireg-test.py", line 38, in
Apologies, The issue is that the extension ".geojson" isn't recognized as a geojson! I had fixed this in my dev version that was just on git but hadn't pushed a new release to pypi. You should be able to reinstall wsireg and try again and it will hopefully work.
to reinstall do from the terminal:
pip install wsireg --upgrade
# or
pip uninstall wsireg
pip install wsireg
If you are in an interactive environment, you can do import wsireg;print(wsireg.__version__)
and you should see "0.3.2". I appreciate your patience on this, you are the first person in the wild that I know of to use this feature so bear with me!
No worries, take your time.
I was able to upgrade wsireg to 0.3.2.
When I run the code, a new error message is generated:
Time spent on saving the results, applying the final transform etc.: 0 ms.
transforming shape set polygons associated with modality_HE to modality_mGT
Traceback (most recent call last):
File "wsireg-test.py", line 37, in <module>
reg_graph.transform_shapes()
File "/Users/mike/Library/Python/3.7/lib/python/site-packages/wsireg/wsireg2d.py", line 1131, in transform_shapes
self.transformations[attachment_modality],
File "/Users/mike/Library/Python/3.7/lib/python/site-packages/wsireg/reg_shapes.py", line 156, in transform_shapes
target_res=self.target_res,
File "/Users/mike/Library/Python/3.7/lib/python/site-packages/wsireg/utils/shape_utils.py", line 391, in transform_shapes
target_res=target_res,
File "/Users/mike/Library/Python/3.7/lib/python/site-packages/wsireg/utils/shape_utils.py", line 337, in itk_transform_pts
t_pt = t.inverse_transform.TransformPoint(pt)
File "/Users/mike/Library/Python/3.7/lib/python/site-packages/SimpleITK/SimpleITK.py", line 4894, in TransformPoint
return _SimpleITK.Transform_TransformPoint(self, point)
TypeError: in method 'Transform_TransformPoint', argument 2 of type 'std::vector< double,std::allocator< double > > const &'
Is it possible for you to send me this specific geojson file? I think I can fix this, but need to make sure of the exact cause. Thanks.
Sure. Pasted below.
[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[856, 137],[851, 139],[813, 139],[805, 142],[800, 142],[795, 144],[784, 144],[779, 147],[774, 147],[772, 149],[764, 149],[762, 152],[759, 152],[754, 154],[749, 154],[746, 157],[744, 157],[739, 159],[736, 159],[734, 162],[731, 162],[726, 165],[723, 165],[723, 167],[718, 167],[718, 170],[716, 170],[713, 172],[711, 175],[708, 177],[703, 180],[698, 185],[695, 188],[690, 190],[685, 193],[683, 198],[677, 200],[672, 205],[665, 210],[660, 213],[655, 218],[649, 221],[644, 226],[639, 228],[634, 231],[629, 233],[624, 236],[621, 239],[619, 239],[616, 241],[614, 244],[611, 246],[606, 249],[604, 251],[601, 254],[596, 256],[593, 261],[591, 264],[588, 267],[586, 269],[583, 274],[583, 277],[581, 279],[581, 284],[578, 289],[578, 292],[578, 297],[578, 300],[578, 305],[578, 307],[578, 310],[578, 312],[578, 315],[578, 320],[578, 325],[581, 330],[581, 338],[583, 343],[583, 346],[583, 351],[586, 356],[586, 358],[588, 363],[591, 366],[593, 371],[593, 374],[596, 376],[598, 381],[601, 384],[604, 386],[606, 391],[609, 394],[611, 397],[614, 399],[619, 402],[621, 404],[624, 407],[626, 409],[632, 412],[634, 414],[637, 417],[639, 419],[642, 422],[647, 425],[649, 427],[655, 432],[660, 435],[665, 440],[670, 445],[672, 448],[675, 450],[680, 455],[688, 458],[693, 463],[700, 468],[708, 473],[731, 486],[734, 486],[736, 488],[731, 491],[734, 493],[736, 493],[736, 496],[739, 496],[741, 498],[744, 501],[746, 501],[746, 504],[751, 504],[751, 506],[754, 506],[756, 509],[759, 511],[762, 511],[762, 514],[764, 514],[767, 516],[769, 519],[772, 519],[774, 521],[777, 521],[777, 524],[782, 524],[782, 527],[784, 527],[787, 529],[790, 529],[792, 532],[795, 532],[797, 534],[800, 534],[805, 537],[807, 539],[813, 539],[815, 542],[818, 544],[823, 547],[825, 547],[828, 549],[830, 549],[833, 552],[835, 552],[835, 555],[841, 555],[843, 557],[853, 557],[853, 560],[907, 560],[907, 557],[912, 557],[912, 555],[914, 555],[917, 552],[920, 549],[920, 547],[922, 547],[922, 544],[922, 542],[925, 542],[925, 539],[925, 537],[927, 534],[927, 532],[927, 529],[927, 527],[927, 524],[927, 521],[927, 519],[930, 516],[930, 511],[930, 509],[930, 506],[932, 504],[932, 501],[932, 498],[932, 493],[932, 491],[932, 488],[932, 486],[932, 483],[932, 481],[932, 478],[932, 476],[932, 473],[932, 470],[932, 465],[932, 463],[932, 460],[932, 458],[932, 455],[932, 453],[932, 448],[932, 445],[932, 442],[932, 440],[932, 435],[932, 432],[932, 427],[932, 422],[932, 417],[932, 414],[932, 412],[932, 409],[932, 407],[930, 402],[930, 397],[930, 394],[930, 389],[930, 386],[927, 381],[927, 376],[925, 371],[925, 366],[925, 363],[925, 358],[925, 353],[922, 351],[922, 346],[922, 343],[922, 338],[922, 335],[920, 330],[920, 328],[920, 325],[920, 320],[920, 318],[917, 312],[917, 310],[914, 305],[914, 300],[914, 297],[914, 292],[914, 287],[914, 282],[912, 279],[912, 274],[912, 269],[912, 267],[909, 261],[909, 256],[909, 251],[909, 246],[909, 244],[909, 239],[909, 236],[909, 231],[909, 228],[909, 226],[909, 221],[907, 218],[907, 216],[907, 213],[907, 210],[904, 208],[904, 205],[904, 203],[904, 200],[902, 198],[902, 195],[902, 193],[899, 190],[899, 188],[897, 185],[894, 182],[894, 180],[892, 175],[892, 172],[892, 170],[889, 167],[889, 165],[889, 162],[886, 159],[886, 157],[886, 154],[886, 152],[886, 149],[884, 147],[884, 144],[884, 142],[884, 139],[876, 139],[874, 137],[856, 137]]]},"properties":{"object_type":"annotation","isLocked":false}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[889, 644],[886, 646],[881, 646],[879, 649],[876, 649],[874, 651],[871, 654],[869, 656],[866, 662],[864, 664],[858, 669],[856, 674],[853, 679],[848, 685],[846, 687],[846, 692],[843, 695],[841, 697],[838, 700],[830, 707],[823, 715],[820, 720],[815, 725],[810, 733],[807, 736],[800, 743],[797, 746],[792, 751],[787, 758],[782, 764],[777, 766],[769, 774],[767, 776],[762, 779],[759, 781],[756, 784],[751, 784],[746, 786],[741, 789],[736, 789],[731, 792],[721, 792],[718, 794],[698, 794],[695, 797],[611, 797],[604, 794],[598, 794],[598, 797],[601, 797],[601, 802],[604, 802],[604, 804],[606, 807],[606, 809],[609, 809],[614, 817],[616, 822],[619, 825],[621, 830],[624, 837],[626, 840],[629, 848],[632, 850],[634, 860],[637, 865],[642, 873],[642, 876],[644, 883],[647, 888],[652, 899],[655, 906],[662, 919],[662, 924],[667, 937],[670, 944],[677, 960],[683, 967],[693, 983],[698, 993],[711, 1013],[718, 1021],[726, 1034],[728, 1036],[734, 1039],[734, 1036],[736, 1039],[739, 1039],[739, 1041],[741, 1041],[741, 1044],[744, 1046],[749, 1046],[751, 1049],[754, 1052],[759, 1052],[759, 1054],[762, 1054],[764, 1057],[779, 1057],[782, 1059],[807, 1059],[810, 1057],[833, 1057],[838, 1054],[848, 1054],[851, 1052],[853, 1052],[856, 1049],[858, 1049],[861, 1046],[864, 1046],[866, 1044],[869, 1044],[871, 1041],[871, 1039],[874, 1039],[876, 1036],[879, 1036],[881, 1034],[884, 1031],[886, 1031],[889, 1029],[892, 1029],[892, 1026],[897, 1026],[897, 1023],[899, 1023],[899, 1021],[904, 1021],[904, 1018],[907, 1016],[909, 1016],[912, 1013],[914, 1011],[917, 1011],[917, 1008],[920, 1008],[922, 1006],[925, 1003],[927, 1003],[930, 1001],[932, 998],[935, 995],[940, 993],[943, 990],[945, 988],[948, 988],[953, 983],[955, 980],[963, 975],[965, 973],[968, 967],[971, 965],[973, 962],[973, 960],[973, 957],[973, 955],[973, 952],[973, 950],[973, 947],[971, 944],[971, 942],[968, 939],[968, 937],[968, 934],[965, 932],[963, 929],[960, 924],[958, 922],[955, 919],[953, 916],[953, 914],[950, 911],[950, 909],[950, 906],[948, 904],[948, 901],[945, 899],[943, 891],[940, 888],[937, 881],[935, 876],[935, 871],[932, 865],[930, 863],[930, 858],[927, 853],[922, 845],[920, 835],[917, 830],[917, 820],[914, 817],[914, 807],[914, 797],[914, 786],[914, 761],[912, 748],[912, 728],[912, 718],[912, 710],[912, 702],[912, 690],[912, 682],[909, 672],[909, 667],[909, 662],[909, 659],[909, 656],[909, 654],[907, 651],[904, 646],[902, 646],[899, 644],[889, 644]]]},"properties":{"object_type":"annotation","isLocked":false}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[1901, 585],[1898, 588],[1891, 588],[1888, 590],[1886, 590],[1883, 593],[1880, 595],[1878, 595],[1878, 598],[1875, 600],[1870, 606],[1865, 606],[1865, 608],[1863, 608],[1857, 611],[1855, 613],[1850, 616],[1845, 616],[1840, 618],[1835, 618],[1827, 621],[1817, 626],[1807, 628],[1794, 634],[1784, 636],[1773, 639],[1766, 641],[1761, 644],[1753, 646],[1745, 649],[1738, 651],[1730, 651],[1722, 654],[1715, 654],[1707, 656],[1702, 656],[1697, 659],[1687, 659],[1682, 662],[1669, 662],[1666, 664],[1656, 664],[1656, 667],[1654, 667],[1654, 669],[1654, 672],[1651, 677],[1651, 679],[1651, 685],[1651, 690],[1651, 692],[1651, 695],[1651, 697],[1651, 700],[1651, 705],[1651, 707],[1651, 713],[1654, 715],[1654, 720],[1656, 725],[1656, 730],[1656, 738],[1659, 743],[1659, 751],[1659, 753],[1659, 761],[1661, 769],[1661, 776],[1661, 784],[1661, 789],[1661, 799],[1661, 807],[1661, 815],[1661, 822],[1661, 830],[1661, 835],[1664, 843],[1664, 850],[1666, 858],[1671, 868],[1674, 878],[1679, 891],[1687, 904],[1694, 919],[1705, 934],[1712, 950],[1720, 962],[1730, 975],[1743, 988],[1750, 992.9],[1750, 993],[1750.14, 993],[1753, 995],[1753, 998],[1753, 1001],[1756, 1001],[1756, 1003],[1756, 1006],[1758, 1006],[1758, 1008],[1761, 1008],[1761, 1011],[1763, 1013],[1763, 1016],[1766, 1018],[1766, 1021],[1768, 1021],[1771, 1023],[1771, 1026],[1773, 1026],[1773, 1029],[1776, 1031],[1781, 1036],[1786, 1039],[1789, 1041],[1791, 1044],[1794, 1046],[1796, 1049],[1796, 1052],[1799, 1052],[1799, 1054],[1801, 1054],[1801, 1057],[1801, 1059],[1804, 1059],[1804, 1062],[1807, 1064],[1809, 1067],[1812, 1069],[1835, 1069],[1835, 1067],[1842, 1067],[1842, 1064],[1850, 1064],[1852, 1062],[1857, 1062],[1857, 1059],[1865, 1059],[1865, 1057],[1870, 1057],[1870, 1054],[1875, 1054],[1878, 1052],[1880, 1052],[1883, 1049],[1888, 1049],[1891, 1046],[1896, 1046],[1898, 1044],[1903, 1044],[1906, 1041],[1911, 1041],[1914, 1039],[1921, 1039],[1924, 1036],[1929, 1036],[1931, 1034],[1936, 1031],[1939, 1031],[1942, 1029],[1947, 1029],[1949, 1026],[1952, 1023],[1957, 1023],[1959, 1021],[1962, 1018],[1965, 1018],[1967, 1016],[1972, 1013],[1975, 1011],[1980, 1008],[1982, 1008],[1985, 1006],[1987, 1003],[1990, 1001],[1995, 995],[1998, 993],[2003, 990],[2008, 988],[2010, 985],[2013, 983],[2018, 980],[2021, 975],[2026, 973],[2028, 970],[2033, 965],[2036, 962],[2041, 957],[2044, 955],[2046, 952],[2051, 947],[2054, 944],[2056, 939],[2059, 937],[2061, 932],[2064, 929],[2066, 927],[2069, 924],[2072, 922],[2074, 919],[2074, 916],[2077, 914],[2079, 911],[2079, 909],[2082, 906],[2082, 904],[2084, 901],[2087, 896],[2089, 891],[2089, 888],[2092, 883],[2095, 881],[2097, 876],[2100, 871],[2102, 865],[2105, 860],[2105, 855],[2107, 853],[2107, 850],[2107, 845],[2110, 843],[2110, 837],[2112, 832],[2112, 827],[2115, 825],[2115, 822],[2115, 820],[2115, 815],[2115, 812],[2115, 809],[2115, 807],[2115, 802],[2115, 799],[2115, 797],[2112, 794],[2112, 792],[2112, 789],[2112, 786],[2110, 784],[2110, 779],[2110, 776],[2110, 774],[2110, 769],[2110, 766],[2110, 764],[2110, 758],[2110, 756],[2112, 753],[2112, 748],[2110, 746],[2110, 741],[2112, 736],[2112, 728],[2112, 723],[2112, 715],[2112, 707],[2112, 702],[2112, 697],[2112, 695],[2112, 692],[2112, 690],[2110, 685],[2107, 682],[2105, 679],[2102, 677],[2102, 674],[2100, 674],[2100, 672],[2095, 672],[2092, 669],[2089, 667],[2084, 667],[2082, 664],[2079, 662],[2074, 659],[2072, 656],[2069, 654],[2064, 651],[2061, 649],[2056, 644],[2054, 641],[2049, 639],[2046, 636],[2038, 631],[2036, 626],[2033, 623],[2031, 621],[2028, 616],[2023, 613],[2021, 611],[2018, 606],[2016, 603],[2010, 598],[2008, 595],[2003, 593],[1998, 590],[1995, 590],[1990, 588],[1985, 588],[1980, 585],[1901, 585]]]},"properties":{"object_type":"annotation","isLocked":false}}]
Thanks for that, I used it to sort out the issue and develop some tests. Your point data is all integer types and the point transformation expects floating point type data, so just a simple conversion. I've updated to v0.3.2.1 on pypi so please reinstall and I think that it will work.
Awesome. Will test in a bit. Thanks again.
Sent from my iPhone
On Dec 28, 2021, at 2:29 PM, Heath Patterson @.***> wrote:
Thanks for that, I used it to sort out the issue and develop some tests. Your point data is all integer types and the point transformation expects floating point type data, so just a simple conversion. I've updated to v0.3.2.1 on pypi so please reinstall and I think that it will work.
— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you authored the thread.
Hi Nathan. Yup its running without issue. Thanks again.
Awesome project. I'm a novice so was wondering if you could show me how to transform/register the QuPath shapes (Geojson) from one modality to the other. Also, I am having trouble importing these changes into QuPath. Is there a way to apply the values generated in your analysis in QuPath.