binary mask for the coordinates using MATLAB - matlab

I need to create a binary mask. I have some coordinates and I make those coordinates and inside that region equal to 1, and background equal to zero.
Here is what I have done, but the problem is ROI located not in the correct position and located on the right bottom of the image. I appreciate if someone could point me to the right direction.
function [X,Y, BW] = Create_mask(X,Y,im)
X = round(X);
Y = round(Y);
X ( X < 1 ) = 1;
Y ( Y < 1 ) = 1;
BW = im > 255;
for p = 1:length(X)
BW(Y(p),X(p)) = 1;
end
for n = 0:(1/round(sqrt((X(end)-X(1))^2 + (Y(end)-Y(1))^2 ))):1
xn = round(X(1) +(X(end) - X(1))*n);
yn = round(Y(1) +(Y(end) - Y(1))*n);
BW(yn,xn) = 1;
end
se = strel('disk',10);
BW = imclose(BW,se);
BW = imdilate(BW,se);
BW = imfill(BW,'holes');
im( im < 255 ) = 0;
im = imclose(im,se);
BW = BW * 255;
BW = im2uint8(BW);
% BW = imresize(BW, [256 256],'nearest');
figure;
imshow(BW);
% close all;
end
Here is the output the function:
I was expecting to be similar to this image. This is not the exact solution but it shows my expectation.
X and Y coordinates are attached here, The first col is X and the second Y.

you can do this by calling function inpolygon, try this
function mask=createmask(x,y, cmin, cmax, dx)
if(nargin<3)
cmin=min([x(:) y(:)]);
end
if(nargin<4)
cmax=max([x(:) y(:)]);
end
if(nargin<5)
dx=(cmax-cmin)/100;
end
if(length(dx)==1)
dx=[dx dx];
end
[xi,yi]=meshgrid(cmin(1):dx(1):cmax(1),cmin(2):dx(2):cmax(2));
mask=reshape(inpolygon(xi(:),yi(:),x(:),y(:)), size(xi));
to test
xv = [0 3 3 0 0 NaN 1 1 2 2 1];
yv = [0 0 3 3 0 NaN 1 2 2 1 1];
mask=createmask(xv,yv, [-1 -1], [4 4]);
imagesc(mask)

Related

Index in position __ exceeds array bounds

