Este desafio visa avaliar suas habilidades práticas no processamento e fusão de imagens médicas DICOM. Você irá desenvolver um sistema web capaz de carregar, analisar e corrigir imagens médicas específicas (DRR e CR), ajustando corretamente suas escalas através da detecção automática de círculos de referência na imagem CR.
- DRR (Digital Radiographic Reconstruction): imagem referência.
- CR (Computed Radiography): imagem de portal com grade circular usada para determinar magnificação.
Você precisará usar a grade circular presente no CR (distância entre os dois círculos maiores é de 10 cm) para calcular a escala e corrigir a magnificação, garantindo que ambas as imagens estejam alinhadas na mesma dimensão.
-
Interface web com capacidade para:
-
Upload das imagens CR e DRR.
-
Três viewports (canvas) distintas:
- Exibição da imagem original DRR.
- Exibição da imagem original CR.
- Exibição da fusão (sobreposição das imagens CR ajustada e DRR).
-
Utilização da biblioteca Cornerstone.js para visualização interativa das imagens.
-
Botões e controles intuitivos para facilitar a interação do usuário com as imagens carregadas.
-
-
Desenvolvimento em uma das linguagens: Python, C++ ou Rust.
-
Processamento automático de imagens DICOM com:
- Detecção automática dos círculos de referência na imagem CR utilizando a Transformada de Hough.
- Cálculo automático da escala da imagem CR baseado na distância conhecida (10 cm) entre os círculos detectados.
-
API REST para:
- Recebimento das imagens CR e DRR do frontend.
- Retorno da imagem CR processada e ajustada em escala para sobreposição precisa.
- Uso obrigatório do Docker e Docker Compose para integração e execução da solução completa.
import cv2
import numpy as np
# Ler imagem CR
img = cv2.imread('imagem_cr.jpg', cv2.IMREAD_GRAYSCALE)
# Detectar círculos (Transformada de Hough)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 40,
param1=90, param2=8, minRadius=30, maxRadius=40)
if circles is not None:
circles = np.uint16(np.around(circles))
center1, center2 = circles[0, :2, :2]
pixel_dist = np.linalg.norm(center1 - center2)
print(f"Distância em pixels: {pixel_dist}")
# Ajustar escala aqui com base na distância de 10 cm#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
cv::Mat img = cv::imread("imagem_cr.jpg", cv::IMREAD_GRAYSCALE);
std::vector<cv::Vec3f> circles;
cv::HoughCircles(img, circles, cv::HOUGH_GRADIENT, 1, 40, 90, 8, 30, 40);
if (circles.size() >= 2) {
cv::Point2f center1(circles[0][0], circles[0][1]);
cv::Point2f center2(circles[1][0], circles[1][1]);
float pixelDist = cv::norm(center1 - center2);
std::cout << "Distância em pixels: " << pixelDist << std::endl;
}
// Ajustar escala com base na distância física conhecida
return 0;
}import cornerstone from 'cornerstone-core';
const elementDRR = document.getElementById('viewportDRR');
const elementCR = document.getElementById('viewportCR');
const elementFusion = document.getElementById('viewportFusion');
cornerstone.enable(elementDRR);
cornerstone.enable(elementCR);
cornerstone.enable(elementFusion);
// Carregar imagens
cornerstone.loadImage('dicom://imagem_drr.dcm').then((drrImage) => {
cornerstone.displayImage(elementDRR, drrImage);
});
cornerstone.loadImage('dicom://imagem_cr.dcm').then((crImage) => {
cornerstone.displayImage(elementCR, crImage);
// Aplicar ajustes da escala recebida do backend antes da exibição no elemento de fusão
cornerstone.displayImage(elementFusion, crImage);
});
// Lógica adicional para sobrepor imagens aqui...rh-cv/
├── backend/
│ ├── Dockerfile
│ ├── api.py (ou cpp/rust equivalente)
│ ├── requirements.txt
├── frontend/
│ ├── Dockerfile
│ ├── src/
│ │ ├── components/
│ │ │ ├── DicomUploader.js
│ │ │ ├── DicomViewer.js
│ │ ├── App.js
│ ├── package.json
├── docker-compose.yml
├── README.md- Docker e Docker Compose
docker-compose up --buildAcesse a aplicação em http://localhost:3000.
Serão avaliados:
- Habilidade técnica e integração frontend/backend.
- Precisão na detecção dos círculos e ajuste de escala.
- Organização, clareza do código e usabilidade.
- Uso adequado de Docker e Docker Compose.