Skip to content

Commit 95190bf

Browse files
committed
Fix MPR geometry
1 parent 0cc0798 commit 95190bf

4 files changed

Lines changed: 151 additions & 569 deletions

File tree

weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/mpr/OriginalStack.java

Lines changed: 10 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import static org.weasis.dicom.viewer2d.mpr.MprView.Plane.AXIAL;
1313
import static org.weasis.dicom.viewer2d.mpr.VolumeBounds.EPSILON;
14-
import static org.weasis.dicom.viewer2d.mpr.VolumeBounds.needsRectification;
1514

1615
import java.util.ArrayList;
1716
import java.util.List;
@@ -68,7 +67,11 @@ protected DicomImageElement getStartingImage() {
6867
return plane == AXIAL ? getLastImage() : getFirstImage();
6968
}
7069

71-
public GeometryOfSlice getFistSliceGeometry() {
70+
protected DicomImageElement getEndingImage() {
71+
return plane == AXIAL ? getFirstImage() : getLastImage();
72+
}
73+
74+
public GeometryOfSlice getFirstSliceGeometry() {
7275
return fistSliceGeometry;
7376
}
7477

@@ -163,68 +166,6 @@ private void checkSliceParallelism() {
163166
}
164167
}
165168

166-
/**
167-
* Computes the spacing correction factor from the image orientation geometry. This generalizes
168-
* the gantry tilt correction to handle both column and row shear.
169-
*
170-
* @return correction factor to apply to measured slice spacing
171-
*/
172-
double computeSpacingCorrectionFromGeometry() {
173-
GeometryOfSlice geometry = fistSliceGeometry;
174-
if (geometry == null) {
175-
return 1.0;
176-
}
177-
178-
// Get shear components based on plane orientation
179-
double colShear = getColumnShearComponent(geometry.getColumn());
180-
double rowShear = getRowShearComponent(geometry.getRow());
181-
182-
// If no significant shear, no correction needed
183-
if (!needsRectification(colShear) && !needsRectification(rowShear)) {
184-
return 1.0;
185-
}
186-
187-
// Combined shear magnitude
188-
double combinedShear = Math.sqrt(colShear * colShear + rowShear * rowShear);
189-
190-
// The correction factor compensates for the apparent shortening of spacing
191-
// when slices are acquired at an angle
192-
double shearAngle = Math.atan(combinedShear);
193-
return 1.0 / Math.cos(shearAngle);
194-
}
195-
196-
/**
197-
* Gets the column shear component based on the acquisition plane. Column shear represents
198-
* deviation in the slice normal direction.
199-
*/
200-
private double getColumnShearComponent(Vector3d col) {
201-
return switch (plane) {
202-
case AXIAL -> col.z;
203-
case CORONAL -> col.y;
204-
case SAGITTAL -> col.x;
205-
};
206-
}
207-
208-
/**
209-
* Gets the row shear component based on the acquisition plane. Row shear represents deviation
210-
* perpendicular to column shear.
211-
*/
212-
private double getRowShearComponent(Vector3d row) {
213-
return switch (plane) {
214-
case AXIAL -> row.z;
215-
case CORONAL -> row.y;
216-
case SAGITTAL -> row.x;
217-
};
218-
}
219-
220-
private double getPlanRotationComponent(Vector3d row) {
221-
return switch (plane) {
222-
case AXIAL -> row.y();
223-
case CORONAL -> row.z();
224-
case SAGITTAL -> -row.z();
225-
};
226-
}
227-
228169
public double getSliceSpace() {
229170
return sliceSpace;
230171
}
@@ -247,13 +188,13 @@ public boolean equals(Object o) {
247188
return Double.compare(getSliceSpace(), that.getSliceSpace()) == 0
248189
&& isVariableSliceSpacing() == that.isVariableSliceSpacing()
249190
&& Objects.equals(getSourceStack(), that.getSourceStack())
250-
&& Objects.equals(getFistSliceGeometry(), that.getFistSliceGeometry());
191+
&& Objects.equals(getFirstSliceGeometry(), that.getFirstSliceGeometry());
251192
}
252193

253194
@Override
254195
public int hashCode() {
255196
return Objects.hash(
256-
getSourceStack(), getFistSliceGeometry(), getSliceSpace(), isVariableSliceSpacing());
197+
getSourceStack(), getFirstSliceGeometry(), getSliceSpace(), isVariableSliceSpacing());
257198
}
258199

259200
/**
@@ -279,11 +220,6 @@ public VolumeBounds computeVolumeBounds() {
279220
normalizeToPositiveDirection(row);
280221
normalizeToPositiveDirection(col);
281222

282-
// Compute shear factors for potential rectification
283-
double columnShear = getColumnShearComponent(firstGeom.getColumn());
284-
double rowShear = getRowShearComponent(firstGeom.getRow());
285-
double planRotation = getPlanRotationComponent(firstGeom.getRow());
286-
287223
// Get pixel spacing from first image
288224
double pixelSpacing = firstImg.getPixelSize();
289225
double sliceSpacing = getSliceSpace();
@@ -300,32 +236,23 @@ public VolumeBounds computeVolumeBounds() {
300236
origin,
301237
row,
302238
col,
303-
normal,
304-
columnShear,
305-
rowShear,
306-
planRotation);
239+
normal);
307240
case CORONAL ->
308241
new VolumeBounds(
309242
new Vector3i(getWidth(), numSlices, getHeight()),
310243
new Vector3d(pixelSpacing, sliceSpacing, pixelSpacing),
311244
origin,
312245
row,
313246
col,
314-
normal,
315-
columnShear,
316-
rowShear,
317-
planRotation);
247+
normal);
318248
case SAGITTAL ->
319249
new VolumeBounds(
320250
new Vector3i(numSlices, getWidth(), getHeight()),
321251
new Vector3d(sliceSpacing, pixelSpacing, pixelSpacing),
322252
origin,
323253
row,
324254
col,
325-
normal,
326-
columnShear,
327-
rowShear,
328-
planRotation);
255+
normal);
329256
};
330257
}
331258

weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/mpr/VolImageIO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public PlanarImage getSlice(Vector3d volumeCenter) {
242242
int instanceNumber = mprAxis.getSliceIndex();
243243
rawIO.setTag(TagD.get(Tag.InstanceNumber), instanceNumber + 1);
244244

245-
GeometryOfSlice geometry = volume.stack.getFistSliceGeometry();
245+
GeometryOfSlice geometry = volume.stack.getFirstSliceGeometry();
246246
Vector3d thlc = transformPosition(geometry, volumeCenter);
247247
rawIO.setTag(TagD.get(Tag.ImagePositionPatient), new double[] {thlc.x, thlc.y, thlc.z});
248248

0 commit comments

Comments
 (0)