Having Trouble with this Error "Index in position 2 is invalid. Array indices must be positive integers or logical values." It only occurs when I enter certain values for the translation. Such as -25 x-direction and +50 in the y-direction. But it will work if I enter in any decimal values such as (12.75,-19.3). Please help me out.
Note: A is an imported image
if (delta_x == 0 && delta_y == 0) % Allows the Orginal Image to be displayed
figure(1)
image(0:ynew-1,0:xnew-1,A) % display a matrix as an image
axis equal
axis ij % put 0,0 in UL corner
axis tight
colormap(gray(L)) % use an 8-bit grayscale
xlabel('y')
ylabel('x')
title('Original Image')
return
end
%Translation Matrix 3x3
Trans = [1 0 delta_x; 0 1 delta_y; 0 0 1];
InverseTrans = (inv(Trans)); %Inverse Mapping Begins
%Allocate Space
E = zeros(xnew, ynew,k);
for i=1:xold
for j=1:yold
% matrix math assumes origin is (0,0) not (1,1)
vw=InverseTrans*[i; j; 1]; % vw will be [v; w; 1]
v = vw(1);
w = vw(2);
if (v < 0 || v >(xold-1)) % Testing for Out of Bounds
E(i,j) = 0;
elseif (w < 0 || w >(yold-1)) % Testing for out of Bounds
E(i,j) = 0;
else
%Takes the Real INTEGER Part
v_fix = fix(v);
w_fix = fix(w);
v_fix1 = v_fix +1;%Indexing
w_fix1 = w_fix +1;
%Change in the Values
dX = v - v_fix;
dY = w - w_fix;
%Indexing Purposes **This is where I'm getting my error**
D1(i,j) = A(v_fix1, w_fix1);
D2(i,j) = A(v_fix1 + 1, w_fix1);
D3(i,j) = A(v_fix1, w_fix1 + 1);
D4(i,j) = A(v_fix1 + 1, w_fix1 + 1);
end
end
end```

Problems with performing image translation in MATLAB

I'm trying to do image translation using MATLAB, and the image doesn't move at all. My code is:
myPic = imread('pic.jpg');
x = 250;
y = 375;
trans = affine2d([1 0 0; 0 1 0; x y 1]);
outputPic = imwarp(myPic, trans);
imshow(myPic)
axis on
figure()
imshow(outputPic)
axis on
isequal(myPic,outputPic) %evaluates to 1!!!
When I do the same for a rotation affine matrix, it worked. Why doesn't this work?
here's what happens when I print both pics:
In order for this to work, you'll need to define an 'OutputView' parameter.
This parameter sets the size and location of the output image in world coordinate system, using imref2d function.
Example:
myPic = imread('peppers.png');
x = 250;
y = 375;
%defines transformations
trans = affine2d([1 0 0; 0 1 0; x y 1]);
eyeTrans= affine2d([1 0 0; 0 1 0; 0 0 1]);
%initializes imref2d object
outView = imref2d([size(myPic,1)+y,size(myPic,2)+x]);
outputPic1 = imwarp(I,trans,'OutputView',outView)
outputPic2 = imwarp(I,eyeTrans,'OutputView',outView)
%display result
figure,
subplot(1,2,1); imshow(outputPic2); title('original')
subplot(1,2,2); imshow(outputPic1); title('translated')
Result:

Horn-Schunck Optical Flow (Averaging Velocity)

I'm currently trying to implement the HS-method for optical flow but my u and v always seem to have only zeros in them. I can't seem to figure out my error in here:
vid=VideoReader('outback.AVI');
vid.CurrentTime = 1.5;
alpha=1;
iterations=10;
frame_one = readFrame(vid);
vid.CurrentTime = 1.6;
frame_two = readFrame(vid);
% convert to grayscale
fone_gr = rgb2gray(frame_one);
ftwo_gr = rgb2gray(frame_two);
% construct for each image
sobelx=[-1 -2 -1; 0 0 0; 1 2 1];
sobely=sobelx';
time=[-1 1];
fx_fone=imfilter(fone_gr, sobelx);
fy_fone=imfilter(fone_gr, sobely);
ft_fone=imfilter(fone_gr, time);
fx_ftwo=imfilter(ftwo_gr, sobelx);
fy_ftwo=imfilter(ftwo_gr, sobely);
ft_ftwo=imfilter(ftwo_gr, time);
Ix=double(fx_fone+fx_ftwo);
Iy=double(fy_fone+fy_ftwo);
It=double(ft_fone+ft_ftwo);
% flow-variables (velocity = 0 assumption)
velocity_kernel=[0 1 0; 1 0 1; 0 1 0];
u = double(0);
v = double(0);
% iteratively solve for u and v
for i=1:iterations
neighborhood_average_u=conv2(u, velocity_kernel, 'same');
neighborhood_average_v=conv2(v, velocity_kernel, 'same');
data_term = (Ix .* neighborhood_average_u + Iy .* neighborhood_average_v + It);
smoothness_term = alpha^2 + (Ix).^2 + (Iy).^2;
numerator_u = Ix .* data_term;
numerator_v = Iy .* data_term;
u = neighborhood_average_u - ( numerator_u ./ smoothness_term );
v = neighborhood_average_v - ( numerator_v ./ smoothness_term );
end
u(isnan(u))=0;
v(isnan(v))=0;
figure
imshow(frame_one); hold on;
quiver(u, v, 5, 'color', 'b', 'linewidth', 2);
set(gca, 'YDir', 'reverse');
The only thing I'm not really confident about is the computation of the neighborhood average:
velocity_kernel=[0 1 0; 1 0 1; 0 1 0];
u = double(0);
v = double(0);
[..]
neighborhood_average_u=conv2(u, velocity_kernel, 'same');
neighborhood_average_v=conv2(v, velocity_kernel, 'same');
Wouldn't that always result in a convolution matrix with only zeros?
I thought about changing it to the following, since I need to compute the average velocity using the velocity kernel on each pixel of my images:
velocity_kernel=[0 1 0; 1 0 1; 0 1 0];
u = double(0);
v = double(0);
[..]
neighborhood_average_u=conv2(Ix, velocity_kernel, 'same');
neighborhood_average_v=conv2(Iy, velocity_kernel, 'same');
But I still don't know if that would be the correct way. I followed the instructions on the bottom of this MATLAB page:
http://de.mathworks.com/help/vision/ref/opticalflowhs-class.html
I found this paper with some further explanations and also some matlab code.
They compute the average of u and v as follows:
% initial values
u = 0; v = 0;
% weighted average kernel
kernel = [1/12 1/6 1/12; 1/6 0 1/6; 1/12 1/6 1/12];
for i = 1:iterations
uAvg = conv2( u, kernel 'same' );
vAvg = conv2( v, kernel 'same' );
...
end

avoid loop matlab in 2D bspline surface interpolation

I want to speed up my code. I always use vectorization. But in this code I have no idea how to avoid the for-loop. I would really appreciate a hint how to proceed.
thank u so much for your time.
close all
clear
clc
% generating sample data
x = linspace(10,130,33);
y = linspace(20,100,22);
[xx, yy] = ndgrid(x,y);
k = 2*pi/50;
s = [sin(k*xx+k*yy)];
% generating query points
xi = 10:5:130;
yi = 20:5:100;
[xxi, yyi] = ndgrid(xi,yi);
P = [xxi(:), yyi(:)];
% interpolation algorithm
dx = x(2) - x(1);
dy = y(2) - y(1);
x_ = [x(1)-dx x x(end)+dx x(end)+2*dx];
y_ = [y(1)-dy y y(end)+dy y(end)+2*dy];
s_ = [s(1) s(1,:) s(1,end) s(1,end)
s(:,1) s s(:,end) s(:,end)
s(end,1) s(end,:) s(end,end) s(end,end)
s(end,1) s(end,:) s(end,end) s(end,end)];
si = P(:,1)*0;
M = 1/6*[-1 3 -3 1
3 -6 3 0
-3 0 3 0
1 4 1 0];
tic
for nn = 1:numel(P(:,1))
u = mod(P(nn,1)- x_(1), dx)/dx;
jj = floor((P(nn,1) - x_(1))/dx) + 1;
v = mod(P(nn,2)- y_(1), dy)/dy;
ii = floor((P(nn,2) - y_(1))/dy) + 1;
D = [s_(jj-1,ii-1) s_(jj-1,ii) s_(jj-1,ii+1) s_(jj-1,ii+2)
s_(jj,ii-1) s_(jj,ii) s_(jj,ii+1) s_(jj,ii+2)
s_(jj+1,ii-1) s_(jj+1,ii) s_(jj+1,ii+1) s_(jj+1,ii+2)
s_(jj+2,ii-1) s_(jj+2,ii) s_(jj+2,ii+1) s_(jj+2,ii+2)];
U = [u.^3 u.^2 u 1];
V = [v.^3 v.^2 v 1];
si(nn) = U*M*D*M'*V';
end
toc
scatter3(P(:,1), P(:,2), si)
hold on
mesh(xx,yy,s)
This is the full example and is a cubic B-spline surface interpolation algorithm in 2D space.

Sequence of dots in matlab and psychotoolbox

How would i display one by one dots that are in a 3x3 matrix such as in the code below?
I would like to have dot1 appears in position [x1,y1] of the grid for a time t1, then dot2 to appears in position [x2,y2] of the grid for a time t2. Only one dot is being shown at each time.
Thanks for help
%grid
dim = 1
[x, y] = meshgrid(-dim:1:dim, -dim:1:dim);
pixelScale = screenYpixels / (dim * 2 + 2);
x = x .* pixelScale;
y = y .* pixelScale;
% Calculate the number of dots
numDots = numel(x);
% Make the matrix of positions for the dots.
dotPositionMatrix = [reshape(x, 1, numDots); reshape(y, 1, numDots)];
% We can define a center for the dot coordinates to be relaitive to.
dotCenter = [xCenter yCenter];
dotColors = [1 0 0];
dotSizes = 20;
Screen('DrawDots', window, dotPositionMatrix,...
dotSizes, dotColors, dotCenter, 2);
I think you want something like this?
%positions of each successive dots:
x_vec = [1,2,3,1,2,3,1,2,3];
y_vec = [1,1,1,2,2,2,3,3,3];
%wait times in sec for each dot:
wait_times = [1,1,2,1,1,2,1,1,2]
dotColor = [1 0 0];
dotSize = 400;
num_dots = length(x_vec);
for i = 1:num_dots
scatter(x_vec(i),y_vec(i),dotSize,dotColor,'filled');
xlim([0,max(x_vec)])
ylim([0,max(y_vec)])
pause(wait_times(i));
end