How do I rotate image within an image? - matlab

I am trying to develop a program that will superimpose a 100x100 pixel image onto a 200x200 pixel background. The user will be prompted to move the smaller image (left,right,up,down) and/or rotate CCW/CW by an arbitrary theta val. My question is simply, 'how do you rotate the smaller image within the larger?'. I have tried using imrotate on the smaller image, and having the larger equal to the smaller vals.
Thanks
a = zeros(15);
b = a(7:9,7:9);
b(:) = 1; %initialize b matrix to ones
a(7:9,7:9) = b; %center matrix
n = 1;
while n ~= 0
n = input('PLLRAFM Aligner\n Please enter a command to align image.\n 8: up\n 2: down\n 4: left\n 6: right\n 7: rotate CCW\n 9: rotate CW\n 0: save image\n');
switch n
case 8 %up
index = sub2ind(size(a),find(a == 1));
[row, col] = ind2sub(size(a),index);
a = zeros(15);
row = row - 1;
a(row,col) = 1;
figure(2)
imagesc(a)
case 2 %down
index = sub2ind(size(a),find(a == 1));
[row, col] = ind2sub(size(a),index);
a = zeros(15);
row = row + 1;
a(row,col) = 1;
figure(2)
imagesc(a)
case 4 %left
index = sub2ind(size(a),find(a == 1));
[row, col] = ind2sub(size(a),index);
a = zeros(15);
col = col - 1;
a(row,col) = 1;
figure(2)
imagesc(a)
case 6 %right
index = sub2ind(size(a),find(a == 1));
[row, col] = ind2sub(size(a),index);
a = zeros(15);
col = col + 1;
a(row,col) = 1;
figure(2)
imagesc(a)
case 7 %rotate CCW
index = sub2ind(size(a),find(a == 1));
theta = 45; %temporary rotation of 1 degree
imrotate(b,theta);
a(b) = 1;
figure(2)
imagesc(a)
case 9 %rotate CW
% index = sub2ind(size(a),find(a == 1));
% [row, col] = ind2sub(size(a),index);
% theta = 45; %temporary rotation of 1 degree
% b = imrotate(a(row,col),theta);
% figure(2)
% imagesc(a)
otherwise
fprintf('Please try again.');
end
end
I would like to rotate this yellow block by 45 degrees for testing.

This should do what you want, if I understood you correctly:
a=zeros(15);
b=ones(3);
b=imrotate(b,45);
a(ceil(length(a)/2)-floor(length(b)/2):ceil(length(a)/2)+floor(length(b)/2),...
ceil(length(a)/2)-floor(length(b)/2):ceil(length(a)/2)+floor(length(b)/2))=b;
imagesc(a);

Related

binary mask for the coordinates using 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)

How to draw a svm splitting line in matlab by contour?

