我有以下情况,我将尽力解释:
我已经完成了一个原型,您可以单击NRRD的线段,然后将三位检测到的坐标转换为IJ坐标系(因为三位的坐标原点系统位于中心,因此我们需要将其位于左上角,是IJ坐标系的原点)。
然后,由于场景中显示的NRRD小于我们从中获取数据的NRRD(对于每个像素,其灰度级为我们提供了有关我们单击的段号的信息),我们需要升级坐标以适合NRRD的原始坐标系统。
首先,我将用图像,计算代码和文字说明工作原型。 其次,我将请求您的帮助,因为我正在尝试将工作原型集成到新界面中,并且行为异常:
如果我们单击左上角,我们将:
归一化坐标:-0.87,0.31,计算公式为:
getMouseCoordinatesNormalizedBetween0and1(canvas) {
let browser = new THREE.Vector2();
browser.x = ( (event.clientX - canvas.getBoundingClientRect().left) /
canvas.width ) * 2 - 1;
browser.y = -( (event.clientY - canvas.getBoundingClientRect().top) /
canvas.height ) * 2 + 1;
console.log('Coordinates retrieved by the browser normalized between 0 and 1', browser.x, browser.y);
return browser;
}
使用三点阵广播恢复的坐标:-147.24,53.79:
getCoordinatesUsingThreeRaycast(browser, sceneManager) {
let raycaster = new THREE.Raycaster();
raycaster.setFromCamera(browser, sceneManager.camera);
const three = raycaster.intersectObjects(sceneManager.scene.children);
if (three[0]) {
console.warn('Coordinates retrieved with THREE: ',
three[0].point.x, three[0].point.y);
browser.x = three[0].point.x;
browser.y = three[0].point.y;
return true;
}
return false
}
IJ系统中的坐标:323.24、48.20,计算公式为:
getCoordinateInIJSystemFromTheOriginalNRRD(mouse) {
const slice = SceneManager.multiVolumeSlice.axial.slices[0];
let rasx = Math.abs((-1 * mouse.x) + (slice.canvas.width / 2));
let rasy = Math.abs(mouse.y - (slice.canvas.height / 2));
console.log('slice.canvas.width', slice.canvas.width,
'slice.canvas.height', slice.canvas.height);
console.log('Coordinate in IJ System', rasx, rasy);
let coordenadas =
SceneManager.multiVolumeSlice.axial.getStructuresAtPosition(rasx, rasy, slice);
console.log('Coordinates converted to the original big NRRD', coordenadas);
return coordenadas;
}
对于这个称为head 1的切片,我们有一个slice.canvas.width = 352和slice.canvas.height = 204
因此,当我们将坐标从3转换为IJ时,要使坐标的原点位于右上角,我们有:
x = -1 * -147.24 + 352/2 = 147.24 + 176 = 323.24
y = 53.79 - 204/2 = 48.21
因此,我们看到手动跟踪为我们提供了与程序相同的结果。
要获取原始NRRD系统中的坐标,我们需要获取其尺寸,磁头1具有:
canvasBuffr.width = 1000,canvasBuffer.height = 580(原始NRRD的尺寸)
这些是通过以下方式计算的:
i = x slice.canvasBuffer.width / slice.canvas.width
j = y slice.canvasBuffer.height / slice.canvas.height
i = 323.24 1000 / 352 = 918
j = 48 580 / 204 = 137
因此,结果与程序给出的值相同。
为帮助您了解为什么要这样做,让我们看一下ITKSnap。考虑到图像的数据是“从右到左”加载的,查看可视图像的方式是“从左到右”。因此,我们需要计算对称的水平点,如您在照片中所见:
--- >>>我试图将这种行为集成到使用另一个接口的应用程序中:
我试图单击同一点(在这种情况下,该点位于右上角,因为图像没有翻转,我的意思是,它是在加载时呈现的):
预期的行为是,如果单击左侧画布上的一个片段,则右侧的相应片段将被着色。
如您在照片中看到的那样,该段未着色:
正在记录的数据是:
归一化坐标:0.29,0.28
使用三个射线投射获得的坐标:100.46,95.85
IJ坐标:276.46、6.14
将IJ坐标转换为NRRDO原始:785,17
点击的细分的索引:0
如果我们进行演算以获取IJ坐标,则由程序计算为:
getCoordinateInIJSystemFromTheOriginalNRRD(coordinatesVector, slice) {
// console.error('Coordenada::IJ from NRRD');
let IJx = Math.abs(coordinatesVector.x + (slice.canvas.width / 2));
console.log('Coordinate::IJx', IJx);
console.log('Coordinate from THREE::', coordinatesVector.x);
console.log('slice.canvas.width ', slice.canvas.width);
let IJy = Math.abs(coordinatesVector.y - (slice.canvas.height / 2));
console.log('Coordinate::IJy', IJy);
console.log('Coordinate from THREE::', coordinatesVector.y);
console.log('slice.canvas.height', slice.canvas.height);
return {IJx, IJy}
}
其中坐标矢量是三个坐标,slice.canvas.width = 352 y slice.canvas.height = 204
x = 100.46 + 352/2 = 100.46 + 176 = 276.46
y = 95.85-204/2 = 6.15
我们看到的与程序给我们的一样:276.46,6.14
->>要转换为原始NRRD系统,我们将其计算为:
getStructuresAtPosition: function (IJx, IJy, slice) {
const i = Math.round(IJx * slice.canvasBuffer.width / slice.canvas.width);
const j = Math.round(IJy * slice.canvasBuffer.height / slice.canvas.height);
console.log('slice.canvasBuffer.width', slice.canvasBuffer.width);
console.log('slice.canvasBuffer.height', slice.canvasBuffer.height);
console.log('slice.canvas.width', slice.canvas.width);
console.log('slice.canvas.height', slice.canvas.height);
console.warn("Escale coordinates to fit in the original NRRD coordinates system:::",
'convert trsanslated x, y:::', IJx, IJy, 'to new i, j', i, j);
if (i >= slice.iLength || i < 0 || j >= slice.jLength || j < 0) {
return undefined;
}
return {i, j};
},
我们有:
i = 276.46 * 1000/352 = 785.39
j = 6.14 * 580/204 = 17.45
如果在ITKSnap中看到该点,则该点在右上角,但与所称水平点的等距水平点不对应:
我得到的结论如下
在第一个原型中,坐标系起作用是因为我们在程序上单击的位置会计算水平的等距点
但是在我们的第二个应用程序中,该点在左侧上方和左侧有些偏移。
我认为可能是不同行为的起源:
在工作的原型中,我们用于计算从三到IJ的转换:
let rasx = Math.abs((-1 * mouse.x) + (slice.canvas.width / 2));
但是在无法很好运行的示例中,代码是:
let IJx = Math.abs(coordinatesVector.x + (slice.canvas.width / 2));
它有一个解释:在第一种情况下,图像是水平翻转的,我们将点移到右上角以获得从数据中点击的片段的索引。
在第二种情况下...嗯...我们只是在x上添加一个值。
您能帮我吗?谢谢。