如何将低分辨率图像ROI转换至不同FoV的高分辨率图像
Alright, let's fix this scaling issue! The core problem here is that you're trying to handle translation and scaling separately by just shifting pixel coordinates—but you need to anchor everything to the physical world coordinates first, since that's the common reference between both images. Here's a step-by-step solution:
Key Concept: Pixel ↔ Physical Coordinate Conversion
Both images have their own pixel-to-physical mappings. To correctly transfer the ROI, we first convert the low-res ROI pixel coordinates to real-world physical positions, then convert those positions to high-res pixel coordinates. This handles both translation (positioning) and scaling (size) in one go.
Step 1: Convert Low-Res ROI Pixel Coordinates to Physical Coordinates
For any pixel (pxX_low, pxY_low) in the 256x256 image, its physical position (in mm) is calculated as:
% Physical X = refpoint X + (pixel X - 1) / low-res pixel spacing physX = refpoint_lowres(1) + (pxX - 1) / pixspacing_lowres; % Physical Y = refpoint Y + (pixel Y - 1) / low-res pixel spacing physY = refpoint_lowres(2) + (pxY - 1) / pixspacing_lowres;
Note: We subtract 1 from the pixel coordinate because (1,1) directly maps to refpoint_lowres—each subsequent pixel adds 1/pixspacing_lowres mm to the physical position.
Step 2: Convert Physical Coordinates to High-Res Pixel Coordinates
Now map those physical positions to the 512x512 image's pixel grid:
% High-res pixel X = 1 + (physical X - refpoint X) * high-res pixel spacing pxX_high = 1 + (physX - refpoint_highres(1)) * pixspacing_highres; % High-res pixel Y = 1 + (physical Y - refpoint Y) * high-res pixel spacing pxY_high = 1 + (physY - refpoint_highres(2)) * pixspacing_highres;
Here, we reverse the logic: the physical offset from the high-res reference point is converted to pixels using the high-res spacing, then add 1 to get back to 1-based pixel indexing.
Updated Working Code
Replace your existing shift/scaling logic with this full pipeline:
% Original low-res mask (unchanged) mask_lowres = double(poly2mask(pxX, pxY, 256., 256.)); % --- Convert ROI coordinates to physical space first --- % Low-res pixel -> physical mm physX = refpoint_lowres(1) + (pxX - 1) / pixspacing_lowres; physY = refpoint_lowres(2) + (pxY - 1) / pixspacing_lowres; % Physical mm -> high-res pixel pxX_high = 1 + (physX - refpoint_highres(1)) * pixspacing_highres; pxY_high = 1 + (physY - refpoint_highres(2)) * pixspacing_highres; % Generate correctly positioned AND scaled high-res mask mask_highres = double(poly2mask(pxX_high, pxY_high, 512., 512.));
Why Your Original Code Failed
Your initial approach only accounted for the translation between the two reference points, but ignored the differing pixel densities:
- The low-res image has a large pixel spacing (0.7757 pixel/mm), meaning each pixel covers more physical area.
- The high-res image has a much smaller spacing (2.8444 pixel/mm), so the same physical ROI will occupy more pixels.
By skipping the physical coordinate step, you weren't scaling the ROI's vertex coordinates to match the high-res pixel grid—you were just shifting the same low-res pixel positions into the high-res image, which is why the size was wrong.
内容的提问来源于stack exchange,提问作者tehm0n

