A Minimally Invasive Approach to Pelvic Osteolysis
A Minimally Invasive Approach to Pelvic Osteolysis
Srinivas K. Prasad, MD Ming Li Nicholas Ramey
Department of Computer Science
Johns Hopkins University
446. Quantitative Medical Computing
Engineering Advisor: Dr. R. H. Taylor, Ph.D.
Dept. of Computer Science
Johns Hopkins University
Clinical Advisor: Dr. F. Frassica, MD
Dept. of Orthopaedic Surgery
Johns Hopkins Medical Institutions
May 14, 2001
Table of Contents
1. Introduction
1. Background 1
2. Potential Solution 1
3. First Generation Constraints and Assumptions 1
4. System Overview 1
5. Process Diagram 2
6. Proposed Apparatus 2
2. Pre-Operative Technical Approach
1. Objectives 3
2. Slicer Interface 3
3. Volume Rendering 3
4. Fiducial Finding 4
5. Trajectory Planning 5
3. Intra-Operative Technical Approach
1. Component Co-Registration
1. Image Processing 5
2. 2D-3D Registration 7
3. Robot Registration 7
2. Robot Control
1. System Setup 10
2. Flow of Information 11
3. Frame Calculation 12
4. Project Completion
1. System Integration 14
2. System Testing 14
5. Conclusion
1. System 15
2. Problems 15
3. Accomplished Goals vs. Planned Goals 16
4. Future Considerations 16
6. Management Summary
1. Division of Labor 17
2. Acknowledgements 17
Appendix A – Source Code
Appendix B – References
1. Introduction
1. Background
Pelvic Osteolysis is a protean disease that involves focal erosion of the skeletal pelvis. It has a variety of etiologies, although it typically involves metastatic disease, infection or instrumentation debris secondary to joint replacement. The complexity and deep anatomic location of these lesions have limited the availability of surgical options to date, and patients with this disease suffer from the untoward consequences of both their primary disease process and their consequent immobility.
Traditional surgical approaches have involved large skin incisions with wide exposure and large bony defects, compromising the ability of these tissues to heal post-operatively. Accordingly, patients treated with available surgical techniques do not enjoy significant benefit despite enduring protracted recovery time.
2. Potential Solution
Pelvic Osteolysis is an ideal setting for the invocation of minimally invasive technologies. By enabling surgeons to adequately evacuate and fill these lesions through small bony defects, we hope to substantially improve patient outcome and decrease post-operative recovery time.
Minimally Invasive treatment of pelvic osteolytic lesions can be accomplished by employing surgical instruments that can be passed down into the lesion cavity without requiring wide exposure. The end-to-end solution that we are proposing can be divided into two sub-projects accordingly. The sub-project that this technical report addresses is the accurate creation of a working channel passed through intermediate soft tissues from the patients skin surface down to the target lesion. The second sub-project involves the development of surgical instruments capable of breaking up and evacuating potentially tenacious lesion parenchyma, and capable of filling the resultant intra-osseous cavity with cement or bone graft.
3. First Generation Constraints and Assumptions
Since the final clinical application will require a very sophisticated solution in a complex surgical setting, certain simplifying assumptions have been made in an effort to construct a crude but complete first generation solution. While the clinical applicability of our first implementation is somewhat limited, the solution is modular enough to allow future enhancements that improve its surgical utility.
Initially we are assuming that all of the involved components are static and, accordingly, that all positional relationships between these components remain constant during the procedure. Additionally, we are limiting the level of invasiveness invested in the surgical robot – we will use the robot only to accurately guide the surgeon-inserted cannula towards the target lesion. Finally, we have employed more primitive 2D-3D registration methods that require placement of fixed metal fiducials on the pelvic surface prior to initial CT imaging. We are anticipating the development of true 2D-3D pelvic registration methods that are based solely on anatomic landmarks, and hope to employ this techno1ogy in our final solution.
4. System Overview
The surgical CAD/CAM approach was employed in developing our first generation solution for treating pelvic Osteolysis. This approach couples important engineering principles of design and implementation with experience and expertise of an orthopeadic surgeon. Because pelvic osteolysis is so difficult to reach and treat accurately by hand, this approach employs pre- and intra-operative planning for a robotically-assisted minimally-invasive penetration of overlying soft tissue, targeting the affected pelvic region. Thus, the system can be separated into two major components, a pre-operative planning component, and an intra-operative registration and execution component.
Pre-operatively, the pelvis is scanned with CT. This resulting DICOM image is piped to Slicer, a volumetric visualization package. Slicer’s intuitive interface proved a natural choice for pelvic visualization and manipulation in three-dimensions. It was augmented with a module for constructing a cannula’s trajectory in three-space. The surgeon orients the model as desired, and defines two points using simple x,y,z sliders. These points define the three-dimensional line along which the cannula will be inserted intra-operatively for treatment. Also incorporated into the interface was pre-written functionality for extracting bead-fiducials on the pelvic cortex for later registration.
Intra-operatively, two angled C-arm Fluoroscopic images are taken of the pelvis. These images are dewarped using an aluminum dewarp plate. Next, the image is transformed to remove intensity gradients from the background. This transformation accentuates the small bead fiducials, whose positions are subsequently extracted and used for C-arm – CT (2D-3D) registration of the pelvis. Also intra-operatively, the robot end-effector is oriented in the Fluoro images, and its radio-opaque tip is used in conjunction with the pelvis’s C-arm – CT registration frame to register the robot with all other components. The coregistration of different poses of the robot tip allows accurate calibration and registration of the robot to the pre-operative CT model.
Information from pre-operative trajectory planning for the cannula is passed to the robot, which positions its end-effector, a cannula guide, along the defined path toward the target on the pelvic cortex. The surgeon then slides the cannula through the guide to the cortex, and operates using minimally-invasive instruments passed through this conduit into the pelvic lesion. This step concludes the goal of this first generation solution.
5. Process Diagram
The following flow diagram illustrates the overall system architecture (Figure 1.5.1).
[pic]
Figure 1.5.1 – System Architecture
6. Proposed Apparatus
This first generation solution proposes minimal required apparatus, distilling it down to hardware necessary only for experimental (in vitro) registration and execution. Figure 1.6.1 illustrates the system components as they might be assembled in the Experimental Apparatus. The apparatus includes small bead-fiducials (1.5 mm diameter), radiolucent phantom for pelvic orientation and fixation, adapted needle-driver from Neuromate’s end-effector to function as the cannula guide, dummy cannula with radio-opaque bead at tip for registration, and surgical cannulas. These apparati are readily obtained through the CISST Engineering Research Center and from our Clinical Advisor, Dr. Frank Frassica.
Figure 1.6.1 – System Apparatus
2. Pre-Operative Technical Approach
1. Objectives
The purpose of the pre-operative planning phase is two-fold:
1. To locate the pelvic fiducials in CT space coordinates, and
2. To define the cannula trajectory desired by the Orthopaedic surgeon, also defined in CT Coordinate space.
Accordingly, pre-operative trajectory planning will be performed by the involved Orthopaedic surgeon to assure the adequate establishment of cannula access. While surgeons are very facile with interpretation of CT scan hard-copies, this medium poses a challenge for accurately characterizing the cannula trajectory in CT-space and, furthermore, for locating the fiducials accurately in CT-space.
2. Slicer Interface
To surmount these challenges, we have employed the Slicer Interface developed at the Massachusetts Institute of Technology, an ERC affiliate institution. Slicer is an open-source, extensible visualization package developed in Tcl/Tk using the Visualization Toolkit (VTK). It has proved to be an extremely valuable surgical guidance system in a variety of clinical settings, including Neurosurgery and Urological Surgery, and has a substantial amount of functionality useful in our implementation. To add functionality not currently available, Tcl/Tk modules can be developed and easily added to the Slicer package as a means of developing custom interfaces. We employed this feature by developing an interface module called “Osteolysis” specifically for our project.
The primary utility of Slicer is its ability to manipulate volumetric CT and MR data. Volumetric data is interpreted and projected into orthogonal slices, but can additionally be directly manipulated for volume visualization. Thresholding capability allows surface rendering and fiducial extraction. Additionally, Slicer employs a uniform, pixel-based coordinate system that can readily be translated into accurate mm units within the CT Coordinate system. Finally, Slicer allows the construction and superimposition of VTK objects onto the visualized volumetric model. This enables us to define cannula position and properties within the CT coordinate space.
3. Volume Rendering
Slicer’s built-in segmentation functionality was used to threshold, segment and render the pelvic CT dataset to create a VTK model of the pelvic surface. Slicer will also potentially allow segmentation of the osteolytic lesion to fully characterize its geometry and anatomical context. While the rendering technology is memory-intensive and slow it allows very accurate pre-operative pelvic surface and lesion visualization, thereby enabling surgeons to correctly define the optimal cannula trajectory. Figures 2.3.1 and 2.3.2 represent screenshots of the Slicer interface with rendered pelvic surface models shown – Figure 2.3.2 illustrates a cannula superimposed on the pelvic model.
[pic] [pic]
Figure 2.3.1 – Slicer Interface Figure 2.3.2 – Slicer Interface
There are two windows on the Slicer screen. The left window is the true Slicer interface and the right window is Slicer’s “Viewer” which visually displays a volumetric representation of image data. Orthogonal 2D slices – axial, sagittal and coronal – can be seen displayed on the bottom panel of the right window. Three-dimensional VTK actors are displayed in the upper panel of the same Viewer window, with all elements in the same coordinate system. The Slicer interface on the left was developed by our group to develop and centralize access to necessary functionality like fiducial finding and trajectory planning. Source code for this module is attached in Appendix A.
4. Fiducial Finding
We imported fiducial finding code developed for the Slicer environment by Sheng Xu. The algorithm implemented by Xu marches through consecutive CT slices thresholding pixels based on a threshold input and collecting adjacent hyperdense pixels into consolidated objects representing fiducials. This software reliably discovered all of the 1.5mm fiducials implanted in our pelvis models, and has been configured to store them in an appropriate text file. Figure 2.4.1 illustrates the Slicer Interface “Osteolysis” module developed for fiducial finding. As shown, there is very limited input; intuitively, the “Find Fiducials” button extracts fiducial coordinates, stores them to a text file and displays them in the text box within the same window.
[pic] [pic]
Figure 2.4.1 – Slicer Fiducial Finding Figure 2.5.1 – Slicer Trajectory Definition
5. Trajectory Planning
Trajectory planning involves the specification of two critical properties: the pelvic target coordinates and the orientation of the cannula with respect to the pelvic anatomy. To accomplish this task, the cannula is defined by its two endpoints. The “pelvic” endpoint represents the pelvic target coordinates where the deep end of the cannula is to be positioned intra-operatively; the “origin” endpoint simply defines the trajectory of the cannula in CT space – it does not dictate the length of the cannula in any way, simply its direction. Figure 2.5.1 illustrates the user interface developed for trajectory planning. Coordinates in CT space are defined independently along the three anatomical axes. Endpoint coordinates may be defined in the “Targets” frame by selecting the relevant endpoint (top toggle button) and either manually typing coordinates into the textboxes or by using the sliders to move endpoints in given directions. Alternatively, Slicer’s Viewer may be employed by scrolling through the 2-D orthogonal slices to the appropriate third coordinate and clicking on the image slice at the appropriate 2-dimensional coordinate. The endpoint is visualized as a small Red or Yellow sphere at the prescribed coordinates in CT space when the “Show Target” button is activated. Finally, when both endpoints have been defined, the cannula can be visualized by activating the “View Cannula” button. Certain cannula display properties like radius and opacity can be modified using the above interface. When the user is satisfied that the cannula trajectory is optimal, “Save Trajectory” saves the Cannula endpoints into a text file for intra-operative access.
The GUI developed employs standard Tcl/Tk features to achieve the above functionality. Slicer supports three different coordinate systems:
1. IJK: This represents (i,j) pixel coordinates in slice k, with lower left corner of the axial slice = (0,0)
2. RAS: This represents the “Right-Anterior-Superior” coordinate system of the Viewer. All (i,j,k) coordinates must be converted to RAS before being displayed in the viewer.
3. XYZ: This is a normalized coordinate system where both X and Y have range from 0 to 255 across image Z.
All coordinates must be defined in the (i,j,k) coordinate system to assure consistency across the system. DICOM header information is used to convert (i,j,k) pixel coordinates to mm coordinates in CT space. Finally, VTK objects (spheres and tubes) are created and actors are generated along the VTK pipeline. These actors can be displayed at the specified coordinates, with opacity and radius properties modified as desired. “Save Trajectory” simply saves the endpoint coordinates – in CT mm coordinates – into a pre-defined text file.
3. Intra-Operative Technical Approach
1. Component Co-Registration
1. Image Processing
Intra-operatively, in order to execute the pre-operative plan, the pelvis and robot must be registered to the CT model. In order to accurately register these components, this system relies on fiducials found in fluoroscopic xray images taken in the operating room. The following scheme is employed to locate bead fiducials for both pelvis registration and robot registration, explained anon. The components described below are being integrated into a single intra-operative visualization and registration package.
The c-arm used in this study requires dewarping. The source projects xrays toward the detector plate of the machine, and the resulting image is often “warped”. It is necessary to subtract this warp factor in order to accurately obtain the position of fiducials later. Thus, an aluminum dewarp plate is temporarily installed on the detector. This plate consists of an etched grid that appears in the image. The resulting warped image grid is dewarped using a two-pass algorithm developed by Jianhua Yao. The dewarping algorithm stores a look up table for application to later images. Figure 3.1.1.a represents a warped detector plate image, and Figure 3.1.1.b is the dewarped version of the same image.
Once the look up table is constructed for one pose of the c-arm, the pelvis (or robot tip) is placed in the view of the detector. Images of the pelvis are taken to maximize the number of viewable fiducials. In the case of Fluoro imaging the robot tip, the robot’s end-effector is positioned in the Fluoro view (without the pelvis). Upon capturing an image and applying the look up table from that pose’s detector plate, we apply Andrew Bzostek’s Directional Grey Level Background Correction transformation. This transformation removes abnormal intensity gradients from the image, essentially dulling the background and accentuating “bright” beads of small radii. Figure 3.1.1.c depicts a dewarped pelvis image with four visible fiducials before the applying the transformation, and Figure 3.1.1.d is the same image after the transformation.
Now that the pelvic and robot images have been dewarped and transformed, the fiducials must be extracted for 2D-3D Registration and Robot Registration. Because they have been dewarped, the images serve as an accurate virtual map for the location of the fiducials’ silhouettes (the shadow cast on the detector by the fiducials in three-space). The transformation dulls the background enough to make it simple to apply Jianhua Yao’s Template-Matching algorithm to find round fiducials of fixed radius and relative density. Upon locating these fiducials, their image-coordinate positions (along with a conversion from pixel to metric units for both x and y directions) are stored in a file that is used later for 2D-3D registration and Robot registration. Figure 3.1.1.e shows the result of applying this algorithm on the image from Figure 3.1.1.d above.
2. 2D-3D Registration
The Image Processing described above and the 2D-3D Registration described below are being integrated into one intra-operative visualization and registration package. 2D-3D Registration is the process of matching the intra-operative pelvis to the pre-operative model from CT. To do this, we match fiducials located in the CT model (from the Slicer interface) to fiducials found in fluoroscopic images (after the Image Processing that was just described). The following algorithm was written and implemented by A. Bhargava, C. S. Hundtofte and M. Thober.
The algorithm’s two most important inputs are the two-dimensional coordinates of fiducials found in the fluoro image, and the three-dimensional coordinates of those fiducials in CT space. Realistically, not all of the pelvis’s fiducials may appear in the limited view of the fluoro’s scope, so the algorithm chooses a set of three 2D points to try to register. Upon choosing these three, the “chosen few”, the algorithm attempts to match them to triplet subsets of the 3D fiducials from CT. The registration frame is taken to be that frame which best maps 3D CT fiducial coordinates’ silhouettes to the chosen few from the fluoro image. In other words, the CT pelvis is virtually placed in the field of the fluoroscope, and reoriented until three of its fiducials cast a shadow that overlaps the shadow of the chosen few from the fluoro image. Figure 3.1.2.a was taken from the report written by Bhargava, et al, and illustrates the principle outlined above.
[pic]
3. Robot Registration
A. Overview
The purpose of Robot Registration is to compute a relation between the CT Coordinate System and the Robot Coordinate System. The relation is embodied in the transformation [pic] which can be applied to 3-dimensional CT coordinates to compute corresponding Robot coordinates. This will enable us to convert the pre-operatively defined cannula trajectory coordinates into robot space for appropriate intra-operative cannula guidance within CT space. The accuracy of this guidance is clearly dependent on the accuracy of the computed transformation. To minimize error in this computation, we have employed certain general techniques:
▪ We will be using two Fluoro poses rather than one for reasons that will be described below.
▪ For each pose, we will be passing the robot endpoint through the same set of 3-D coordinates to generate non-parallel image projections of the same 3-D points.
▪ While the Fluoro coordinate system will be used as an intermediate step, we will use it simply to correlate known coordinates in robot space with corresponding coordinates in CT space.
▪ These two sets of corresponding coordinates will be used to directly compute the best rigid transformation between the two coordinate systems, [pic].
As described above in Section 3.1.2, 2D-3D registration requires the construction of projected rays from the Fluoro detector plate back to the Fluoro source. The (x,y) coordinates are reasonably well defined, but it is clear that the z coordinate, along the projected ray, is more susceptible to admitting error. Accordingly we use more than one Fluoro pose to generate two non-parallel projections for each 3-D coordinate. This significantly constrains the z-dimensional error associated with a single ray and enables us to identify the intersection of these two lines as the corresponding 3-dimensional coordinate for the two 2-D Fluoro images.
[pic] [pic]
Figure 3.1.3.a – Fluoroscope: Pose 1 Projection Figure 3.1.3.b – Fluoroscope: Pose 2 Projection
B. Method
1. For each Fluoro Pose:
i. The two fluoroscope poses are illustrated in Figures 3.1.3.a and 3.1.3.b. Note that there are three coordinate systems shown: the Fluoro space, the CT space and the Robot space. Of significance, note that neither the CT coordinate system, nor the Robot coordinate system move with respect to each other, but The Fluoro coordinate system moves with respect to both.
ii. We will employ the 2D-3D Registration algorithm described in Section 3.12 above to generate a transformation [pic] for each pose that transforms 3D points in Fluoro space into 3D points in CT-space.
iii. We will march the robot instrument tip – calibrated to emulate the cannula and marked with a dense, easily identifiable terminal fiducial – through a pre-determined sequence of 3D points in robot space. These points are represented as sequential row vectors in the n x 3 matrix:
[pic]
iv. For each point,[pic], a fluoro image is taken, the fiducial tip is located in the image and the two dimensional image coordinate, (u,v)i, is converted to three dimensional fluoro coordinates, (x,y,0)i.
v. The 3D image point (x,y,0)i is projected back in Fluoro space to the position of the ionizing radiation source, spos, shown in Figures 3.1.3.a and 3.1.3.b. This generates a 3D line in Fluoro space, [pic], and we employ the transformation [pic] derived by our 2D-3D registration of the pelvis to convert this line into a 3D line in CT space, [pic].
vi. Since we have implemented steps (iv) and (v) for each of the n robot points, we have effectively generated a corresponding line in CT space for every point in robot space. We know that the robot point must lie somewhere along this line, but we make no guesses about its exact location.
2. Combining both Poses:
i. Effectively we have created a point-to-line correlation for each pose:
[pic] and [pic]
ii. Since the same set of robot points are used in each Fluoro pose to generate CT-space lines, it follows that each point in robot space, [pic], lies at the intersection of the two lines projected through CT space, [pic] and [pic]. This is illustrated in Figure 3.1.3.c.
[pic]
Figure 3.1.3.c – Computing [pic]
Thus we can compute
[pic]
Clearly, the two 3D lines need not intersect, and, in this case, our function takes the intersection to be the midpoint of the shortest segment connecting the two lines. We can thus generate a point-to-point correlation from points in robot space to points in CT space
[pic]
iii. We can now invoke the CIS library function “ComputeBestRigidRotation()” which takes two sets of 3D points and computes the best rigid transformation between them. This returns the desired transformation between the CT Coordinate System and the Robot Coordinate System, [pic]:
[pic]
2. Robot Control
1. System Setup
The robot we used in our system is Neuromate. The appearance of Neuromate is shown in Figure 3.2.1.a. Neuromate has 5 joints, each joint can only rotate around its axis.
Figure 3.2.1.a – Neuromate Robot
The system setup of the robot control is shown in Figure 3.2.1.b. The MRC (Modular Robot Control) Client is a standard MRC client that connects over the network using RPC/UDP. The MRC Server/Serial Interface is a standard MRC Server that has been modified to include serial communications. This server accepts connections from MRC clients and communicates with the Neuromate Serial Server using the MRC command structure. The Neuromate Serial Server is the server running on the Neuromate PC, which controls the Neuromate robot. This server is responsible for interpreting commands sent from the MRC server, and making calls to the ISS library to manipulate the robot.
Figure 3.2.1.b – Robot Control System Setup
2. Flow of Information
In our first generation solution, we only use the MRC server to control the movements of the robot. Considering the possibility of incorporating and integrating other utilities such as Optical Tracking and Image Overlay into our system, we also developed our robot control software on an MRC client level. The flow of information in our MRC client – MRC Server – Neuromate Server is illustrated in Figure 3.2.2.a. The robot commands originate in the MRC client. This application creates MRC commands that are sent to the MRC server over a network connection. The MRC Server receives and processes these commands, and repackages the commands as necessary before sending them over to the Neuromate. MRC commands are sent over an RS-232 serial connection to the Neuromate Serial Server. The Neuromate server receives the commands, processes them, and returns a command containing the results of the action. When commands are processed, the command opcode is used to call functions that are provided by the ISS library. This library provides the interface from the server to the Neuromate. The ISS library in turn makes calls to the MCS, a background motion control system that controls the Neuromate hardware.
3. Frame Calculation
In our current version, an Instrument holder can be attached to the fifth joint of Neuromate, so that the Neuromate robot serves only as a guide for the Surgically inserted cannula. The goal of robot control in this setting is to move the instrument holder to a specific position and orientation in robot space that accurately guides the cannula along the pre-operatively planned cannula trajectory. The planned trajectory information was stored pre-operatively in CT coordinates, and this must be converted accurately to robot coordinates to meaningfully guide the cannula towards the target. The robot should then maintain this position and orientation throughout the procedure.
The Neuromate Server provides methods to control the Neuromate’s movements on a Frame level. We must calculate the target frame of the holder. By the pre-operative plan, we know the position of the pelvic target, the position of a point on the planned trajectory (which can be the insertion point on the patient’s skin) and the cannula length which represents the distance between the tip of the instrument holder and target (see Figure 3.2.3.a). All these positions are in CT coordinates.
Figure 3.2.3.a – Parameter used in frame calculation
Method to calculate the frame
(1) Translate all the points into Robot Coordinates
All the positions we know here are in CT coordinates. Since we control the movement of the robot using robot coordinates, we need to translate all the positions in CT coordinates into robot coordinates. In Robot Registration, we got the transformation frame from CT coordinates to Robot coordinates. From formula 3.1, 3.2, we get the coordinates of the target T’ and point A’ in Robot coordinates
(3.1)
(3.2)
(2) Calculate the position of the frame
The distance between T’ and A’ is
(3.3)
The coordinates of position P’ in robot coordinates can be calculated by formula 3.3. This is the position of our target frame.
(3) Calculate the rotation of the frame
To make our life easy, we let the planned orientation of the cannula holder to be the z-axis of our target frame. The robot frame first rotates around its x-axis, and then rotates around its y-axis to the orientation of the planned trajectory.
Figure 3.2.3.b – Geometry View of the rotation angle
From Figure 3.2.3.b, we can see the angle (() that the robot frame rotates around its y-axis is the angle between the line PT’ (function 3.4) and plane YOZ (function 3.5). Then we can calculate ( by formula 3.6.
(3.4)
(3.5)
(3.6)
From Figure 3.5, we also can see the angle (() that the robot frame rotates around its x-axis is the angle between the projected line of PT’ in plane YOZ (function 3.7) and z-axis. Then we can calculate ( by formula 3.8.
(3.7)
(3.8)
Therefore, is the rotation from the robot frame to the target frame. And the target frame is .
4. Project Completion
1. System Integration
Clearly, the first generation solution is incomplete at this time. Future work is necessary to bring the system full functionality. This work lies mainly in the integration of the components outlined above that were developed in parallel for the intra-operative environment.
Although the code exists for the Image Processing, 2D-3D Registration, and Robot Registration, it is not seamless, nor is it optimally configured into one application. This relatively simple task involves establishing a naming standard for input and output files from both pre- and intra-op image processing. Such a standard exists but, again, is not seemlessly integrated and requires too many human steps. Essentially, the goal for intra-operative imaging is:
1) Image robot tip and pelvis in one pose,
2) Reimage robot tip and pelvis in a second pose,
3) Press a button to dewarp and extract fiducials into appropriate files,
4) Press a button to calculate and output registration frames for the fluoro and robot to CT.
Aside from image manipulation for registration, intra-operative robot control must be integrated into the system as well. We are taking advantage of MRC’s robot control server interface, but have not established explicit communication between this interface and
1) the output of the registrations, and
2) the output of the pre-operative trajectory planning.
We also have not built the dummy cannula for robot registration, and so by extension have yet to test robot registration altogether.
2. System Testing
After integrating all of the system components that we have developed into a single intra-operative application, we need to test it to establish that all components are functioning independently and interactively as planned, while maintaining high accuracy. We will simulate the entire experimental process with a previously CT-imaged human pelvis phantom. This pelvis has had a peri-acetabular lesion created artificially, and we will measure the accuracy of the cannula guidance with respect to the created defect. Additionally, we will test the accuracy of the system by directing the robot to known points in CT space, e.g. surface fiducials. This will allow us to estimate system inaccuracy embodied in Robot Registration, CT-Fluoro Registration and the Neuromate Robot Control. Alternatively we can move the robot to positions within the Fluoro field of view and compute a predicted Fluoro image position. Comparing this to the actual image coordinate will allow us to estimate inaccuracy in these same system components.
We will use this apparatus as a t estbed for future evolution, enabling us to approximate error introduced by new components such as Optical Tracking Systems and true 2D-3D registration.
5. Conclusion
1. System
This section is a brief conclusion of the system components and interactions of this first generation solution, encompassing some of the gross component limitations.
Pre-operatively, Slicer has proved to be a good choice for visualization and planning. It is relatively fast-rendering, and includes functionality that may assist the surgeon’s ability to plan, such as opacity manipulations. New functionality like path planning was added as a module. At this point, the two most annoying aspects have been its unusual lust for memory, and the fact that the rendering package operates in its own coordinate system, different from the coordinate system of the CT volume itself.
Intra-operatively, from an image-processing standpoint, Microsoft Foundation Classes (MFC) have been most useful. We have been able to enhance the functionality of existing software to tailor the application capabilities to our system needs. Using MFC offers the ease of use and seemlessness of a true Windows application, and is fairly intuitive to program. Of course, planning the architecture of a truly effective graphical interface has proven to be difficult, given the range of tools at our fingertips, and the amount of data we juggle from so many sources.
Robotically, the Neuromate appears at first to be an ideal solution. It is even equipped with a driver that looks to be easily adapted to our purposes of cannula guiding. However, it has limitations. New joint-level control was recently added, and its server was having difficulty communicating serially. Also, the Neuromate has an incomplete workspace, meaning that it may not be able to reach certain points we ask it to reach. This is a huge drawback, considering the current level of pelvic rigidity required for registrations.
Other apparatus components have not been a problem yet. Although we have not obtained a cannula, or a dummy registration cannula, these are expected to be standard and easily obtained; we have aproximate dimensions that will serve for now. The pelvic phantom is a plastic box originally designed to be CT and MRI compatible. Unfortunately, we learned that structural pieces of the box (i.e., struts) are radio-opaque, which presents no practical problems, but is aesthetically undesirable when viewing images.
2. Problems
We met with predictable organizational challenges that included the administrative complexity of getting on Dr. Frassica’s busy calendar. We did a reasonable job of compensating for this delay by developing other components not requiring his immediate input. Additionally, there was sometimes considerable delay in gaining access to the Neuroradiology CT scanner that Mr. Vince Lerie was gracious enough to use for imaging of our pelvises.
The Slicer interface is a powerful environment for manipulating volumetric datasets such as ours; its extensibility has generated a kind of chaos in the variety of modules offered, and Attila Tanacs is doing an admirable job of streamlining this application. Nevertheless, generating functional Tcl/Tk code fulfilling the desired functions involved jumping through some arbitrary Slicer hoops that will hopefully disappear soon.
Problems encountered in developing the image-processing and registration package were expected. One initial problem was the fact that we had no experience with MFC. After experimenting with MFC code, however, the issue became one of how best to integrate CIS code from many sources. Graciously supplied with packages for Finding Fiducials and Background Correction and 2D-3D Registration, our job was to compile varied functionality into an MFC application for viewing and manipulating images. Fortunately, the foundation was in place, and the choices for arranging components and such were intuitive.
We met some problems when we tried to get the MRC server to communicate with the Neuromate server. MRC commands were sent over a RS-232 serial connection to the Neuromate serial server, but Neuromate did not respond. We found that although the Neuromate server received the message from MRC by serial port, the format by which it retrieves commands from the serial buffer is not the same as the format by which MRC constructs the command. Therefore, it cannot recognize these commands, and it cannot respond correctly. Adam Morris, who is responsible for the Neuromate server interface software, helped us to check and update the command format to make it functional.
Another limitation that we discovered in the Neuromate robot is that its worspace is incomplete. Accordingly, positions that would seem to be contained in Neuromate’s workspace may not be reachable because of specific joint limitations.
3. Accomplished Goals vs. Planned Goals
As a consequence of the variety of obstacles encountered, we have not yet implemented a complete solution. Macroscopically, the project can be divided into two phases – (1) the completion of the multiple project components outlined above, and (2) the integration of these components into a complete, testable solution. We have successfully assembled all of the components necessary to implement our solution; some of these components were imported from existing CIS software, some components represent modifications of existing CIS software and some components have been developed afresh. The components can be divided as follows::
A. Pre-Operative Modeling and Trajectory Planning Software – developed afresh on Slicer platform
B. Intra-Operative Image Processing Software – modified J. Yao’s dewarping and fiducial finding software
C. Intra-Operative Registration Software – imported Bhargava, et. Al., 2D-3D registration software and developed robot registration software afresh.
D. Robot Control Software – modified existing MRC software
These components are functioning reasonably well in isolation and what remains is to integrate the system components into a single, cooperative application that performs the desired tasks accurately. To assure this, we will have to test the integrated system on phantoms with redundant groundtruth metrics to allow accuracy determination.
If we accomplish this last intergration and testing phase, then we will have achieved all of the goals planned for this first generation solution.
4. Future Considerations
As described in the Introduction, section 1.3, there are a few constraints and assumptions that we instituted in an effort to realize a crude, but complete first generation system. Surmounting these constraints is fertile ground for future evolution.
a. True 2D-3D Registration
Incorporation of fiducial-free 2D-3D registration algorithms would obviate the need for pre-imaging fiducial placement. This is an unnecessarily invasive pre-operative procedure that increases cost, time and patient discomfort; moreover, the patient is exposed to increased risks associated with this additional procedure.
b. Component Tracking
Incorporation of intra-operative optical or magnetic tracking systems would allow real-time component tracking, making the experimental apparatus more realistic. This would allow the pelvis to be tracked in real-time, allowing the robot to compensate its trajectory guidance to maintain a fixed cannula orientation with respect to the moving pelvis. Moreover, rigid bodies could be placed and calibrated on surgical instruments used such as drills, cannulas and evacuation microinstruments to allow intra-operative tracking and monitoring/guidance.
c. Robotic Cannula Insertion
Employment of Active Robots capable of inserting the cannula might increase consistency and accuracy of cannula placement and allow better control of the cannula in a non-static surgical environment.
d. Alternative Surgical Settings
The surgical system developed for pelvic Osteolysis has vast potential in a variety of Orthopedic interventions and in interventions within other surgical disciplines. The utility of this apparatus in other settings is largely dependent on the surgical instruments developed for passage through the cannula. With continued evolution, this apparatus promises to be invoked in a variety of minimally invasive surgical interventions with well-definable targets.
6. Management Summary
1. Division of Labor
□ Apparatus Construction: Nick and Srini
□ Pre-Operative Modeling and Trajectory Planning Software: Srini
□ Intra-Operative Image Processing Software: Nick
□ Intra-Operative Registration Software: Srini and Nick
□ Robot Control Software: Ming
□ Coordinating Clinical Interaction: Srini
2. Acknowledgements
We have enjoyed the support and guidance of a number of people without whom this project would not have gotten off the ground. We would especially like to thank the following people:
□ Dr. Russell H. Taylor, Ph. D.
□ Dr. Frank Frassica, MD
□ Dr. James Wenz, MD
□ Andy Bzostek
□ Jianhua Yao
□ Rajesh Kumar
□ Attila Tanacs
□ Ankur Bhargava, Sean Hundtofte and Mark Thober
□ Adam Morris
□ Sheng Xu
□ Vince Lerie
□ Anton Denuet
Appendix A: Source Code
A. Slicer Interface – “Osteolysis” Module [Tcl/Tk] : Osteolysis.tcl
###################
# Surgeon GUI for Osteolysis Trajectory Planning and Fiducial Finding
#
# FILE: Osteolysis.tcl
# PROCEDURES:
# OsteolysisInit
# OsteolysisEnter
# OsteolysisExit
# OsteolysisBuildVTK
# OsteolysisBuildGUI
# OsteolysisShiftB1Release
# OsteolysisSetTargetPosition
# OsteolysisSetTargetVisibility
# OsteolysisSetActiveTarget
# OsteolysisViewCannula
# OsteolysisFindFiducials
# OsteolysisSave
#
#
###################
#-----------------------------------------
# .PROC OsteolysisInit
#
# .ARGS
# .END
#-----------------------------------------
proc OsteolysisInit {} {
global Osteolysis Module
### Define Tabs ###
set m Osteolysis
set Module($m,row1List) "Help Trajectory Fiducials"
set Module($m,row1Name) "{Help} {Trajectory} {Fiducials}"
set Module($m,row1,tab) Trajectory
### Define Procedures ###
set Module($m,procGUI) OsteolysisBuildGUI
set Module($m,procVTK) OsteolysisBuildVTK
set Module($m,procEnter) OsteolysisEnter
set Module($m,procExit) OsteolysisExit
### Define Dependencies ###
set Module($m,depend) ""
### Set Version Info ###
lappend Module(versions) [ParseCVSInfo $m \
{$Revision: 1.0 $} {$Date: 2001/03/30 17:15:30 $}]
### Initialize Module-Level variables ###
set Osteolysis(idList) "0 1"
set Osteolysis(0,name) Origin
set Osteolysis(0,diffuseColor) "1 1 0"
set Osteolysis(0,x) 0
set Osteolysis(0,y) 0
set Osteolysis(0,z) 0
set Osteolysis(0,xRas) 0
set Osteolysis(0,yRas) 0
set Osteolysis(0,zRas) 0
set Osteolysis(0,visibility) 0
set Osteolysis(0,radius) 4
set Osteolysis(0,focalPoint) 0
set Osteolysis(1,name) Pelvis
set Osteolysis(1,diffuseColor) "1 0 0"
set Osteolysis(1,x) 0
set Osteolysis(1,y) 0
set Osteolysis(1,z) 0
set Osteolysis(1,xRas) 0
set Osteolysis(1,yRas) 0
set Osteolysis(1,zRas) 0
set Osteolysis(1,visibility) 0
set Osteolysis(1,radius) 4
set Osteolysis(1,focalPoint) 0
set Osteolysis(active0) 1
set Osteolysis(active1) 0
set Osteolysis(focalPoint) 0
set Osteolysis(visibility) 0
set Osteolysis(xStr) ""
set Osteolysis(yStr) ""
set Osteolysis(zStr) ""
set Osteolysis(can,radius) 4
set Osteolysis(can,visibility) 0
set Osteolysis(can,diffuseColor) "0 0 1"
set Osteolysis(can,opacity) 1
set Osteolysis(num_cannula_sides) 16
set Osteolysis(ctPoints,nCount) 0
set Osteolysis(portNum) 3
set Osteolysis(threshold) 2000
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisEnter
# Called when this module is entered by the user. Pushes the event manager
# for this module.
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisEnter {} {
global Osteolysis
# Push event manager
#------------------------------------
# Description:
# So that this module's event bindings don't conflict with other
# modules, use our bindings only when the user is in this module.
# The pushEventManager routine saves the previous bindings on
# a stack and binds our new ones.
# (See slicer/program/tcl-shared/Events.tcl for more details.)
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisExit
# Called when this module is exited by the user. Pops the event manager
# for this module.
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisExit {} {
# Pop event manager
#------------------------------------
# Description:
# Use this with pushEventManager. popEventManager removes our
# bindings when the user exits the module, and replaces the
# previous ones.
#
}
#-----------------------------------------
# .PROC OsteolysisBuildVTK
#
# .ARGS
# .END
#-----------------------------------------
proc OsteolysisBuildVTK {} {
global Osteolysis
vtkTrajectory Osteolysis(vtkTraj)
### Targets ###
set Osteolysis(activeID) [lindex $Osteolysis(idList) 0]
foreach t $Osteolysis(idList) {
MakeVTKObject Sphere Osteolysis(cantarget$t)
Osteolysis(cantarget${t})Source SetRadius $Osteolysis($t,radius)
eval [Osteolysis(cantarget${t})Actor GetProperty] SetColor Osteolysis($t,diffuseColor)
Osteolysis(cantarget${t})Actor SetVisibility $Osteolysis($t,visibility)
}
### Cannula ###
vtkLineSource Osteolysis(canline)
Osteolysis(canline) SetPoint1 $Osteolysis(0,x) $Osteolysis(0,y) $Osteolysis(0,z)
Osteolysis(canline) SetPoint2 $Osteolysis(1,x) $Osteolysis(1,y) $Osteolysis(1,z)
vtkTubeFilter Osteolysis(cannula)
Osteolysis(cannula) SetInput [Osteolysis(canline) GetOutput]
Osteolysis(cannula) SetRadius $Osteolysis(can,radius)
Osteolysis(cannula) SetNumberOfSides $Osteolysis(num_cannula_sides)
vtkPolyDataMapper Osteolysis(canmapper)
Osteolysis(canmapper) SetInput [Osteolysis(cannula) GetOutput]
vtkActor Osteolysis(canactor)
Osteolysis(canactor) SetMapper Osteolysis(canmapper)
eval [Osteolysis(canactor) GetProperty] SetColor $Osteolysis(can,diffuseColor)
Osteolysis(canactor) SetVisibility $Osteolysis(can,visibility)
eval [Osteolysis(canactor) GetProperty] SetOpacity $Osteolysis(can,opacity)
MainAddActor Osteolysis(canactor)
}
#-----------------------------------------
# .PROC OsteolysisBuildGUI
#
# .ARGS
# .END
#-----------------------------------------
proc OsteolysisBuildGUI {} {
global Gui Osteolysis Osteolysis Module
set texts "RL PA IS"
set axi "X Y Z"
#-------------------------------------------
# Frame Hierarchy:
#-------------------------------------------
# Help
# Trajectory
# Targets
# Top
# Active
# Bottom
# Vis
# Title
# Pos
# Cannula
# Vis
# Features
# Opacity
# Radius
# Save
# Fiducials
# Finder
# Coordinates
#
#-------------------------------------------
#-------------------------------------------
# Help frame
#-------------------------------------------
set help ""
#-------------------------------------------
# Trajectory frame
#-------------------------------------------
set fTrajectory $Module(Osteolysis,fTrajectory)
set f $fTrajectory
frame $f.fTargets -bg $Gui(activeWorkspace) -relief groove -bd 3
frame $f.fCannula -bg $Gui(activeWorkspace) -relief groove -bd 3
frame $f.fSave -bg $Gui(activeWorkspace) -relief groove -bd 3
pack $f.fTargets $f.fCannula $f.fSave \
-side top -padx $Gui(pad) -pady 2 -fill x
#-------------------------------------------
# Trajectory->Targets
#-------------------------------------------
set f $fTrajectory.fTargets
eval {label $f.l -text "TARGETS"} $Gui(WTA)
frame $f.fTop -bg $Gui(backdrop) -relief sunken -bd 2
frame $f.fBot -bg $Gui(activeWorkspace) -height 150
pack $f.l $f.fTop $f.fBot -side top -pady 2 -padx $Gui(pad) -fill x
#-------------------------------------------
# Trajectory->Targets->Top frame
#-------------------------------------------
set f $fTrajectory.fTargets.fTop
frame $f.fActive -bg $Gui(backdrop)
pack $f.fActive -side top -pady 2
#-------------------------------------------
# Trajectory->Targets->Top->Active frame
#-------------------------------------------
set f $fTrajectory.fTargets.fTop.fActive
eval {label $f.lActive -text "Active Target:"} $Gui(BLA)
frame $f.fActive -bg $Gui(activeWorkspace)
foreach mode "0 1" name "Origin Pelvis" {
eval {checkbutton $f.fActive.c$mode \
-text "$name" -variable Osteolysis(active$mode) -width 7 \
-indicatoron 0 -command "OsteolysisSetActiveTarget $mode; Render3D"} $Gui(WCA)
pack $f.fActive.c$mode -side left -padx 0
}
pack $f.lActive $f.fActive -side left -padx $Gui(pad)
#-------------------------------------------
# Trajectory->Targets->Bot frame
#-------------------------------------------
set f $fTrajectory.fTargets.fBot
frame $f.fVis -bg $Gui(activeWorkspace)
frame $f.fTitle -bg $Gui(activeWorkspace)
frame $f.fPos -bg $Gui(activeWorkspace)
frame $f.fButtons -bg $Gui(activeWorkspace)
pack $f.fVis $f.fTitle $f.fPos $f.fButtons \
-side top -padx $Gui(pad) -pady 2
#-------------------------------------------
# Trajectory->Targets->Bot->Vis frame
#-------------------------------------------
set f $fTrajectory.fTargets.fBot.fVis
# Visibility
eval {checkbutton $f.cTarget \
-text "Show Target" -variable Osteolysis(visibility) -width 18 \
-indicatoron 0 -command "OsteolysisSetTargetVisibility; Render3D"} $Gui(WCA)
pack $f.cTarget -pady 2
#-------------------------------------------
# Trajectory->Targets->Bot->Title frame
#-------------------------------------------
set f $fTrajectory.fTargets.fBot.fTitle
eval {label $f.l -text "Target Position"} $Gui(WTA)
pack $f.l
#-------------------------------------------
# Trajectory->Targets->Bot->Pos frame
#-------------------------------------------
set f $fTrajectory.fTargets.fBot.fPos
# Position Sliders
foreach slider $axi text $texts {
eval {label $f.l${slider} -text "$text:"} $Gui(WLA)
eval {entry $f.e${slider} \
-textvariable Osteolysis([Uncap ${slider}]Str) -width 7} $Gui(WEA)
bind $f.e${slider} \
"OsteolysisSetTargetPosition $slider; Render3D"
bind $f.e${slider} \
"OsteolysisSetTargetPosition $slider; Render3D"
eval {scale $f.s${slider} -from 0 -to 500 -length 120 \
-variable Osteolysis([Uncap ${slider}]Str) \
-command "OsteolysisSetTargetPosition $slider; Render3D" \
-resolution .01} $Gui(WSA)
}
# Grid
grid $f.lX $f.eX $f.sX -padx $Gui(pad) -pady 1
grid $f.lX -sticky e
grid $f.lY $f.eY $f.sY -padx $Gui(pad) -pady 1
grid $f.lY -sticky e
grid $f.lZ $f.eZ $f.sZ -padx $Gui(pad) -pady 1
grid $f.lZ -sticky e
#-------------------------------------------
# Trajectory->Cannula frame
#-------------------------------------------
set f $fTrajectory.fCannula
eval {label $f.l -text "CANNULA"} $Gui(WTA)
frame $f.fVis -bg $Gui(activeWorkspace)
frame $f.fFeatures -bg $Gui(activeWorkspace)
pack $f.l $f.fVis $f.fFeatures -side top -pady 2 -padx $Gui(pad) -fill x
#-------------------------------------------
# Trajectory->Cannula->Vis frame
#-------------------------------------------
set f $fTrajectory.fCannula.fVis
# Visibility
eval {checkbutton $f.cTrajectory \
-text "View Cannula" -variable Osteolysis(can,visibility) -width 18 \
-indicatoron 0 -command "OsteolysisViewCannula; Render3D"} $Gui(WBA)
pack $f.cTrajectory \
-side top -pady 2 -padx 0
#-------------------------------------------
# Trajectory->Cannula->Features frame
#-------------------------------------------
set f $fTrajectory.fCannula.fFeatures
## Feature Sliders ##
# Opacity #
eval {label $f.lopac -text "Opacity:"} $Gui(WLA)
eval {entry $f.eopac -textvariable Osteolysis(can,opacity) -width 7} $Gui(WEA)
bind $f.eopac \
"OsteolysisViewCannula; Render3D"
bind $f.eopac \
"OsteolysisViewCannula; Render3D"
eval {scale $f.sopac -from 0 -to 1 -length 80 \
-variable Osteolysis(can,opacity) \
-command "OsteolysisViewCannula; Render3D" \
-resolution .05} $Gui(WSA)
# Radius #
eval {label $f.lrad -text "Radius:"} $Gui(WLA)
eval {entry $f.erad -textvariable Osteolysis(can,radius) -width 7} $Gui(WEA)
bind $f.erad \
"OsteolysisViewCannula; Render3D"
bind $f.erad \
"OsteolysisViewCannula; Render3D"
eval {scale $f.srad -from 0 -to 10 -length 80 \
-variable Osteolysis(can,radius) \
-command "OsteolysisViewCannula; Render3D" \
-resolution .5} $Gui(WSA)
# Grid
grid $f.lopac $f.eopac $f.sopac -padx $Gui(pad) -pady 1
grid $f.lopac -sticky e
grid $f.lrad $f.erad $f.srad -padx $Gui(pad) -pady 1
grid $f.lrad -sticky e
#-------------------------------------------
# Trajectory->Save frame
#-------------------------------------------
set f $fTrajectory.fSave
eval {label $f.l -text "TRAJECTORY"} $Gui(WTA)
eval {button $f.bSave -text "Save Trajectory" \
-command "OsteolysisSave"} $Gui(WBA)
pack $f.l $f.bSave -side top -pady 3 -padx $Gui(pad)
#-------------------------------------------
# Fiducials frame
#-------------------------------------------
set fFiducials $Module(Osteolysis,fFiducials)
set f $fFiducials
frame $f.fFinder -bg $Gui(activeWorkspace) -relief groove -bd 3
frame $f.fCoordinates -bg $Gui(activeWorkspace) -relief groove -bd 3
pack $f.fFinder $f.fCoordinates \
-side top -padx $Gui(pad) -pady 4 -fill x
#-------------------------------------------
# Fiducials->Finder frame
#-------------------------------------------
set f $fFiducials.fFinder
eval {label $f.l -text "FIDUCIAL SEGMENTATION"} $Gui(WTA)
frame $f.fParams -bg $Gui(activeWorkspace)
frame $f.fFindFid -bg $Gui(activeWorkspace)
pack $f.l $f.fParams $f.fFindFid -side top -pady 4 -padx $Gui(pad) -fill x
#-------------------------------------------
# Fiducials->Finder->Params frame
#-------------------------------------------
set f $fFiducials.fFinder.fParams
## Parameters ##
# Threshold #
DevAddLabel $f.lThreshold "Threshold:"
eval {entry $f.eThreshold -textvariable Osteolysis(threshold) -width 8} $Gui(WEA)
# Port Number #
DevAddLabel $f.lPortNumber "Port Number:"
eval {entry $f.ePortNumber -textvariable Osteolysis(portNum) -width 8} $Gui(WEA)
# Grid
grid $f.lThreshold $f.eThreshold -padx $Gui(pad) -pady 2
grid $f.lThreshold -sticky e
grid $f.lPortNumber $f.ePortNumber -padx $Gui(pad) -pady 2
grid $f.lPortNumber -sticky e
#-------------------------------------------
# Fiducials->Finder->FindFid frame
#-------------------------------------------
set f $fFiducials.fFinder.fFindFid
# Find Fiducials
eval {button $f.bSave -text "Find Fiducials" \
-command "OsteolysisFindFiducials"} $Gui(WBA)
pack $f.bSave -side top -pady 3 -padx $Gui(pad)
#-------------------------------------------
# Fiducials->Coordinates frame
#-------------------------------------------
set f $fFiducials.fCoordinates
eval {label $f.l -text "FIDUCIAL COORDINATES"} $Gui(WTA)
set Osteolysis(FidTextBox) [ScrolledText $f.tText]
pack $f.l $f.tText -side top -pady $Gui(pad) -padx $Gui(pad) \
-fill x -expand true
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisShiftB1Release
# Handles what happens when the left mouse button is released
# over a slice: selecting markers, target and entry points,
# and points for calibration.
# Called from MainInteractor.tcl proc MainInteractorB1Release
# .ARGS
# x x slice coordinate
# y y slice coordinate
# .END
#-------------------------------------------------------------------------------
proc OsteolysisShiftB1Release { x y } {
global Osteolysis Volume
# Get IJK coordinates
set s [Slicer GetActiveSlice]
Slicer SetReformatPoint $s $x $y
scan [Slicer GetIjkPoint] "%g %g %g" xIjk yIjk zIjk
scan [Volume($Volume(activeID),node) GetSpacing] "%g %g %g" resx resy resz
set x [expr $resx * $xIjk]
set y [expr $resy * $yIjk]
set z [expr $resz * $zIjk]
set Osteolysis(xStr) [format "%.2f" $x]
set Osteolysis(yStr) [format "%.2f" $y]
set Osteolysis(zStr) [format "%.2f" $z]
eval [OsteolysisSetTargetPosition 0]
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisSetTargetPosition
# 'value' comes from the sliders, but is unused here.
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisSetTargetPosition {{value ""}} {
global Volume Osteolysis
if {[ValidateFloat $Osteolysis(xStr)] == 0} {
tk_messageBox -message "LR is not a floating point number."
return
}
if {[ValidateFloat $Osteolysis(yStr)] == 0} {
tk_messageBox -message "PA is not a floating point number."
return
}
if {[ValidateFloat $Osteolysis(zStr)] == 0} {
tk_messageBox -message "IS is not a floating point number."
return
}
set t $Osteolysis(activeID)
set Osteolysis($t,x) $Osteolysis(xStr)
set Osteolysis($t,y) $Osteolysis(yStr)
set Osteolysis($t,z) $Osteolysis(zStr)
set ijk2ras [Volume($Volume(activeID),node) GetPosition]
scan [Osteolysis(vtkTraj) TransformPoint $ijk2ras $Osteolysis($t,x) $Osteolysis($t,y) $Osteolysis($t,z)] "%g %g %g" Osteolysis($t,xRas) Osteolysis($t,yRas) Osteolysis($t,zRas)
Osteolysis(cantarget${t})Actor SetPosition $Osteolysis($t,xRas) $Osteolysis($t,yRas) $Osteolysis($t,zRas)
OsteolysisViewCannula
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisSetTargetVisibility
# Toggles active target visibility
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisSetTargetVisibility {} {
global Osteolysis
set t $Osteolysis(activeID)
set Osteolysis($t,visibility) $Osteolysis(visibility)
Osteolysis(cantarget${t})Actor SetVisibility $Osteolysis($t,visibility)
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisSetActiveTarget
# Sets active target
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisSetActiveTarget {{t ""}} {
global Osteolysis
if {$t == ""} {
set t $Osteolysis(activeID)
} else {
set Osteolysis(activeID) $t
}
# Change button status
set Osteolysis(active0) 0
set Osteolysis(active1) 0
set Osteolysis(active$t) 1
set Osteolysis(visibility) $Osteolysis($t,visibility)
foreach param "x y z" {
set Osteolysis(${param}Str) [format "%.2f" $Osteolysis($t,$param)]
}
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisViewCannula
# Toggles cannula visibility
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisViewCannula {} {
global Osteolysis
Osteolysis(canline) SetPoint1 $Osteolysis(0,xRas) $Osteolysis(0,yRas) $Osteolysis(0,zRas)
Osteolysis(canline) SetPoint2 $Osteolysis(1,xRas) $Osteolysis(1,yRas) $Osteolysis(1,zRas)
Osteolysis(cannula) SetRadius $Osteolysis(can,radius)
eval [Osteolysis(canactor) GetProperty] SetOpacity $Osteolysis(can,opacity)
Osteolysis(canactor) SetVisibility $Osteolysis(can,visibility)
}
#-------------------------------------------------------------------------------
# .PROC OsteolysisFindFiducials
# Extracts CT Fiducial coordinates for future registration.
# Stores results in mm units within CT space coordinates
# .ARGS
# .END
#-------------------------------------------------------------------------------
proc OsteolysisFindFiducials {} {
global Volume Osteolysis
set outputfile [open p:/CIS2_Project/Data/CTfidCoord.txt w+]
puts $outputfile "CT Fiducial Coordinates: \n"
set num $Osteolysis(ctPoints,nCount)
for {set i 0} {$i < $num} {incr i} {
unset Osteolysis(ctPoints,$i)
}
scan [Volume($Volume(activeID),node) GetSpacing] "%g %g %g" resx resy resz
vtkImageLabel ImgLabel
ImgLabel SetInput [Volume($Volume(activeID),vol) GetOutput]
ImgLabel ThresholdByUpper $Osteolysis(threshold)
[ImgLabel GetOutput] Update
set num [ImgLabel GetSegmentNum]
set Osteolysis(ctPoints,nCount) $num
for {set i 0} {$i < $num} {incr i} {
set x [ImgLabel GetCenter $i 0]
set y [ImgLabel GetCenter $i 1]
set z [ImgLabel GetCenter $i 2]
set Osteolysis(ctPoints,$i) "$i: $x, $y, $z"
## File output in mm coordinates ##
set x_mm [expr $x * $resx]
set y_mm [expr $y * $resy]
set z_mm [expr $z * $resz]
puts $outputfile "$i: $x_mm, $y_mm, $z_mm"
set insertText "$i: $x_mm, $y_mm, $z_mm \n"
$Osteolysis(FidTextBox) insert end $insertText
}
close $outputfile
}
#----------------------------------------------------------------------------
# .PROC OsteolysisSave
# Saves the Trajectory endpoint coordinates in specific file (mm units)
# .ARGS
# .END
#----------------------------------------------------------------------------
proc OsteolysisSave {} {
global Volume Osteolysis
set outputfile [open p:/CIS2_Project/Data/TrajectoryCoord.txt w+]
puts $outputfile "Trajectory Coordinates: "
## File output in mm coordinates ##
puts $outputfile "Origin: $Osteolysis(0,x), $Osteolysis(0,y), $Osteolysis(0,z)"
puts $outputfile "Target: $Osteolysis(1,x), $Osteolysis(1,y), $Osteolysis(1,z)"
close $outputfile
B. Fiducial Finding Code – [ Visual C++ ] : CIS_Image_Process_Algo_Bead_Detection.cpp
#include "stdafx.h"
#include
#ifdef USE_MIL_LIBRARY
#include
#endif
#include
#include
#include
#include
// this algo is used to extract the beads from the image
// this routine is not a in-place operation, we need an output file
//
template
CIS_ImageErrorCode
CIS_IPA_BeadDetection(CIS_Array_Image2D *im,
int apprRadius, int beadDensity, int OuterColor, int diffTh,
int beadNum, double *beads_x, double *beads_y, int *beadGot)
{
int rows = im->Num_Rows();
int cols = im->Num_Cols();
int i,j,m,n,currInd,currMN,k;
int sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8, sumG;
int sub1, sub2, sub3, sub4, sub5, sub6, sub7, sub8;
int currGray;
int* Out;
_DATA_REP_IM2D_* array=im->GetArray();
Out = (int *)calloc(rows*cols, sizeof(int));
// apply the some user defined bead template onto the image
// here we use two templates, and combine both results together
// here we assume apprRadius = 3
// 1. the first is as follow
// 1 1 1 4 3 3 3
// 1 1 2 4 4 3 3
// 1 2 2 4 4 4 3
// 2 2 2 0 6 6 6
// 7 8 8 8 6 6 5
// 7 7 8 8 6 5 5
// 7 7 7 8 5 5 5
// here we divide the template into eight regions, the region with even number
// are those areas of the bead, the region with odd number are the background area
// the background region should have higher grayscale than the bead regions
//
// 2. the second template
// 1 1 1
// 1 1 1
// 1 1 1
// -1-1-1
// -1-1-1
// 1 1 1-1-1-1-1-1-1-1 1 1 1
// 1 1 1-1-1-1 0-1-1-1 1 1 1
// 1 1 1-1-1-1-1-1-1-1 1 1 1
// -1-1-1
// -1-1-1
// 1 1 1
// 1 1 1
// 1 1 1
//
// the region numbered with -1 are the bead, the regions numbered with 1 are
// the background
for(i=2*apprRadius+1; i ................
................
In order to avoid copyright disputes, this page is only a partial summary.
To fulfill the demand for quickly locating and searching documents.
It is intelligent file search solution for home and business.
Related searches
- minimally invasive back surgery
- minimally invasive open heart surgery
- minimally invasive cervical spine surgery
- unc minimally invasive gynecologic surgery
- minimally invasive spinal surgery
- minimally invasive spine
- best minimally invasive spine surgery
- minimally invasive lumbar spine surgery
- minimally invasive lower back surgery
- unc minimally invasive gyn
- minimally invasive gynecology
- minimally invasive gyn surgery society