a variation of Windy gridworld game problem in reinforcement learning with my matlab code - matlab

In reinforcement learning, a typical example is the windy gridworld
And I face with a new variation of windy gridworld, which additionally has a wall and stochastic wind, I am stuck in these two new things
Figure 1 shows a standard gridworld, with start (S) and goal (G) cells, but with two dierences: there
is a wall the agent can not cross (indicated by the black cells) and there is a crosswind down and to the
left at the right edge of the grid. The available actions in each cell are the king's moves | 8 actions in
total for each cell. If any action would bring you outside the gridworld or collide with the wall, you end
up in the nearest cell (e.g. going northeast in the top left cell will bring you one cell to the right). In the
right region the resultant next cells are shifted down-left by a stochastic \wind", the mean strength of
which varies column by column. The mean strength of the wind is given below each column, in number
of cells shifted down-left.
Due to stochasticity, the wind sometimes varies by 1 from the mean values
given for each column (except if the mean is 0). That is, a third of the time you are shifted down-left
exactly according to the values indicated below the column, a third of the time you are shifted one cell
further down and left that, and another third of the time you are shifted one cell less than the mean.
For example, if you are in the row of the wall and in the middle of the opening and you move up, then
one-third of the time you end up one row west of that cell, one-third of the time you end up two colums
west, one column south of that cell, and one-third of the time you end up at the same column north of
that cell. The wind aects the cell you are in, not the cell you are going to.
Implement the Q-learning algorithm2 in the above problem with = 0:1,
= 0:9 and initial Q(s; a) = 0
for all s; a. Each action generates a reward of rs = 􀀀1, except for the actions that lead immediately to
the goal cell (rg = 10). Use the:
-Greedy action selection method with = 0:2.
Greedy action selection method with initial Q(s,a) > 0 and initial Q(s,a) < 0.
my matlab code will work.
My real problem is on the
function nextPos = GiveNextPos(curPos, actionIndex, windpowers, gridCols, gridRows), in which the agent will decide a action, and move to the next step. But there are many factors to influence the next step, such as stochastic wind and wall
so first question is about the stochastic wind, how can I program in matlab to say in 1/3 chance, it is 3, in another 1/3 chance, it is 1...
the second question is about colliding wall?should I firstly calculate the next step for king's walk and wind, and then use this next step value to check if I hit the wall or not???)
function WindyGridWorldQLearning()
fprintf('WindyGridWorldQLearning\n');
gamma = 0.9;
alpha = 0.1;
epsilon = 0.2;
gridcols = 10;
gridrows = 7;
windpowers = [0 0 0 0 1 1 2 2 1 1];
fontsize = 16;
showTitle = 1;
episodeCount = 900;
selectedEpisodes = [900];
isKing = 1;
canHold = 0;
start.row = 7;
start.col = 1;
goal.row = 1;
goal.col = 1;
selectedEpIndex = 1;
actionCount = 8;
% initialize Q with zeros
Q = zeros(gridrows, gridcols, actionCount);
a = 0; % an invalid action
% loop through episodes
for ei = 1:episodeCount,
%disp(sprintf('Running episode %d', ei));
curpos = start;
nextpos = start;
%epsilon or greedy
if(rand > epsilon) % greedy
[qmax, a] = max(Q(curpos.row,curpos.col,:));
else
a = IntRand(1, actionCount);
end
while(PosCmp(curpos, goal) ~= 0)
% take action a, observe r, and nextpos
nextpos = GiveNextPos(curpos, a, windpowers, gridcols, gridrows);
if(PosCmp(nextpos, goal) ~= 0), r = -1; else r = 10; end
% choose a_next from nextpos
[qmax, a_next] = max(Q(nextpos.row,nextpos.col,:));
if(rand <= epsilon) % explore
a_next = IntRand(1, actionCount);
end
% update Q:
curQ = Q(curpos.row, curpos.col, a);
nextQ = qmax; %Q(nextpos.row, nextpos.col, a_next);
Q(curpos.row, curpos.col, a) = curQ + alpha*(r + gamma*nextQ - curQ);
curpos = nextpos; a = a_next;
end % states in each episode
% if the current state of the world is going to be drawn ...
if(selectedEpIndex <= length(selectedEpisodes) && ei == selectedEpisodes(selectedEpIndex))
curpos = start;
rows = []; cols = []; acts = [];
for i = 1:(gridrows + gridcols) * 10,
[qmax, a] = max(Q(curpos.row,curpos.col,:));
nextpos = GiveNextPos(curpos, a, windpowers, gridcols, gridrows);
rows = [rows curpos.row];
cols = [cols curpos.col];
acts = [acts a];
if(PosCmp(nextpos, goal) == 0), break; end
curpos = nextpos;
end % states in each episode
%figure;
figure('Name',sprintf('Episode: %d', ei), 'NumberTitle','off');
DrawWindyEpisodeState(rows, cols, acts, start.row, start.col, goal.row, goal.col, windpowers, gridrows, gridcols, fontsize);
if(showTitle == 1),
title(sprintf('Windy grid-world SARSA - episode %d - (\\epsilon: %3.3f), (\\alpha = %3.4f), (\\gamma = %1.1f)', ei, epsilon, alpha, gamma));
end
selectedEpIndex = selectedEpIndex + 1;
end
end % episodes loop
function c = PosCmp(pos1, pos2)
c = pos1.row - pos2.row;
if(c == 0)
c = c + pos1.col - pos2.col;
end
function nextPos = GiveNextPos(curPos, actionIndex, windpowers, gridCols, gridRows)
nextPos = curPos;
switch actionIndex
case 1 % east
nextPos.col = curPos.col + 1;
case 2 % south
nextPos.row = curPos.row + 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 3 % west
nextPos.col = curPos.col - 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.col = curPos.col; end
case 4 % north
nextPos.row = curPos.row - 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 5 % northeast
nextPos.col = curPos.col + 1;
nextPos.row = curPos.row - 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 6 % southeast
nextPos.col = curPos.col + 1;
nextPos.row = curPos.row + 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 7 % southwest
nextPos.col = curPos.col - 1;
nextPos.row = curPos.row + 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 8 % northwest
nextPos.col = curPos.col - 1;
nextPos.row = curPos.row - 1;
if(nextPos.row ==4 && nextPos.col <= 4 ) nextPos.row = curPos.row; end
case 9 % hold
nextPos = curPos;
otherwise
disp(sprintf('invalid action index: %d', actionIndex))
end
if(curPos.col > 4)
nextPos.row = nextPos.row - windpowers(nextPos.col);
nextPos.col = nextPos.col - windpowers(nextPos.col);
end
if(nextPos.col <= 0), nextPos.col = 1; end
if(nextPos.col > gridCols), nextPos.col = gridCols; end
if(nextPos.row <= 0), nextPos.row = 1; end
if(nextPos.row > gridRows), nextPos.row = gridRows; end
function n = IntRand(lowerBound, upperBound)
n = floor((upperBound - lowerBound) * rand + lowerBound);
function DrawWindyEpisodeState(rows, cols, acts, SRow, SCol, GRow, GCol, windpowers, gridrows, gridcols, fontsize)
DrawGrid(gridrows, gridcols);
DrawTextOnCell('S', 0, SRow, SCol, gridrows, gridcols, fontsize);
DrawTextOnCell('G', 0, GRow, GCol, gridrows, gridcols, fontsize);
for i=1:length(rows),
DrawActionOnCell(acts(i), rows(i), cols(i), gridrows, gridcols, fontsize);
end
for i=1:gridcols,
[xc, yc] = FindColBaseCenter(i, gridrows, gridcols);
text(xc, yc, sprintf('%d',windpowers(i)), 'FontSize', fontsize, 'Rotation', 0);
end
function DrawEpisodeState(rows, cols, acts, SRow, SCol, GRow, GCol, gridrows, gridcols, fontsize)
DrawGrid(gridrows, gridcols);
DrawTextOnCell('S', 0, SRow, SCol, gridrows, gridcols, fontsize);
DrawTextOnCell('G', 0, GRow, GCol, gridrows, gridcols, fontsize);
for i=1:length(rows),
DrawActionOnCell(acts(i), rows(i), cols(i), gridrows, gridcols, fontsize);
end
function DrawGrid(gridrows, gridcols)
xsp = 1 / (gridcols + 2);
ysp = 1 / (gridrows + 2);
x = zeros(1, 2*(gridcols + 1));
y = zeros(1, 2*(gridcols + 1));
i = 1;
for xi = xsp:xsp:1 - xsp,
x(2*i - 1) = xi; x(2*i) = xi;
if(mod(i , 2) == 0)
y(2*i - 1) = ysp;y(2*i) = 1-ysp;
else
y(2*i - 1) = 1 - ysp;y(2*i) = ysp;
end
i = i + 1;
end
x2 = zeros(1, 2*(gridrows + 1));
y2 = zeros(1, 2*(gridrows + 1));
i = 1;
for yi = ysp:ysp:1 - ysp,
y2(2*i - 1) = yi; y2(2*i) = yi;
if(mod(i , 2) == 0)
x2(2*i - 1) = xsp;x2(2*i) = 1-xsp;
else
x2(2*i - 1) = 1 - xsp;x2(2*i) = xsp;
end
i = i + 1;
end
plot(x, y, '-');
hold on
plot(x2, y2, '-');
axis([0 1 0 1]);
axis off
set(gcf, 'color', 'white');
function DrawTextOnCell(theText, rotation, row, col, gridrows, gridcols, fontsize)
[xc, yc] = FindCellCenter(row, col, gridrows, gridcols);
text(xc, yc, theText, 'FontSize', fontsize, 'Rotation', rotation);
function DrawActionOnCell(actionIndex, row, col, gridrows, gridcols, fontsize)
rotation = 0;
textToDraw = 'o';
switch actionIndex
case 1 % east
textToDraw = '\rightarrow';
rotation = 0;
case 2 % south
textToDraw = '\downarrow';
rotation = 0;
case 3 % west
textToDraw = '\leftarrow';
rotation = 0;
case 4 % north
textToDraw = '\uparrow';
rotation = 0;
case 5 % northeast
textToDraw = '\rightarrow';
rotation = 45;
case 6 % southeast
textToDraw = '\downarrow';
rotation = 45;
case 7 % southwest
textToDraw = '\leftarrow';
rotation = 45;
case 8 % northwest
textToDraw = '\uparrow';
rotation = 45;
otherwise
disp(sprintf('invalid action index: %d', actionIndex))
end
DrawTextOnCell(textToDraw, rotation, row, col, gridrows, gridcols, fontsize);
function [x,y] = FindCellCenter(row, col, gridrows, gridcols)
xsp = 1 / (gridcols + 2);
ysp = 1 / (gridrows + 2);
x = ((2*col + 1) / 2) * xsp;
y = 1 - (((2*row + 1) / 2) * ysp);
x = x - xsp/5;
function [x,y] = FindColBaseCenter(col, gridrows, gridcols)
row = gridrows + 1;
xsp = 1 / (gridcols + 2);
ysp = 1 / (gridrows + 2);
x = ((2*col + 1) / 2) * xsp;
y = 1 - (((2*row + 1) / 2) * ysp);
x = x - xsp/5;

