Image registration
advancedviewportregistration
Console
Image registration tool
image_registration.html
1<!doctype >
2<html lang="en">
3
4<head>
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=10">
7 <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
8
9 <!-- Include PMA.UI required libraries downloaded or from CDN -->
10 <script src="./pma.ui/jquery-3.1.0.js"></script>
11 <link href="./pma.ui/font-awesome.min.css" type="text/css" rel="stylesheet">
12
13 <!-- Include PMA.UI script & css -->
14 <script src="./pma.ui/pma.ui.js"></script>
15 <link href="./pma.ui/pma.ui.css" type="text/css" rel="stylesheet">
16
17 <!-- Include custom script & css -->
18 <script src="./js/image_registration.js"></script>
19 <link href="./css/image_registration.css" type="text/css" rel="stylesheet">
20
21 <title>Image Registration</title>
22</head>
23
24<body>
25 <h3 id="status-label">Ready</h3>
26 <div class="container">
27 <div id="viewer1" tabindex="0" class="column"></div>
28 <div id="viewer2" tabindex="0" class="column"></div>
29 </div>
30
31 <div style="clear: left; text-align: center">
32 <input id="btn-register" type="button" value="Register" />
33 </div>
34</body>
image_registration.css
1html,
2body {
3 height: 100%;
4 padding: 0px;
5 margin: 0px;
6 overflow: hidden;
7}
8
9.container {
10 height: 90%;
11 display: flex;
12}
13
14.column {
15 flex-grow: 1;
16 background-color: lightgray;
17 border: 1px gray solid;
18 border-radius: 5px;
19 margin: 10px;
20}
21
22#status-label {
23 text-align: center;
24 margin: 0;
25}
image_registration.js
1var serverUrl = "https://host.pathomation.com/pma.core.3/";
2var username = "zuidemo";
3var password = "zuidemo";
4
5var leftAnnotationPoints = [];
6var rightAnnotationPoints = [];
7var leftRegistrationPoints = [];
8var rightRegistrationPoints = [];
9
10var slideLoader1, slideLoader2;
11var annotationManager1, annotationManager2;
12
13jQuery(function () {
14 var context = new PMA.UI.Components.Context({
15 caller: "Image registration",
16 });
17 new PMA.UI.Authentication.AutoLogin(context, [
18 { serverUrl: serverUrl, username: username, password: password },
19 ]);
20
21 var options1 = {
22 element: "#viewer1",
23 digitalZoomLevels: 2,
24 scaleLine: true,
25 filename: false,
26 barcode: false,
27 annotations: true,
28 };
29
30 slideLoader1 = new PMA.UI.Components.SlideLoader(context, options1);
31 annotationManager1 = null;
32
33 slideLoader1.listen(
34 PMA.UI.Components.Events.SlideLoaded,
35 function (args) {
36 annotationManager1 = new PMA.UI.Components.Annotations({
37 context: context,
38 element: null,
39 viewport: slideLoader1.mainViewport,
40 serverUrl: args.serverUrl,
41 path: args.path,
42 enabled: true,
43 });
44
45 annotationManager1.listen(
46 PMA.UI.Components.Events.AnnotationAdded,
47 function (e) {
48 leftAnnotationPoints.push(e.feature.getId());
49 leftRegistrationPoints.push(e.feature.getGeometry().getCoordinates());
50
51 if (leftRegistrationPoints.length === 1) {
52 document.querySelector("#status-label").innerHTML = "Define the first anchor point on the right image";
53 annotationManager2.startDrawing({ type: "Point", notes: "1" });
54 }
55 if (leftRegistrationPoints.length === 2) {
56 document.querySelector("#status-label").innerHTML = "Define the second anchor point on the right image";
57 annotationManager2.startDrawing({ type: "Point", notes: "2" });
58 }
59 // else {
60 // setTimeout(() => {
61 // annotationManager1.startDrawing({ type: "Point" });
62 // }, 150);
63 // }
64 }
65 );
66 }
67 );
68
69 slideLoader1.load(
70 serverUrl,
71 "wsiformats/Registration/PDL1(22C3)_04311207B0011S.mrxs"
72 );
73
74 var options2 = {
75 element: "#viewer2",
76 digitalZoomLevels: 2,
77 scaleLine: true,
78 filename: false,
79 barcode: false,
80 annotations: true,
81 };
82
83 slideLoader2 = new PMA.UI.Components.SlideLoader(context, options2);
84 annotationManager2 = null;
85
86 slideLoader2.listen(
87 PMA.UI.Components.Events.SlideLoaded,
88 function (args) {
89 annotationManager2 = new PMA.UI.Components.Annotations({
90 context: context,
91 element: null,
92 viewport: slideLoader2.mainViewport,
93 serverUrl: args.serverUrl,
94 path: args.path,
95 enabled: true,
96 });
97
98 annotationManager2.listen(
99 PMA.UI.Components.Events.AnnotationAdded,
100 function (e) {
101 rightAnnotationPoints.push(e.feature.getId());
102 rightRegistrationPoints.push(e.feature.getGeometry().getCoordinates());
103
104 if (rightRegistrationPoints.length === 1) {
105 document.querySelector("#status-label").innerHTML = "Define the second anchor point on the left image";
106 annotationManager1.startDrawing({ type: "Point", notes: "2" });
107 }
108 else if (rightRegistrationPoints.length === 2) {
109 document.querySelector("#status-label").innerHTML = "Affine transformation calculated";
110 slideLoader2.mainViewport.alignViewports(slideLoader1.mainViewport, rightRegistrationPoints, leftRegistrationPoints);
111
112 // Clear all previous annotations
113 for (var i in leftAnnotationPoints) {
114 annotationManager1.deleteAnnotation(leftAnnotationPoints[i]);
115 }
116
117 for (var i in rightAnnotationPoints) {
118 annotationManager2.deleteAnnotation(rightAnnotationPoints[i]);
119 }
120
121 syncManager.enableSync();
122 }
123 // else {
124 // setTimeout(() => {
125 // annotationManager2.startDrawing({ type: "Point" });
126 // }, 150);
127 // }
128 }
129 );
130 }
131 );
132
133 slideLoader2.load(
134 serverUrl,
135 "wsiformats/Registration/PDL1(22C3)_04311207B0013S.mrxs"
136 );
137
138 document.querySelector("#btn-register").addEventListener("click", () => {
139 syncManager.disableSync();
140 document.querySelector("#status-label").innerHTML = "Define the first anchor point on the left image";
141
142 // Cancel any drawing operation before we begin
143 annotationManager1.finishDrawing(false);
144 annotationManager2.finishDrawing(false);
145
146 // Reset anchor point arrays
147 leftAnnotationPoints = [];
148 rightAnnotationPoints = [];
149 leftRegistrationPoints = [];
150 rightRegistrationPoints = [];
151
152 // Start drawing on the left image and wait until we get two points
153 annotationManager1.startDrawing({ type: "Point", notes: "1" });
154 annotationManager2.startDrawing({ type: "Point", notes: "1" });
155 });
156
157 // Initialize sync manager for both slide loaders
158 syncManager = new PMA.UI.Components.SyncView([slideLoader1, slideLoader2]);
159});