Как программно добавить и провести измерения из макетных данных в Ohif/Cornerstone.js? [закрыто]Javascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Как программно добавить и провести измерения из макетных данных в Ohif/Cornerstone.js? [закрыто]

Сообщение Anonymous »

Я работаю над проектом, основанным на зрителе Ohif. Моя цель состоит в том, чтобы загрузить данные измерения из макетного файла JSON и автоматически нарисовать его на соответствующий срез изображения, когда зритель загружается. Внутри этого крюка я делаю следующее: < /p>
Прочитайте мои данные о измерении. Показывает данные правильно. Тем не менее, аннотация (фактический рисунок PlanarFreeHandroi) не отображается на слое SVG ViewPort. В консоли нет ошибок. SeasurementService.AnnotationTomeasurement и AnnotationManager.Addannotation вручную. Это правильным, или MeasureMerservice.AddMeasurement автоматически обрабатывает рендеринг через его отображения?
В моей текущей реализации используется крюк использования. Есть ли более надежный подход на основе событий (например, прослушивание enums.events.image_rendered), чтобы убедиться, что просмотр будет полностью готов, прежде чем я попытаюсь добавить аннотацию?
Вот соответствующие фрагменты кода и моя макетная структура данных. Любое руководство было бы очень оценено! < /P>

Код: Выделить всё

  const getViewportInfo = useCallback(() => {
return cornerstoneViewportService.getViewportInfo(activeViewportId);
}, [cornerstoneViewportService, activeViewportId]);
const getCurrentImageId = useCallback(() => {
if (!activeViewportId) return null;
const viewportObj = cornerstoneViewportService.getCornerstoneViewport(activeViewportId);
return viewportObj?.getCurrentImageId();
}, [cornerstoneViewportService, activeViewportId]);

if (!dataSource) {
console.error('ViewerLayout: Invalid DataSource');
} else {
servicesManager.services.dataSource = dataSource;
servicesManager.services.getImageIdsForDisplaySet = ds =>
dataSource.getImageIdsForDisplaySet(ds);
}

const customToMeasurementSchema = useCallback(
raw => {
console.log('customToMeasurementSchema', raw);
if (!dataSource?.getImageIdsForDisplaySet || !displaySetService.getDisplaySetByUID) {
return null;
}
const ds = displaySetService.getDisplaySetByUID(raw.displaySetInstanceUID);

if (!ds) {
console.warn(`DisplaySet with UID ${raw.displaySetInstanceUID} not found.`);

return null;
}
const imageIds = dataSource.getImageIdsForDisplaySet(ds) || [];
const imageId = imageIds[raw.frameNumber - 1] || imageIds[0];
const measurementSchema = {
uid: raw.uid,
SOPInstanceUID: raw.SOPInstanceUID,
FrameOfReferenceUID: ds.FrameOfReferenceUID || raw.metadata?.FrameOfReferenceUID,
referenceStudyUID: raw.referenceStudyUID || raw.studyInstanceUID,
referenceSeriesUID: raw.seriesInstanceUID || ds.SeriesInstanceUID,
frameNumber: raw.frameNumber || 1,
displaySetInstanceUID: raw.displaySetInstanceUID,
label: raw.label || '',
displayText: raw.displayText || [],
type: raw.type,
points: raw.points || [],
source: raw.source,
toolName: raw.toolName,
referencedImageId: imageId,
metadata: {
...raw.metadata,
FrameOfReferenceUID: ds.FrameOfReferenceUID || raw.metadata?.FrameOfReferenceUID,
referencedImageId: imageId,
},

data: { [imageId]: raw.data },
selected: raw.selected || false,
textBox: raw.textBox,
};
console.log('customToMeasurementSchema Output:', measurementSchema);
return measurementSchema;
},
[dataSource, displaySetService]
);

const toAnnotationSchema = useCallback((measurement, annotationType) => {
const annotationObj = {
annotationType,
uid: measurement.uid,
imageId: measurement.referencedImageId,
frameNumber: measurement.frameNumber || 1,
visible: true,
handles: {
points: measurement.points.map(([x, y, z]) => ({
x,
y,
world: [x, y, z],
})),
textBox: {
x: measurement.textBox?.worldPosition[0],
y: measurement.textBox?.worldPosition[1],
},
},
textBox: {
x: measurement.textBox?.worldPosition[0],
y: measurement.textBox?.worldPosition[1],
},
style: {
color: 'rgb(0,255,0)',
lineWidth: 3.5,
fill: 'rgba(0,255,0,0.1)',
},
metadata: {
...(measurement.metadata || {}),
FrameOfReferenceUID:
measurement.metadata?.FrameOfReferenceUID || measurement.FrameOfReferenceUID || '',
},
data: measurement.data,
};
console.log('toAnnotationSchema Output:', annotationObj);
return annotationObj;
}, []);

