From d6922c79feb99961fce1c93bc750978a151c80b8 Mon Sep 17 00:00:00 2001 From: ashmeigh Date: Tue, 3 Dec 2024 13:21:51 +0000 Subject: [PATCH 1/2] added better explaintions of COR and tilt --- .../reconstructions/center_of_rotation.rst | 76 +++++++++++++------ 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/docs/user_guide/explanations/reconstructions/center_of_rotation.rst b/docs/user_guide/explanations/reconstructions/center_of_rotation.rst index a59e6bc9619..a7ca9b8732b 100644 --- a/docs/user_guide/explanations/reconstructions/center_of_rotation.rst +++ b/docs/user_guide/explanations/reconstructions/center_of_rotation.rst @@ -3,7 +3,7 @@ Center of Rotation and Tilt =========================== -Center of Rotation (COR) and Tilt usage +Center of Rotation (COR) and Tilt Usage --------------------------------------- The correct center of rotation is required for a good reconstruction. @@ -12,32 +12,63 @@ However, sometimes the values they find are not accurate, so there is also a man to adjust the center of rotation. The algorithms used for reconstruction require a COR for each sinogram, -i.e. a list of CORs equal to the number of sinograms (also equal to the number of rows in a projection). -This is abstracted away and the two final values that are used are: center of rotation and tilt. +i.e., a list of CORs equal to the number of sinograms (also equal to the number of rows in a projection). +This is abstracted away, and the two final values that are used are: center of rotation and tilt. -In that case the COR refers to the value at sinogram 0 (also referred to as slice 0). -Using the tilt we then use a linear regression to calculate the COR for each sinogram in the data. +In that case, the COR refers to the value at sinogram 0 (also referred to as slice 0). +Using the tilt, we then use a linear regression to calculate the COR for each sinogram in the data. +What is the Center of Rotation (COR)? +------------------------------------- -Entering known COR and tilt +The **Center of Rotation (COR)** is a reference point that defines the axis around which the object rotates +during image acquisition in tomography. It is the midpoint of the rotational axis when looking at +a slice of the data (a sinogram). + +Why COR Matters: + - If the COR is incorrect, the projections will not align correctly during reconstruction, + leading to artifacts and blurred images. + - COR is specific for each sinogram (i.e., each slice of the object being scanned). + +How COR is Used: + - For accurate reconstruction, the COR for the first sinogram (sinogram 0, also called slice 0) is determined. + - Using the **Tilt** parameter, CORs for subsequent sinograms are calculated through a linear adjustment. + +What is Tilt? +------------- + +**Tilt** describes the gradual change in the COR along the axis perpendicular to the rotation plane +(typically corresponding to the rows in a projection). It reflects any misalignment or non-uniformity +in the system during the acquisition of the sinograms. + +Why Tilt Matters: + - Tilt accounts for the variation in COR values across sinograms due to physical or mechanical imperfections. + - Without considering tilt, the reconstructed slices may not align correctly, causing distortions or streaking artifacts. + +How Tilt is Used: + - Tilt is measured as the rate of change of COR across the sinograms. + - With the known COR of the first sinogram and the tilt value, the COR for every sinogram + is interpolated or extrapolated. + +Entering Known COR and Tilt --------------------------- -If the COR and tilt are already known you can enter them in the "Enter known COR/Tilt manually here" section -and press "Use COR/Tilt values from above". In this case you can go immediately to reconstruction. +If the COR and tilt are already known, you can enter them in the "Enter known COR/Tilt manually here" section +and press "Use COR/Tilt values from above." In this case, you can go immediately to reconstruction. Correlate 0 and 180 ------------------- This automatic COR algorithm finds the shift between the projections at 0 and 180 degrees. -The projection exactly at 180 degrees is necessary for the best result. -We provide the option of loading a 180 degree projection in the load dialog. +The projection exactly at 180 degrees is necessary for the best result. We provide the option +of loading a 180-degree projection in the load dialog. -The algorithm will not run unless a 180 degree projection has been loaded. +The algorithm will not run unless a 180-degree projection has been loaded. This is not a problem and could be rectified either by adding a manual COR or using the minimisation algorithm. -Minimise error +Minimise Error -------------- This automatic COR algorithm uses the square sum of the projection as a noise heuristic. @@ -47,31 +78,30 @@ It does so for a number of sinograms (slices) and adds the result in the COR tab This algorithm may not work well on noisy data or with very bright outliers, as the minimisation can get lost in a local minima and not find the best reconstructed slice. -As the same heuristic is also used in the manual "Refine" window, to highlight +As the same heuristic is also used in the manual "Refine" window to highlight one of the choices as the best, the behaviour can also be seen there. -In this case the best action is to use the correlate as a starting point, -and go immediately to manual COR correction. +In this case, the best action is to use the correlate as a starting point and +go immediately to manual COR correction. -Manual COR correction +Manual COR Correction --------------------- -Due to the limitations of the algorithms above there is also a manual way of calculating the COR - +Due to the limitations of the algorithms above, there is also a manual way of calculating the COR— using the "COR Table - refine manually" part of the GUI. -In that table you can click Add to add a new COR for the currently selected slice. Once added -you can click the row and then "Refine" which will take you -to a window that reconstructs the sinogram with multiple CORs simultaneously, and allows you -to visually pick the best one. +In that table, you can click Add to add a new COR for the currently selected slice. Once added, +you can click the row and then "Refine," which will take you to a window that reconstructs +the sinogram with multiple CORs simultaneously, and allows you to visually pick the best one. After you have two or more CORs in the table, a fit will be performed in order to find the COR and tilt using the data from the table rows. It is sometimes good enough to add a COR at the top of your data and the bottom. Once the best CORs for those are found, the resulting tilt should be accurate. -To increase the accuracy further add more COR rows. +To increase the accuracy further, add more COR rows. -To reconstruction +To Reconstruction ----------------- Once you have a satisfactory value of COR or tilt, you are ready to proceed to the "Reconstruct" tab. From 49d8b63bd2357102a3ffe6152db49b643995f102 Mon Sep 17 00:00:00 2001 From: ashmeigh Date: Mon, 9 Dec 2024 13:00:07 +0000 Subject: [PATCH 2/2] added images and removed redundant info --- docs/_static/cor_bad.png | Bin 0 -> 188638 bytes docs/_static/cor_good.png | Bin 0 -> 189547 bytes .../reconstructions/center_of_rotation.rst | 34 ++++++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 docs/_static/cor_bad.png create mode 100644 docs/_static/cor_good.png diff --git a/docs/_static/cor_bad.png b/docs/_static/cor_bad.png new file mode 100644 index 0000000000000000000000000000000000000000..0ef52b2a06311d256dc20d1cf9f46a6910d42ad3 GIT binary patch literal 188638 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