PMA.UI Examples 2.43.3by Pathomation

Image registration

advancedviewportregistration
Console
Image registration tool
image_registration.html
1<!doctype html>
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});