const injectMeasurements = useCallback(
(currentImageId, displayUID, instance, viewportElement) =>  {
console.log('Instance object in injectMeasurements:', instance);
const renderingEngine = getRenderingEngine(renderingEngineId);
if (!renderingEngine) {
console.error('Rendering engine not found in injectMeasurements');
return;
}
const viewport = renderingEngine.getViewport(activeViewportId);
if (!viewport) {
console.error('Viewport not found');
return;
}

const { clientWidth, clientHeight } = viewport.element;
const topLeftWorld = viewport.canvasToWorld([0, 0]);
const bottomRightWorld = viewport.canvasToWorld([clientWidth, clientHeight]);
const center = [
(topLeftWorld[0] + bottomRightWorld[0]) / 2,
(topLeftWorld[1] + bottomRightWorld[1]) / 2,
(topLeftWorld[2] + bottomRightWorld[2]) / 2,
];

const worldWidth = Math.abs(bottomRightWorld[0] - topLeftWorld[0]);
const worldHeight = Math.abs(bottomRightWorld[1] - topLeftWorld[1]);
const dynamicPoints = [
[center[0] - worldWidth * 0.1, center[1] - worldHeight * 0.1, center[2]],
[center[0] + worldWidth * 0.1, center[1] - worldHeight * 0.1, center[2]],
[center[0] + worldWidth * 0.1, center[1] + worldHeight * 0.1, center[2]],
[center[0] - worldWidth * 0.1, center[1] + worldHeight * 0.1, center[2]],
];
console.log('Calculated dynamic points:', dynamicPoints);

const commonProps = {
displaySetInstanceUID: displayUID,
StudyInstanceUID: instance.StudyInstanceUID,
referenceStudyUID: instance.StudyInstanceUID,
referenceSeriesUID: instance.SeriesInstanceUID,
SOPInstanceUID: instance.SOPInstanceUID,
metadata: {
...measurementsMock[0],
FrameOfReferenceUID: instance.FrameOfReferenceUID,
referencedImageId: currentImageId,
data: measurementsMock[0].data,
textBox: measurementsMock[0].textBox,
},
FrameOfReferenceUID: instance.FrameOfReferenceUID,
};
console.log('Common Props before raw assignment (with actual UIDs):', commonProps);

const source = measurementService.getSource('Cornerstone3DTools', '0.1');
const annotationManager = annotation.state.getAnnotationManager();

if (!annotationManager || typeof annotationManager.addAnnotation !== 'function') {
console.error(
'Annotation Manager is not available or addAnnotation method is missing! Cannot inject measurements.'
);
return;
}
const rawTemplate = measurementsMock[0];

measurementsMock.forEach(rawTemplate =>  {
const raw = {
...rawTemplate,
...commonProps,
points: dynamicPoints,
metadata: {
...(rawTemplate.metadata || {}),
...(commonProps.metadata || {}),
},

referencedImageId: currentImageId,
SOPInstanceUID: commonProps.SOPInstanceUID,
FrameOfReferenceUID: commonProps.FrameOfReferenceUID,
referenceSeriesUID: commonProps.referenceSeriesUID,
referenceStudyUID: commonProps.referenceStudyUID,
};
console.log('Raw object for customToMeasurementSchema (after dynamic merge):', raw);

measurementService.annotationToMeasurement(
source,
measurementService.VALUE_TYPES.POLYLINE,
raw,
false
);

let existingAnnotation = annotationManager.getAnnotation(raw.uid);

if (!existingAnnotation) {
console.log('Injecting measurement (no existing annotation found with this UID)');
const annotationObj = toAnnotationSchema(raw, raw.toolName || 'PlanarFreehandROI');
console.log('Eklenecek Annotation FoR:', annotationObj.metadata.FrameOfReferenceUID);

annotationObj.imageId = currentImageId;
console.log(
'Final annotationObj before addAnnotation (full object):',
JSON.stringify(annotationObj, null, 2)
);

const engine = getRenderingEngine(renderingEngineId);
if (!engine) {
console.error(`[ViewerLayout] Geçersiz renderingEngineId: ${renderingEngineId}`);
return;
}
const groupKey = annotationObj.metadata.FrameOfReferenceUID;
annotationManager.addAnnotation(annotationObj, groupKey);
engine.render();
const added = annotationManager.getAnnotation(raw.uid);

if (!added) {
console.error(`Annotation UID ${raw.uid} eklenemedi.`);
}

console.log(
'Annotation retrieved from manager AFTER addAnnotation:',

annotationManager.getAnnotation(raw.uid)
);
} else {
console.log(
`Annotation with UID ${raw.uid} already exists in manager.  Skipping injection.`
);
}
});
},

[measurementService, toAnnotationSchema, renderingEngineId, activeViewportId]
);