For the wind just generate a random number n, say between 0 and 1. If you want 3 different behaviors each with a 1/3 chance, just have conditions for n < .33 , .33 < n < .66 ... etc.
I don't quite understand what you're saying with the wall, but you should check the action the agent will take and the effect the wind will have on it and then see if this results in you hitting a wall. If so take the appropriate action.

Related

Sum of rectangles in Matlab

I have a code which doesnt work the way I want to. The problem is i need a sum of all rctangles from a picture as below.
My code:
imH = size(I, 1);
imW = size(I, 2);
windowWidth = 30;
windowHeight = 30;
step = 1;
for r = 1:step:imH - windowHeight + 1
for c = 1:step:imW - windowWidth + 1
Win = I(r:r + windowHeight - 1, c:c + windowWidth - 1, :);
post =[c r windowHeight windowWidth];
I think I lack sum here
%stop = waitforbuttonpress;
subplot(121); imshow(I); title 'Image';
hold on;
rectangle('Position', pos, 'EdgeColor', 'r');
hold off;
subplot (122); imshow(W); title 'ooo';
drawnow;
pause(0.0000001);
end
end
Everything works great but I need to sum separately every rectangle values
You only need to add & in the 1st and 2nd rgb intervals as below:
matchNh = (R > 45 & R < 180) & (G > 50 & G < 185) & (B > 160 & B < 215);
matchNd = (R > 40 & R < 115) & (G > 6 & G < 80) & (B > 10 & B < 75);
Then you are doing right to count the nonzero pixels i.e.
Nh = nnz(matchNh);
Nd = nnz(matchNd);
If you want to use for more than one image , then you can use another for loop outside the two for loops e.g.
imgnames = dir('*.jpg'); % get list of jpg images in current directory
NN = length(imgnames)
%sliding window size
windowWidth = 64;
windowHeight = 64;
%step
step = 64;
Nh = 0;
Nd = 0;
for ii = 1 : NN
I = imread(imgnames(ii).name);
% your code i.e. two for loops as you have written above
imH = size(I, 1);
imW = size(I, 2);
for r = 1:step:imH - windowHeight + 1
for c = 1:step:imW - windowWidth + 1
%sliding window value
W = I(r:r + windowHeight - 1, c:c + windowWidth - 1, :);
pos =[c r windowHeight windowWidth];
R = W(:,:,1);
G = W(:,:,2);
B = W(:,:,3);
% RGB intervals for every sliding window
matchNh = (R > 45 & R < 180) & ...
(G > 50 & G < 185) & ...
(B > 160 & B < 215);
matchNd = (R > 40 & R < 115) & ...
(G > 6 & G < 80) & ...
(B > 10 & B < 75);
Nh = Nh + nnz(matchNh);
Nd = Nd + nnz(matchNd);
end
end
PIc = Nd / (Nh + Nd)
end

