2

I just need to get the ROI in pixels (relative to image, not figure) using rbbox, but I'm having a hard time converting from normalized figure coordinates of the rbbox to image coordinates.

I already tried to multiply it by: image size, figure size, screen size, (image size) / (figure size). Also tried to use the axis position.

Normalized means from 0 to 1, so 1 should be the image size, or the figure size, so what I tried should have worked! I guess maybe the borders of the figure also count... Google is not helping this time.

There should be a method pixelStuff = FromNormalizedToImagePixels(normalizedStuff) !!

  • Figure size in pixels = windows size, useless, it includes the borders.
  • I need the ROI in "image pixels" (image inside the figure).
  • I can calculate the ROI if I could get the image region inside the figure (without the borders).

What I'm missing??

Code sample:

close all; clc;

figH = figure();
set(figH,'Units','normalized');
if isvalid(figH)
    % load some image
    imgData = imread('ImL_9.png');

    imshow(imgData,'Colormap', hot(256),'DisplayRange',...
        [min(imgData(:)) max(imgData(:))],'InitialMagnification','fit');
    grid on; axis on; xlabel('x'); ylabel('y');
    axis equal; axis manual;
    % Get image size (pixels)
    [isy,isx] = size(imgData);
    % Set axis to fit image
    ax = get(figH,'CurrentAxes');
    set(ax,'xlim',[0 isx]); set(ax,'ylim',[0 isy]);

    % Get mouse event to set ROI
    k = waitforbuttonpress;
    imgROIn = rbbox;
    annotation('rectangle',imgROIn,'Color','red');

    % Get screen size
    screenSize = get(0,'screensize');

    % Get figure position
    pos = get(figH, 'Position');

    % Conversion 1. roi size px = roi size norm * (image size px / figure size norm)
    cx = isx / pos(3);
    cy = isy / pos(4);
    conv = [cx cy cx cy];
    % Converts from normalized figure coordinate to image pixels coordinate
    imgROIpx = imgROIn.*conv;

    % Show result. imgROIpx does not match what was expected, like
    % selecting the entire image the result should be: 0 0 isx isy
    imgROIpx
end
Pedro77
  • 5,176
  • 7
  • 61
  • 91

2 Answers2

1

I think I solved the puzzle.

I created the following example that converts rbbox normalized coordinates to image coordinates in pixels:

close all

%Load and display an image for testing
I = imread('pout.tif');
imshow(I);
set(gcf, 'Units', 'normalized')
k = waitforbuttonpress;
rect_pos = rbbox;

%Get screen size.
screenSize = get(0, 'ScreenSize');

%Screen size in pixels (width, height).
screenSizePixels = screenSize(3:4);

%Get figure size (normalized to [0, 1] out of screenSize).
figPositionNormalized = get(gcf, 'Position');

%Get axes size (normalized to [0, 1] out of figure size).
axesPositionNormalized = get(gca, 'Position');

%Convert figure size to pixels.
figPositionPixels = figPositionNormalized.*[screenSizePixels, screenSizePixels];
figSizePixels = figPositionPixels(3:4);

%Convert axes position to pixels.
axesPositionPixels = axesPositionNormalized.*[figSizePixels, figSizePixels];

axesSizePixels = axesPositionPixels(3:4);

%Subtract axes upper left corner from rect_pos.
rect_pos(1:2) = rect_pos(1:2) - axesPositionNormalized(1:2);

%Convert rect_pos to pixels
rectPosPixels = rect_pos.*[figSizePixels, figSizePixels];

%Reverse up/down (to get coordinates in image).
rectPosPixels(2) = axesSizePixels(2) - rectPosPixels(2);

rectPosPixels = round(rectPosPixels);

%Mark pixel with white rectange, and black dot.
I(rectPosPixels(2)-1:rectPosPixels(2)+1, rectPosPixels(1)-1:rectPosPixels(1)+1) = 255;
I(rectPosPixels(2), rectPosPixels(1)) = 0;

%Show marked image.
imshow(I);

I pointed the center pixel with the mouse:
enter image description here

Rotem
  • 30,366
  • 4
  • 32
  • 65
  • Ok but what I need is to convert the normalized ROI data to image pixels. – Pedro77 Mar 16 '17 at 22:45
  • Took me a while to get it right... Sorry for ignoring your latest edit. – Rotem Mar 17 '17 at 00:27
  • Nice, it seams it is marking correctly the bottom left ROI corner. There is one problem, if the figure is resized (like maximize) before starting the ROI, it will not work. I'm looking into it – Pedro77 Mar 17 '17 at 14:17
1

@Rotem solution does not work if the image is resized.

I was looking to get a ROI, so the solution that I found is to use roipoly Another way to find the mouse position is ginput

ROImask = roipoly; % Multi sides ROI
% or
[x,y] = ginput(1); % mouse position in image coordinates
Pedro77
  • 5,176
  • 7
  • 61
  • 91
  • I got messed with the normalized coordinates format... When there is an axes within a figure within the screen, it's really confusing. It's not so difficult to correct my post, but I am glad you found more elegant solution to your problem. – Rotem Mar 17 '17 at 21:30