useEffect(() => {
const source = measurementService.getSource('Cornerstone3DTools', '0.1');

measurementService.addMapping(
source,
measurementService.VALUE_TYPES.POLYLINE,
{ points: measurementsMock[0].points.length },
toAnnotationSchema,
customToMeasurementSchema
);
}, [measurementService, toAnnotationSchema, customToMeasurementSchema]);

useEffect(() => {
const timeoutId = setTimeout(() => {
const viewportInfo = getViewportInfo();

if (viewportInfo?.renderingEngineId) {
setRenderingEngineId(viewportInfo.renderingEngineId);

console.log('[ViewerLayout] renderingEngineId set:', viewportInfo.renderingEngineId);
}
}, 5000);

return () => clearTimeout(timeoutId);
}, [getViewportInfo]);

useEffect(() => {
if (!renderingEngineId || !activeViewportId) return;

const toolGroup = ToolGroupManager.getToolGroupForViewport(activeViewportId, renderingEngineId);

if (!toolGroup) {
console.error('ToolGroup not available, skipping tool configuration.');

return;
}

toolGroup.setToolActive(PlanarFreehandROITool.toolName, {
bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
});

console.log('[ViewerLayout] Tool configured for:', toolGroup);
}, [renderingEngineId, activeViewportId]);

useEffect(() => {
if (!activeViewportId || !viewports.has(activeViewportId) || !renderingEngineId) {
return;
}

const renderingEngine = getRenderingEngine(renderingEngineId);

if (!renderingEngine) {
console.error('ViewerLayout: Invalid Rendering Engine');

return;
}

const viewport = renderingEngine.getViewport(activeViewportId);

if (!viewport) {
console.error('ViewerLayout: Invalid Viewport');

return;
}

const currentImageId = getCurrentImageId();

console.log('Active Viewport currentImageId:', currentImageId);

if (!currentImageId) {
console.error('ViewerLayout: No current image ID');

return;
}

if (showLoadingIndicator) {
setShowLoadingIndicator(false);
}

const dsUIDs = viewports.get(activeViewportId).displaySetInstanceUIDs || [];

if (!dsUIDs.length) return;

const displayUID = dsUIDs[0];

const ds = displaySetService.getDisplaySetByUID(displayUID);

if (!ds?.instances?.length) return;

const instance = ds.instances[0];

const toolGroup = ToolGroupManager.getToolGroupForViewport(activeViewportId, renderingEngineId);

if (toolGroup) {
const viewportIdsInToolGroup = toolGroup.getViewportIds();

console.log('Viewport IDs in ToolGroup:', viewportIdsInToolGroup);

let isViewportAlreadyAdded = false;

if (Array.isArray(viewportIdsInToolGroup)) {
isViewportAlreadyAdded = viewportIdsInToolGroup.includes(activeViewportId);
}

if (!isViewportAlreadyAdded) {
toolGroup.addViewport(activeViewportId, renderingEngineId);

console.log(
`[ViewerLayout] Added viewport ${activeViewportId} (engine: ${renderingEngineId}) to toolGroup ${toolGroup.id}`
);
}
} else {
console.error(`No toolGroup found for viewport ${activeViewportId}. Cannot add viewport.`);

return;
}

injectMeasurements(currentImageId, displayUID, instance, viewport.element);

viewport.render();

console.log('[ViewerLayout] Measurements and annotations injected successfully');
}, [
activeViewportId,
viewports,
renderingEngineId,
displaySetService,
getCurrentImageId,
injectMeasurements,
showLoadingIndicator,
]);

максимальные данные добавляются в службу измерения, служба аннотаций также запускается, и, по -видимому, добавлены данные, но соответствующие изменения не отображаются на слое SVG, в результате, рисунок не видно на изображении.

Подробнее здесь: https://stackoverflow.com/questions/796 ... if-corners
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Javascript»