I want to draw a curved line to split these binary points by contour. Suppose I've found all "svm" points and other's arguments like these:
X = [0.8169,1.3179;
1.5769,1.6961;
0.8577,1.8586;
0.8186,2.4992;
2.1778,0.9407;
1.1385,0.7873;
-0.6291,2.4245;
1.1454,1.0360;
1.6432,1.2201;
0.9730,2.1020;
2.7943,0.2780;
2.4555,0.7790;]
Y = [-1;
-1;
1;
-1;
1;
1;
1;
1;
-1;
-1;
-1;
-1;]
alpha = [ 100.0000;
12.6706;
100.0000;
8.4964;
100.0000;
20.4036;
1.1586;
51.9297;
63.0729;
38.1640;
35.2393;
15.8488;]
b = 3.080277010242503
C = 100
margin = 0.032448872572666
But i get this result.
How can i get the curved line to split these binary points by contour?
These are my codes.
plot(X(find(Y>0),1), X(find(Y>0),2), 'bx', X(find(Y<0),1), X(find(Y<0),2), 'k.');
axis([-3 8 -3 8]);
title('soft SVM')
hold on
[x1, x2] = meshgrid(-2:0.1:7, -2:0.1:7);
[rows, cols] = size(x1);
nt = rows * cols;
Xt = [reshape(x1,1,nt); reshape(x2,1,nt)];
Z = sign(sum(bsxfun(#times, alpha .* Y, (X+margin)*(Xt+margin) )) + b);
Z = reshape(Z, rows, cols);
contour(x1,x2,Z,[0 0],'m');
hold off

Random Walk, simplifying the code

I am currently practicing modelling "random walks" and population modelling. I have a working code that works for a 1D random walk, in the future I'd like to add extra dimensions and I think the code I have at the moment would make it more difficult. I need to plot the first two positions before I can start the for loop. Ideally I would like to get rid of that issue and have it start from the first step.
numjumps = 20; %number of steps
R = 0.5; %probability of step to right
more off
prev_position = [0 0]; %first position
x = rand(1); %generate random number 0-1
if x >= R;
step = 1; %take a step to the right
elseif x < R
step = -1; %take a step to the left
end
position = [1 prev_position(2) + step];
close all;
figure;
hold on;
plot([prev_position(1) position(1)], [prev_position(2) position(2)]);
axis([0 numjumps -5 5])
for i = (2:numjumps);
prev_position(i) = position(i-1);
x = rand(1); %generate random number 0-1
if x >= R;
step = 1; %take a step to the right
elseif x < R
step = -1; %take a step to the left
end
position(i) = [prev_position(i) + step]; %add step to position
plot(position);
axis([0 numjumps -5 5])
end
total = sum(position);
mean_position = total/numjumps;
disp(mean_position);
Any help would be greatly appreciated.
You shouldn't use a for loop, just vectorize your code:
numjumps = 20; %number of steps
R = 0.5; %probability of step to right
x = rand (numjumps, 1);
step = 2 * (x >= R) - 1;
position = [0; cumsum(step)];
plot (position)
now it's easy to make it 2D:
numjumps = 200; %number of steps
R = 0.5; %probability of step to right
x = rand (numjumps, 2);
step = 2 * (x >= R) - 1;
position = [0, 0; cumsum(step)];
plot (position(:, 1), position (:, 2))
gives

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

generate a matrix image after having all the balck pixel's coordinates with MatLab

I have an Image, converted into binary, i got all the black pixel's coordinates.
The 'matrix' contains the x and y coordinates arranged by columns.
Now i Need to make a Simulation, to see if my Programme works.
I have to generate an Matrix Image with my results.
im=imread('square.jpg');
imshow(im); c=im2bw(im); figure; imshow(c);
dim = size(c) % size of the image
x = [];
y = [];
xdif = [];
newx = [];
matrix = [];
for i = 1:dim(1)
for j = 1:dim(2)
if c(i,j)==0;
x = [x i];
y = [y j];
end
end
end
% show black pixel's coordinates
p = [x;y];
%number of pixels
nr = length(x)
dimp = size(p);
xval = p(1,:);
yval = p(2,:);
j=1;
i=1;
for z = 1:dimp(2)-1
xdif = xval(z+1)-xval(z);
ff=find(xdif > 0);
if ff == 1
i = 1;
else
i=i+1;
end
newx(i,j)= xval(z);
newy(i,j)= yval(z);
if ff == 1
j= j+1;
end
end
xsize = size(newx);
ysize = size(newy);
matrix_size = xsize(2)+ysize(2)
xinc = 1;
yinc = 1;
x=1;
for ct = 1:1:matrix_size/2
x;
matrix(:,x) = newx(:,xinc);
matrix(:,x+1) = newy(:,yinc);
matrix;
xinc = xinc+1;
yinc = yinc+1;
x=x+3;
end
matrix
this is my Programme, now i need to make a simulation, by generating an image with my coordinates.
how can i do that?
thank's