20 views (last 30 days)

I have an image and i used the impoly() command do draw a slanted rectangle. I have the positions of the vertex of the rectangle and i would like to copy the intensities on those indexes into another matrix. My problem is that the matrix i want to extract is slanted. This is the relevant part of my code:

filename = uigetfile; %get the file name

obj = VideoReader(filename);

nFrames=obj.NumberOfFrames;

thisfig = figure();

for k = 1 : nFrames

this_frame = read(obj, k);

thisax = axes('Parent', thisfig);

image(this_frame, 'Parent', thisax);

if k==nFrames

title(thisax, sprintf('Frame #%d', k));

end

if k==1

result=input('How many rectangles would you like to draw? ');

pos=zeros(4,2,10); %declaring a reasonable size for post

for i=1:result

handle=impoly;

sample=getPosition(handle);

pos(:,:,i) = getPosition(handle);

end

end

end

Matt J
on 15 Sep 2013

Edited: Matt J
on 15 Sep 2013

I have the positions of the vertex of the rectangle and i would like to copy the intensities on those indexes into another matrix.

I assume you really mean that you want the image values enclosed by the polygon. The vertex coordinates can fall in between pixel locations and so are not indexable.

To get the enclosed values, you can do

regionValues=this_frame( createMask(handle) )

where "handle" is your handle to the impoly object.

Matt J
on 15 Sep 2013

not a matrix as i wished

If you want the polygon values embedded in a new matrix, what should the matrix values be outside the polygon? Zeros? If so, you can just do

masked_frame= this_frame.*createMask(handle);

Matt J
on 15 Sep 2013

I need to extract the values inside my polygon/rectangle into a new matrix so i will be able to calculate things like the mean of the columns and etc.

Since your data has a slanted geometry, it's not clear what you mean by "mean of the columns". A column is a notion that applies to rectangular arrays. My vague impression (you have to be clearer!) is that you want to take means etc... across the columns of your original matrix, but ignoring data outside the polygon. If so, and if you have the Statistics Toolbox, then you could fill the region outside the polygon with NaNs and use NANMEAN, NANSTD, etc...

mask=createMask(handle);

this_frame(~mask)=nan;

columnMeans=nanmean(this_frame)

If you don't have nanmean, nanstd, etc... you can re-invent them by doing things like

columnMeans=sum(this_frame.*mask,1)./sum(mask,1);

Image Analyst
on 15 Sep 2013

See my well commented demo below. You should be easily able to adapt it from copying and pasting rectangles to polygons using impoly() and poly2mask(). If you can't let me know.

% Lets user drag out a box on an image, then define where they want to paste it.

% Then it pastes the drawn region onto the original image.

clc; % Clear the command window.

close all; % Close all figures (except those of imtool.)

imtool close all; % Close all imtool figures.

clear; % Erase all existing variables.

workspace; % Make sure the workspace panel is showing.

fontSize = 20;

format compact;

% Check that user has the Image Processing Toolbox installed.

hasIPT = license('test', 'image_toolbox');

if ~hasIPT

% User does not have the toolbox installed.

message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');

reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');

if strcmpi(reply, 'No')

% User said No, so exit.

return;

end

end

% Read in a standard MATLAB gray scale demo image.

folder = fullfile(matlabroot, '\toolbox\images\imdemos');

baseFileName = 'eight.tif';

% Get the full filename, with path prepended.

fullFileName = fullfile(folder, baseFileName);

% Check if file exists.

if ~exist(fullFileName, 'file')

% File doesn't exist -- didn't find it there. Check the search path for it.

fullFileName = baseFileName; % No path this time.

if ~exist(fullFileName, 'file')

% Still didn't find it. Alert user.

errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);

uiwait(warndlg(errorMessage));

return;

end

end

grayImage = imread(fullFileName);

% Get the dimensions of the image.

% numberOfColorBands should be = 1.

[rows columns numberOfColorBands] = size(grayImage);

% Display the original gray scale image.

subplot(2, 2, 1);

imshow(grayImage);

axis on;

title('Original Grayscale Image', 'FontSize', fontSize);

% Enlarge figure to full screen.

set(gcf, 'units','normalized','outerposition',[0 0 1 1]);

% Give a name to the title bar.

set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')

% Let's compute and display the histogram, just for fun.

[pixelCount grayLevels] = imhist(grayImage);

subplot(2, 2, 2);

bar(pixelCount);

grid on;

title('Histogram of original image', 'FontSize', fontSize);

xlim([0 grayLevels(end)]); % Scale x axis manually.

% Ask user to draw a box.

subplot(2, 2, 1);

promptMessage = sprintf('Drag out a box that you want to copy,\nor click Cancel to quit.');

titleBarCaption = 'Continue?';

button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');

if strcmpi(button, 'Cancel')

return;

end

k = waitforbuttonpress;

point1 = get(gca,'CurrentPoint'); % button down detected

finalRect = rbbox; % return figure units

point2 = get(gca,'CurrentPoint'); % button up detected

point1 = point1(1,1:2); % extract x and y

point2 = point2(1,1:2);

p1 = min(point1,point2); % calculate locations

offset = abs(point1-point2); % and dimensions

% Find the coordinates of the box.

xCoords = [p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1) p1(1)];

yCoords = [p1(2) p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2)];

x1 = round(xCoords(1));

x2 = round(xCoords(2));

y1 = round(yCoords(5));

y2 = round(yCoords(3));

hold on

axis manual

plot(xCoords, yCoords, 'b-'); % redraw in dataspace units

% Display the cropped image.

croppedImage = grayImage(y1:y2,x1:x2);

subplot(2, 2, 3);

imshow(croppedImage);

axis on;

title('Region that you defined', 'FontSize', fontSize);

% Paste it onto the original image

[rows2 columns2] = size(croppedImage)

promptMessage = sprintf('Click on the upper left point where you want to paste it,\nor click Cancel to quit.');

titleBarCaption = 'Continue?';

button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');

if strcmpi(button, 'Cancel')

return;

end

[x, y] = ginput(1)

% Determine the pasting boundaries.

r1 = int32(y);

c1 = int32(x);

r2 = r1 + rows2 - 1;

r2 = min([r2 rows]);

c2 = c1 + columns2 - 1;

c2 = min([c2, columns]);

plot([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], 'r-');

% Paste as much of croppedImage as will fit into the original image.

grayImage(r1:r2, c1:c2) = croppedImage(1:(r2-r1+1), 1:(c2-c1+1));

subplot(2, 2, 4);

imshow(grayImage);

axis on;

title('Region that you defined pasted onto original', 'FontSize', fontSize);

Andrea
on 7 Nov 2014

Did you figure it out? I have the same exact problem for over a month and still could not find any resealable solution for that. my rectangular position changes in every loop and I don't know the angels.

In fact it is part of the swath which is mapped over the earth and since I am just interested in the specific slanted geo-location on those swath, I need to select the slanted rectangular and tilt it as a new matrix which also excludes the arrays outside. And the swath will change in every loop, that's why the slant rectangular will change. So please help me if you already found out the solution.

Matt J
on 8 Nov 2014

So please help me if you already found out the solution.

Andrea, The thread has an Accepted answer, involving imrotate and it's not clear why that wouldn't work for you as well. You say you "don't know the angles", but since you know the boundaries of the swath, you should be able to calculate that. If you don't know the boundaries of the swath, you couldn't have any basis for deciding what's to be extracted.

Image Analyst
on 8 Nov 2014

Opportunities for recent engineering grads.

Apply TodayFind the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
## 0 Comments

Sign in to comment.