MATLAB 3D lines are invisible

Hello I'am suffered from a problem
As you can see I want a draw 3D graph.
Problem is when I draw sphere lines are invisible.
Here is simple version of my source
clear all; close all; clc
n=1;
n_inner_drone=3;
n_outter_drone=2;
length=100;
initial_d = zeros(1,n);
inner_x = zeros(n_inner_drone,n);
inner_y = zeros(n_inner_drone,n);
inner_z = zeros(n_inner_drone,n);
outter_x = zeros(n_outter_drone,n);
outter_y = zeros(n_outter_drone,n);
outter_z = zeros(n_outter_drone,n);
radius= length;
disp('test');
%%%%%%%%%%%%%%%%%%%%%% Sphere
% figure()
% [x, y, z] = sphere;
% h = surfl(x*length, y*length, z*length);
% hSurf = surf(X,Y,Z,'EdgeColor','none','LineStyle','none','FaceLighting','phong');
% set(h, 'FaceAlpha', 0.05)
% surf(x*length, y*length, z*length,
% shading interp
hold on
%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:n_inner_drone
k=1;
while 1
x_temp= randi([-length, length], 1, 1);
y_temp= randi([-length, length], 1, 1);
z_temp= randi([-length, length], 1, 1);
dist = sqrt(x_temp^2 + y_temp^2 + z_temp^2);
if dist<radius
if i==1
initial_d(k) = dist;
end
inner_x(i,k) = x_temp;
inner_y(i,k) = y_temp;
inner_z(i,k) = z_temp;
k = k+1;
end
if k == n+1, break, end
end
end
ideal_direction_length = ones(1,n);
ideal_direction_length = ideal_direction_length * length;
ideal_direction_length = ideal_direction_length - initial_d;
k=1;
random_x = inner_x(1,:);
random_y = inner_y(1,:);
random_z = inner_z(1,:);
random_moving_distance = zeros(1,n);
moving_distance = 0;
trigger = 0;
while 1
if trigger == 0
direction = randi([1, 6], 1, 1);
trigger = 1;
end
if direction == 1
random_x(k) = random_x(k) + 1;
elseif direction == 2
random_x(k) = random_x(k) - 1;
elseif direction == 3
random_y(k) = random_y(k) + 1;
elseif direction == 4
random_y(k) = random_y(k) - 1;
elseif direction == 5
random_z(k) = random_z(k) + 1;
elseif direction == 6
random_z(k) = random_z(k) - 1;
end
dist = sqrt(random_x(k)^2 + random_y(k)^2 + random_z(k)^2);
moving_distance = moving_distance+1;
%%%%%%%%%% Line
plot3(random_x(n),random_y(n),random_z(n),'k+')
%%%%%%%%%%%%%%%
if dist>radius
random_moving_distance(k) = moving_distance;
k = k+1;
moving_distance = 0;
trigger = 0;
end
if k == n+1, break, end
end
plot3(inner_x(1,n),inner_y(1,n),inner_z(1,n),'r*')
for k=2:n_inner_drone
plot3(inner_x(k,n),inner_y(k,n),inner_z(k,n),'b*')
end
for k=1:n_outter_drone
plot3(outter_x(k,n),outter_y(k,n),outter_z(k,n),'k*')
end
At the first, I suspected I worngly draw lines, but without sphere I can see lines as fig2.
Those anyone who knows about this problem.
Please answer to me and I will very appericiate about it.
Thanks for reading.
I think it is because:
plot3(gravity_x(n),gravity_y(n),gravity_z(n))
is not a line. Its a single point.
plot3(gravity_x(n:n+1),gravity_y(n:n+1),gravity_z(n:n+1))
is a line.

Finger peak detection using MATLAB

I have to create an algorithm with Matlab that, with a image of a hand, can know the form of the hand by the number of raised fingers and the presence or absence of the thumb. So far, the algorithm is almost complete but I don't know what more I can do that could find the peaks that represents the fingers. We tried a lot of things but nothing works. The idea is to find when there is a sudden increasement but as the pixels are never completely aligned, nothing that we tried worked. Someone has any idea? Here is the code so far.
The image that he is reading is this one:
To know if the finger is relevant or not, we already have an idea that might work... but we need to find the fingers first.
clear all
close all
image=imread('mao2.jpg');
YCBCR = rgb2ycbcr(image);
image=YCBCR;
cb = image(:,:,2);
cr = image(:,:,3);
imagek(:,1) = cb(:);
imagek(:,2) = cr(:);
imagek = double(imagek);
[IDX, C] = kmeans(imagek, 2, 'EmptyAction', 'singleton');
s=size(image);
IDX= uint8(IDX);
C2=round(C);
imageNew = zeros(s(1),s(2));
temp = reshape(IDX, [s(1) s(2)]);
for i = 1 : 1 : s(1)
for j = 1 : 1 : s(2)
imageNew(i,j,:) = C2(temp(i,j));
end
end
imageNew=uint8(imageNew);
[m,n]=size(imageNew);
for i=1:1:m
for j = 1:1:n
if(imageNew(i,j)>=127)
pretobranco(i,j)=0;
else
pretobranco(i,j)=1;
end
end
end
I2=imfill(pretobranco);
imshow(I2);
imwrite(I2, 'mao1trab.jpg');
[m,n]=size(I2);
B=edge(I2);
figure
imshow(B);
hold on;
stats=regionprops(I2,'BoundingBox');
rect=rectangle('position', [stats(1).BoundingBox(1), stats(1).BoundingBox(2), stats(1).BoundingBox(3), stats(1).BoundingBox(4)], 'EdgeColor', 'r');
stats(1).BoundingBox(1)
stats(1).BoundingBox(2)
stats(1).BoundingBox(3)
stats(1).BoundingBox(4)
figure
Bound = B( stats(1).BoundingBox(2): stats(1).BoundingBox(2)+stats(1).BoundingBox(4)-1, stats(1).BoundingBox(1):stats(1).BoundingBox(1)+stats(1).BoundingBox(3)-1);
imshow(Bound)
y1 = round(stats(1).BoundingBox(2))
y2 = round(stats(1).BoundingBox(2)+stats(1).BoundingBox(4)-1)
x1 = round(stats(1).BoundingBox(1))
x2 = round(stats(1).BoundingBox(1)+stats(1).BoundingBox(3)-1)
% Bounding box contida em imagem[M, N].
[M,N] = size(Bound)
vertical=0;
horizontal=0;
if M > N
vertical = 1 %imagem vertical
else
horizontal = 1 %imagem horizontal
end
%Find thumb
MaoLeft = 0;
MaoRight = 0;
nPixelsBrancos = 0;
if vertical==1
for i = x1:1:x2
for j= y1:1:y2
if I2(j,i) == 1
nPixelsBrancos = nPixelsBrancos + 1; %Numero de pixels da mão
end
end
end
for i=x1:1:x1+30
for j=y1:1:y2
if I2(j,i) == 1
MaoLeft = MaoLeft + 1; %Number of pixels of the hand between the 30 first colums
end
end
end
for i=x2-30:1:x2
for j=y1:1:y2
if I2(j,1) == 1
MaoRight = MaoRight + 1; %Number of pixels of the hand between the 30 last colums
end
end
end
TaxaBrancoLeft = MaoLeft/nPixelsBrancos
TaxaBrancoRight = MaoRight/nPixelsBrancos
if TaxaBrancoLeft <= (7/100)
if TaxaBrancoRight <= (7/100)
Thumb = 0 %Thumb in both borders is defined as no Thumb.
else
ThumbEsquerdo = 1 %Thumb on left
end
end
if TaxaBrancoRight <= (7/100) && TaxaBrancoLeft >= (7/100)
ThumbDireito = 1 %Thumb on right
end
end
if horizontal==1
for i = x1:1:x2
for j= y1:y2
if I2(i,j) == 1
nPixelsBrancos = nPixelsBrancos + 1; %Numero de pixels da mão
end
end
end
for i=x1:1:x2
for j=y1:1:y1+30
if I2(i,j) == 1
MaoLeft = MaoLeft + 1; %Numero de pixels da mão entre as 30 primeiras colunas
end
end
end
for i=x1:1:x2
for j=y2-30:1:y2
if I2(j,1) == 1
MaoRight = MaoRight + 1; %Numero de pixels da mão entre as 30 ultimas colunas
end
end
end
TaxaBrancoLeft = MaoLeft/nPixelsBrancos
TaxaBrancoRight = MaoRight/nPixelsBrancos
if TaxaBrancoLeft <= (7/100)
if TaxaBrancoRight <= (7/100)
Thumb = 0 %Polegar nas duas bordas. Definimos como sem polegar.
else
ThumbEsquerdo = 1 %Polegar na borda esquerda
end
end
if TaxaBrancoRight <= (7/100) && TaxaBrancoLeft >= (7/100)
ThumbDireito = 1 %Polegar na borda direita
end
end
figure
imshow(I2);
%detecção da centroid
Ibw = im2bw(I2);
Ilabel = bwlabel(Ibw);
stat = regionprops(Ilabel,'centroid');
figure
imshow(I2); hold on;
for x = 1: numel(stat)
plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro');
end
centroid = [stat(x).Centroid(1) stat(x).Centroid(2)] %coordenadas x e y da centroid
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Seemed like an interesting problem, so I gave it a shot. Basically you start with a Sobel filter to find the edges in your image (after slight denoising). Then clean up the resulting lines, use them to separate regions within your binary mask of the hand, use a watershed transform to find the wrist, some distance transforms to find other landmarks, then remove the palm. What you're left with is separate regions for each finger and thumb. You can count those regions easily enough or find which way they are pointing, or whatever you'd like.
imgURL = 'https://encrypted-tbn2.gstatic.com/imgs?q=tbn:ANd9GcRQsqJtlrOnSbJNTnj35Z0uG9BXsecX2AXn1vV0YDKodq-zSuqnnQ';
imgIn=imread(imgURL);
gaussfilt = fspecial('gaussian', 3, .5); % Blur starting image
blurImg = imfilter(double(img(:,:,1)), gaussfilt);
edgeImg = edge(blurImg, 'sobel'); % Use Sobel edge filter to pick out contours of hand + fingers
% Clean up contours
edgeImg = bwmorph(edgeImg, 'close', 1);
edgeImg = bwmorph(edgeImg, 'thin', Inf);
% Clean up rogue spots in corners
edgeImg([2 end-1], 2) = 0;
edgeImg([2 end-1], end-1) = 0;
% Extend lines to edge of image (correct for 'close' operation above
edgeImg([1 end],:) = edgeImg([2 end-1],:);
edgeImg(:, [1 end]) = edgeImg(:, [2 end-1]);
% Remove all but the longest line
regs = regionprops(edgeImg, 'Area', 'PixelIdxList');
regs(vertcat(regs.Area) ~= max(vertcat(regs.Area))) = [];
lineImg = false(size(edgeImg, 1), size(edgeImg, 2));
lineImg(regs.PixelIdxList) = 1;
fillImg = edgeImg;
% Close in wrist
if any(fillImg(1,:))
fillImg(1,:) = 1;
end
if any(fillImg(end,:))
fillImg(end,:) = 1;
end
if any(fillImg(:,1))
fillImg(:,1) = 1;
end
if any(fillImg(:,end))
fillImg(:,end) = 1;
end
fillImg = imfill(fillImg, 'holes');
fillImg([1 end], :) = 0;
fillImg(:, [1 end]) = 0;
fillImg([1 end],:) = fillImg([2 end-1],:);
fillImg(:, [1 end]) = fillImg(:, [2 end-1]);
% Start segmenting out hand + fingers
handBin = fillImg;
% Set lines in above image to 0 to separate closely-spaced fingers
handBin(lineImg) = 0;
% Erode these lines to make fingers a bit more separate
handBin = bwmorph(handBin, 'erode', 1);
% Segment out just hand (remove wrist)
distImg = bwdist(~handBin);
[cDx, cDy] = find(distImg == max(distImg(:)));
midWrist = distImg;
midWrist = max(midWrist(:)) - midWrist;
midWrist(distImg == 0) = Inf;
wristWatershed = watershed(imerode(midWrist, strel('disk', 10)));
whichRegion = wristWatershed(cDx, cDy);
handBin(wristWatershed ~= whichRegion) = 0;
regs = regionprops(handBin, 'Area', 'PixelIdxList');
regs(vertcat(regs.Area) ~= max(vertcat(regs.Area))) = [];
handOnly = zeros(size(handBin, 1), size(handBin, 2));
handOnly(regs.PixelIdxList) = 1;
% Find radius of circle around palm centroid that excludes wrist and splits
% fingers into separate regions.
% This is estimated as D = 1/3 * [(Centroid->Fingertip) + 2*(Centroid->Wrist)]
% Find Centroid-> Wrist distance
dist2w = wristWatershed ~= whichRegion;
dist2w = bwdist(dist2w);
distToWrist = dist2w(cDx, cDy);
% Find Centroid-> Fingertip distance
dist2FE = zeros(size(handOnly, 1), size(handOnly, 2));
dist2FE(cDx, cDy) = 1;
dist2FE = bwdist(dist2FE).*handOnly;
distToFingerEnd = max(dist2FE(:));
circRad = mean([distToFingerEnd, distToWrist, distToWrist]); % Estimage circle diameter
% Draw circle
X = bsxfun(#plus,(1:size(handOnly, 1))',zeros(1,size(handOnly, 2)));
Y = bsxfun(#plus,(1:size(handOnly, 2)),zeros(size(handOnly, 1),1));
B = sqrt(sum(bsxfun(#minus,cat(3,X,Y),reshape([cDx, cDy],1,1,[])).^2,3))<=circRad;
% Cut out binary mask within circle
handOnly(B) = 0;
% Label separate regions, where each now corresponds to a separate digit
fingerCount = bwlabel(handOnly);
% Display overlay image
figure()
imshow(imgIn)
hold on
overlayImg = imshow(label2rgb(fingerCount, 'jet', 'k'));
set(overlayImg, 'AlphaData', 0.5);
hold off
Results:
http://imgur.com/ySn1fPy

line equation for lane lines

i have to find the mid points of each lane in a binary iamge , i wrote a code but that is too long and its give error when ever i change the pic of road . i have to save the mid points of each lane and then by finding slope and intercept i have to draw lines on that binary image.
here is the code
x=imread('C:\users\guest\documents\matlab\1.png');
[q,r]= size(x);
n4=zeros(q,r);
midpoint= zeros (720,2); % Array to store midlle points of road lane.
% finding mid points of both lanes.
for n3=540:720
s=x(n3,:);
startIndex =1;
lastIndex =1280;
pixelsRow =s;
FirstWhiteStart=0; FirstWhiteEnd=0; SecondWhiteStart=0; SecondWhiteEnd=0;
for k=1:1280
if (pixelsRow(k) == 1)&&(FirstWhiteStart == 0)
FirstWhiteStart =k;
elseif (pixelsRow(k)==0)&&(FirstWhiteStart>0)&&(FirstWhiteEnd==0)
FirstWhiteEnd=k-1;
elseif (pixelsRow(k)== 1)&&(FirstWhiteEnd>0)&&(SecondWhiteStart==0)
SecondWhiteStart=k;
elseif (pixelsRow(k)==0)&&(SecondWhiteStart>0)&&(SecondWhiteEnd==0)
SecondWhiteEnd=k-1;
end
end
m1=(FirstWhiteStart + FirstWhiteEnd)./2; % first lanes middle point
m1r = round(m1);
if (m1r <= 1)
mp= sub2ind(size(midpoint),n3,1);
midpoint(mp) = 0;
elseif (m1r > 1)
indices = sub2ind(size(n4),n3,m1r);
n4(indices) = 1;
if (m1r >=640)
mp= sub2ind(size(midpoint),n3,2);
midpoint(mp) = m1r;
elseif (m1r <= 640)
mp= sub2ind(size(midpoint),n3,1);
midpoint(mp) = m1r;
end
end
m2=(SecondWhiteStart + SecondWhiteEnd+1)./2; % second lane middle point.
m2r = round(m2);
if (m2r <= 1)
indices = sub2ind(size(n4),n3,m2r);
n4(indices) = 0;
mp= sub2ind(size(midpoint),n3,1);
midpoint(mp) = 0;
elseif (m2r > 1)
indices = sub2ind(size(n4),n3,m2r);
n4(indices) = 1;
if (m2r >=640)
mp= sub2ind(size(midpoint),n3,2);
midpoint(mp) = m2r;
elseif (m2r <=640)
mp= sub2ind(size(midpoint),n3,1);
midpoint(mp) = m2r;
end
end
end
pairpoints = nchoosek([540:720],2);
var1 = zeros (16290,2); % array to store variables a and b of first lane.
var2 = zeros (16290,2); % array to stote variables a and b of second lane.
% calling middle points previously stored in array,putting in equation.
for n = 1 : 16290
x1 = pairpoints(n,1); %value of frst row
x2 = pairpoints(n,2); %value of 2nd row
y1 = midpoint (pairpoints(n,1), 1); %rows of midpoint matrix are specified from pairpoints location martix
y2 = midpoint (pairpoints(n,2), 1);
z1 = midpoint (pairpoints(n,1), 2);
z2 = midpoint (pairpoints(n,2), 2);
a1 = (y2 - y1) ./ (x2 - x1);
a2 = (z2 - z1) ./ (x2 - x1);
b1=(((x2)*(y1)) - (x1)*(y2)) ./ (x2 - x1);
b2=(((x2)*(z1)) - (x1)*(z2)) ./ (x2 - x1);
% variables a and b of first lane.
line = sub2ind(size(var1),n,1);
var1(line) = a1;
line = sub2ind(size(var1),n,2);
var1(line) = b1;
% variables A and b of second lane.
line = sub2ind(size(var2),n,1);
var2(line) = a2;
line = sub2ind(size(var2),n,2);
var2(line) = b2;
end
v11=round(var1);
v22=round(var2);
% eleminating zeros from array.
[i,j] = find(v11);
a1 = v11(i,1);
a1= a1(a1~=0);
b1 = v11(i,2);
b1= b1(b1~=0);
a11=median(a1)
b11=median(b1)
% eleminating zeros from array.
[k,l] = find(v22);
row = i;
a2 = v22(k,1);
a2= a2(a2~=0);
b2 = v22(k,2);
b2= b2(b2~=0);
a22=median(a2)
b22=median(b2)
%assign variables
lin=zeros(720,2);
% implementation of final line equation.
for x1 = 1:720
% equation becomes (w = eh + f) as actual was (y = ax + b)
y1 = (a11 * x1) + b11;
y2 = (a22 * x1) + b22;
col = sub2ind( size(lin),x1,1); % equation for first lane.
lin(col)= y1;
col = sub2ind( size(lin),x1,2); % equation for second lane.
lin(col)= y2;
end
array=lin;
r= 1:720;
c= 1:1280;
x(r,c)= 0;
imshow(x);
imwrite(x,'a.png');
image =imread('C:\users\guest\documents\matlab\a.png');
for r1 = 1:720
for c = 1:2;
if array(r1,c) < 0;
lin(r1,c) = abs (array(r1,c));
image(r1,lin(r1,c))= 0;
elseif array(r1,c) > 0;
image(r1,lin(r1,c))= 1;
end
end
end
imshow(image)

Filter points using hist in matlab

I have a vector. I want to remove outliers. I got bin and no of values in that bin. I want to remove all points based on the number of elements in each bin.
Data:
d1 =[
360.471912914169
505.084636471948
514.39429429184
505.285068055647
536.321181755858
503.025854206322
534.304229816684
393.387035881967
396.497969729985
520.592172434431
421.284713703215
420.401106087984
537.05330275495
396.715779872694
514.39429429184
404.442344469518
476.846474245118
599.020867750031
429.163139144079
514.941744277933
445.426761656729
531.013596812737
374.977332648255
364.660115724218
538.306752697753
519.042387479096
1412.54699036882
405.571202133485
516.606049132218
2289.49623498271
378.228766753667
504.730621222846
358.715764917016
462.339366699398
512.429858614816
394.778786157514
366
498.760463549388
366.552861126468
355.37022947906
358.308526273099
376.745272034036
366.934599077274
536.0901883079
483.01740134285
508.975480745389
365.629593988233
536.368800360349
557.024236456548
366.776498701866
501.007025898839
330.686029339009
508.395475983019
429.563732174866
2224.68806802212
534.655786464525
518.711297351426
534.304229816684
514.941744277933
420.32368479542
367.129404978681
525.626188464768
388.329756778952
1251.30895065927
525.626188464768
412.313764019587
513.697381733643
506.675438520558
1517.71183364959
550.276294237722
543.359917550053
500.639590923451
395.129864728041];
Histogram computation:
[nelements,centers] = hist(d1);
nelements=55 13 0 0 1 1 1 0 0 2
I want to remove all points apearing less than 5 (in nelements). It means only first 2 elements in nelements( 55, 13 ) remains.
Is there any function in matlab.
You can do it along these lines:
threshold = 5;
bin_halfwidth = (centers(2)-centers(1))/2;
keep = ~any(abs(bsxfun(#minus, d1, centers(nelements<threshold))) < bin_halfwidth , 2);
d1_keep = d1(keep);
Does this do what you want?
binwidth = centers(2)-centers(1);
centersOfRemainingBins = centers(nelements>5);
remainingvals = false(length(d1),1);
for ii = 1:length(centersOfRemainingBins )
remainingvals = remainingvals | (d1>centersOfRemainingBins (ii)-binwidth/2 & d1<centersOfRemainingBins (ii)+binwidth/2);
end
d_out = d1(remainingvals);
I don't know Matlab function for this problem, but I think, that function with follow code is what are you looking for:
sizeData = size(data);
function filter_hist = filter_hist(data, binCountRemove)
if or(max(sizeData) == 0, binCountRemove < 1)
disp('Error input!');
filter_hist = [];
return;
end
[n, c] = hist(data);
sizeN = size(n);
intervalSize = c(2) - c(1);
if sizeData(1) > sizeData(2)
temp = transpose(data);
else
temp = data;
end
for i = 1:1:max(sizeN)
if n(i) < binCountRemove
a = c(i) - intervalSize / 2;
b = c(i) + intervalSize / 2;
sizeTemp = size(temp);
removeInds = [];
k = 0;
for j = 1:1:max(sizeTemp)
if and(temp(j) > a, less_equal(temp(j), b) == 1)
k = k + 1;
removeInds(k) = j;
end
end
temp(removeInds) = [];
end
end
filter_hist = transpose(temp);
%Determines when 'a' less or equal to 'b' by accuracy
function less_equal = less_equal(a, b)
delta = 10^-6; %Accuracy
if a < b
less_equal = 1;
return;
end
if abs(b - a) < delta
less_equal = 1;
return;
end
less_equal = 0;
You can do something like this
nelements=nelements((nelements >5))