I created a 3D stick man walking in matlab and I want to add an image as the floor that he is walking on. I'm not sure how to go about doing this. I looked at an example of someone adding an image as a background. That is kinda what I want but I want it to appear as the floor. I going to give the stick man a trajectory and make him walk across the floor. Can anyone point me in the right direction.
Ok now I got it thanks to Andrey.
clear all
cyl = UnitCylinder(2);
sph = UnitSphere(2);
% Head
L1 = 2;
Head = translate(scale(sph,L1/2, L1/2, L1/2),0,0,L1+4.5);
Head.facecolor = 'yellow';
%Shoulder
r2 = 0.3;
L2 = 3;
Shoulder = translate(rotateX(scale(cyl,r2/2,r2/2,L2/2),90),0,0,5);
Shoulder.facecolor = 'red';
%Left Upper Arm
w1_s = [-20:4:20 20:-4:-20];
r3 = 0.3;
L3 = 2;
Upper_Arm_left = translate(scale(cyl,r3/2,r3/2,L3/2),0,0,-L3/2);
Upper_Arm_left.facecolor = 'red';
%Right Upper Arm
Upper_Arm_right = translate(scale(cyl,r3/2,r3/2,L3/2),0,0,-L3/2);
Upper_Arm_right.facecolor = 'red';
%Left Forearm
w2_s = [-5:1:5 5:-1:-5];
L3_f = 2.5;
Fore_Arm_left = translate(scale(cyl,r3/2,r3/2,L3_f/2),0,0,-L3_f/2);
Fore_Arm_left.facecolor = 'red';
%Right Forearm
Fore_Arm_right = translate(scale(cyl,r3/2,r3/2,L3_f/2),0,0,-L3_f/2);
Fore_Arm_right.facecolor = 'red';
%Chest
r4 = 2;
L4 = 2;
Chest = translate(scale(cyl,r4/2,r4/2,L4/2),0, 0, 5-L4/2);
Chest.facecolor = 'yellow';
%Weist
r5 = 1;
L5 = 2;
Weist = translate(scale(cyl,r5/2,r5/2,L5/2),0, 0, 5-L4-L5/2);
Weist.facecolor = 'yellow';
%Hip
L6 = 1.5;
Hip = translate(rotateX(scale(cyl,r2/2,r2/2,L6/2),90),0,0,5-L4-L5-r2/2);
Hip.facecolor = 'green';
%Left Upper Leg
r7 = 0.4;
L7 = 2.5;
L71 = (L6/2+r7/2);
L72 = 5-L7/2-L4-L5;
Upper_Leg_left = translate(scale(cyl,r7/2,r7/2,L7/2),0,0,-L7/2);
Upper_Leg_left.facecolor = 'green';
%Right Upper Leg
Upper_Leg_right = translate(scale(cyl,r7/2,r7/2,L7/2),0,0,-L7/2);
Upper_Leg_right.facecolor = 'green';
%Left Lower Leg
L7_f = 3;
Lower_Leg_left = translate(scale(cyl,r7/2,r7/2,L7_f/2),0,0,-L7_f/2);
Lower_Leg_left.facecolor = 'green';
%Right Lower Leg
Lower_Leg_right = translate(scale(cyl,r7/2,r7/2,L7_f/2),0,0,-L7_f/2);
Lower_Leg_right.facecolor = 'green';
angle1 = 0;
angle2 = 0;
for i = 1:120
angle1 = w1_s(rem(i,length(w1_s))+1);
angle2 = w2_s(rem(i,length(w1_s))+1);
Arm_left = combine(translate(rotateY(Fore_Arm_left,angle2),0,0,-L3), Upper_Arm_left);
Arm_right = combine(translate(rotateY(Fore_Arm_right,-angle2),0,0,-L3), Upper_Arm_right);
Arm_left = translate(rotateY(Arm_left,angle1),0,-L2/2,(5-L3/2)+L3/2);
Arm_right = translate(rotateY(Arm_right,-angle1),0,L2/2,(5-L3/2)+L3/2);
Leg_left = combine(translate(rotateY(Lower_Leg_left,-angle2),0,0,-L7), Upper_Leg_left);
Leg_right = combine(translate(rotateY(Lower_Leg_right,angle2),0,0,-L7), Upper_Leg_right);
Leg_left = translate(rotateY(Leg_left,-angle1),0,-L71,L72+L7/2);
Leg_right = translate(rotateY(Leg_right,angle1),0,L71,L72+L7/2);
Upper_Body = combine(Head, Shoulder, Arm_left, Arm_right, Chest, Weist);
Lower_Body = combine(Hip, Leg_left, Leg_right);
walker = combine(Upper_Body, Lower_Body);
cla
img = imread('peppers.png');
[X,Y] = ndgrid([-10 10],[-10 10]);
zImage = [-5 -5; -5 -5];
surf(X,Y,zImage,'CData',img,'FaceColor','texturemap');
% view([1 1 1]);
hold on
view(3)
set(gca,'xlim',[-10 10],'ylim',[-10 10],'zlim',[-6 6]);
renderpatch(walker);
camlight
box on
drawnow
pause(0.04)
end
I want to get something like this floor but I don't know how to do it. This person used a .fig in their code.This is a piece of what they used.
F1 = open('background1.fig');
background_gca = gca;
F2 = figure(2);
.
.
.
clf(F2)
copyobj(background_gca,F2);
view([-40,25])
set(gca,'xlim',[-5 5],'ylim',[-5 5],'zlim',[0 10]);
renderpatch(walker);
camlight
box on
% axis off
drawnow;
You had a small syntax error:
First, you reversed z and y :
surf(xImage,zImage,yImage,...)
Also, you should think about surf as a surface. Thus, all z should be 0
img = imread('peppers.png');
[X,Y] = ndgrid([-5 5],[-5 5]);
zImage = [0 0; 0 0];
surf(X,Y,zImage,'CData',img,'FaceColor','texturemap');
view([1 1 1]);
make that background image as GIF image, it feels like man walking on floor
otherwise visit here, useful video:http://www.youtube.com/watch?v=Ztb6_kIkXb8
Related
I have written a code in MATLAB which allows me to automatically crop regions of interest in one image, and perform cross-correlation with a second image. The correlated regions are identified by a quiver plot, which I would like to extend across the two images (they are arranged in a vertical montage). However, the quiver arrows appear only in the upper image.
Would anyone know why this happens (and how to fix it)? Hopefully it's something straightforward. I've included some of my code below. Thanks!
Initial = rgb2gray(imread('img9.png'));
Secondary = rgb2gray(imread('img8.png'));
XC = imcrop(Initial, [0 0 1300 350]);
YC = imcrop(Secondary, [0 0 1300 350]);
Multi = cat(1,XC,YC);
VertLinSpace1 = linspace(0, 300, 7);
HorzLinSpace1 = linspace(0, 1250, 24);
imshow(Multi)
axis( [0 1300 0 700])
axis on
for k1 = 1:length(VertLinSpace1)
for k2 = 1:length(HorzLinSpace1)
template = imcrop(Multi, [HorzLinSpace1(k2) VertLinSpace1(k1), 50 50]);
c = normxcorr2(template,YC);
[ypeak, xpeak] = find(c==max(c(:)));
yO = ypeak-size(template,1);
xO = xpeak-size(template,2);
x1 = HorzLinSpace1(k2); y1 = VertLinSpace1(k1); x2 = xO+1; y2 = yO+1;
a = [x1, y1, 0];
b = [x2, y2, 0];
Q = [x1 y1
x2 y2];
QX = Q(:,1);
QY = Q(:,2);
[~,UV] = gradient(Q);
UVX = [UV(1,1); 0];
UVY = [UV(1,2); 0];
figure(1)
hold on
quiver(QX, QY, UVX, UVY, 'color','red')
hold off
end
end
Initial image
Comparison image
I simplified the arrow XY computation, but the essence was to add 350 to point down to the second half. I added 25 to indicate the middle of the template (the tail of the arrows). This may not be 100% accurate solution, because, for example, the middle of a 50 by 50 pixel square is 25.5 (25 pixels on either side) but it solves the main issue and you can take it from here.
Initial = rgb2gray(imread('https://i.stack.imgur.com/5fTa1.png'));
Secondary = rgb2gray(imread(('https://i.stack.imgur.com/sg1co.png')));
XC = imcrop(Initial, [0 0 1300 350]);
YC = imcrop(Secondary, [0 0 1300 350]);
Multi = cat(1,XC,YC);
VertLinSpace1 = linspace(0, 300, 7);
HorzLinSpace1 = linspace(0, 1250, 24);
imshow(Multi)
axis( [0 1300 0 700])
axis on
hold on
counter = 0;
for kV = 1:length(VertLinSpace1)
for kH = 1:length(HorzLinSpace1)
template = imcrop(Multi, [HorzLinSpace1(kH) VertLinSpace1(kV), 50 50]);
c = normxcorr2(template,YC);
[ypeak, xpeak] = find(c==max(c(:)));
fromXY = [HorzLinSpace1(kH)+25,VertLinSpace1(kV)+25];
addXY = [xpeak-fromXY(1),350+ypeak-fromXY(2)];
quiver(fromXY(1), fromXY(2), addXY(1), addXY(2), 'color','red')
drawnow
end
end
I am working on visualizing some stability areas of Runge Kutta Methods. now i have the issue, that i cant 'flip' the colours in the colormap.. I've been researching and trying out possible solutions..but all did not work. hope you guys can help me :)
here is my code:
function [g] = butcher(s1,c1,b1)
x0 = -3;
x1 = 3;
Nx = 301;
y0 = -3;
y1 = 3;
Ny = 301;
xv = linspace(x0,x1,Nx);
yv = linspace(y0,y1,Ny);
[x,y] = meshgrid(xv,yv);
z = x + i*y;
g=1+z*b1.*(1./(1-z*c1))*1;
gmag=abs(g);
contourf(x,y,gmag,[1 1],'k-');
cmap=flipud(colormap(gray));
colormap(cmap);
%colormap(flipud('gray'));
grid on;
axis equal;
end
I have lena image in Matlab. First I need to find the centroid C, and then divide the image into equal number of parts. I can calculate the centroid of the image but from that how can I divide the image into equal number of parts as shown below. Please anyone help me.
Thanks
Using poly2mask to create binary sectors and using the resulting sectors for indexing
Code:
im = imread('peppers.png');
r = 300;
out1 = ones(max(size(im,1),r*2)+2,max(size(im,2),r*2)+2,3).*255;
xoffset = floor((size(out1,2)-size(im,2))/2);
yoffset = floor((size(out1,1)-size(im,1))/2);
out1(yoffset:yoffset+size(im,1)-1,xoffset:xoffset+size(im,2)-1,:) = im(:,:,:);
im = out1;
cy = floor(size(im,1)/2);
cx = floor(size(im,2)/2);
figure;
imshow(uint8(im));
hold on
pos = [cx-r+1 cy-r+1 r*2 r*2];
rectangle('Position',pos,'Curvature',[1 1]);
x1 = [-r, 0, -r*cosd(45), -r*cosd(45); r, 0, r*cosd(45), r*cosd(45)]+cx+1;
y1 = [0, -r, -r*sind(45), r*sind(45); 0, r, r*sind(45), -r*sind(45)]+cy+1;
plot(x1,y1);
hold off
figure;
for i = 0:45:315
t = linspace(-i,-i-45,128);
x = [cx, cx+r*cosd(t), cx];
y = [cy, cy+r*sind(t), cy];
bw = poly2mask( x, y, size(im,1),size(im,2));
bw = repmat(bw,1,1,3);
out = ones(size(im,1),size(im,2),size(im,3)).*155;
out(bw) = im(bw);
subplot(2,4,(i/45)+1); imshow(uint8(out));
end;
Results:
Original Image
Partitions drawn over Original Image
Segments of the image
Update
for getting pixel values of the lines, by using Bresenham function from here
figure;
bw1 = zeros(size(im,1),size(im,2));
outmat = zeros(size(bw1));
[X,Y] = bresenham(cx+1-r,cy+1,cx+1+r,cy+1);
ind = sub2ind(size(outmat), Y, X);
outmat(ind) = 1;
[X,Y] = bresenham(cx+1,cy+1-r,cx+1,cy+1+r);
ind = sub2ind(size(outmat), Y, X);
outmat(ind) = 1;
[X,Y] = bresenham(cx+1-r*cosd(45),cy+1-r*sind(45),cx+1+r*cosd(45),cy+1+r*sind(45));
ind = sub2ind(size(outmat), Y, X);
outmat(ind) = 1;
[X,Y] = bresenham(cx+1-r*cosd(45),cy+1+r*sind(45),cx+1+r*cosd(45),cy+1-r*sind(45));
ind = sub2ind(size(outmat), Y, X);
outmat(ind) = 1;
se = strel('disk',5); %// change the '5' value to affect thickness of the line
outmat = imdilate(outmat,se);
outmat = repmat(boolean(outmat),1,1,3);
outmat1 = zeros(size(outmat));
outmat1(outmat) = im(outmat);
imshow(uint8(outmat1));
Pixel values under each lines
Check the following code. I just did it for a grayscale image. You can now change it to a color image as well. Check and pls confirm this is what you wanted.
clear all;
i = rgb2gray(imread('hestain.png'));
imshow(i);
cr = floor(size(i,1)/2);
cl = floor(size(i,2)/2);
r = min(cr, cl);
a = 90;
r1 = cr;
c1 = size(i,2);
v1=[c1 r1]-[cl cr];
i2 = zeros(size(i,1),size(i,2),ceil(360/a));
for ri = 1:size(i,1)
for ci = 1:size(i,2)
v2=[ci ri]-[cl cr];
a2 = mod(-atan2(v1(1)*v2(2)-v1(2)*v2(1), v1*v2'), 2*pi) * 180/pi;
d2 = pdist([ci ri; cl cr],'euclidean');
if d2<=r
if ceil(a2/a)==0
a2 =1;
end
i2(ri,ci,ceil(a2/a)) = i(ri,ci);
end
end
end
figure;
for i=1:360/a
subplot(2,180/a,i);
imshow(mat2gray(i2(:,:,i)));
end
Sample output:
I load a model with vertex and vertex nromal,
for (var i = 0, vindex = 0; i < triangle.length; i++, vindex += 3) {
x = parseFloat(triangle[i].attributes.getNamedItem('x1').value);
y = parseFloat(triangle[i].attributes.getNamedItem('y1').value);
z = parseFloat(triangle[i].attributes.getNamedItem('z1').value);
this.geometry.vertices.push(new THREE.Vector3(x * scale + this.translateVector.x, y * scale + this.translateVector.y, z * scale + this.translateVector.z));
x = parseFloat(triangle[i].attributes.getNamedItem('x2').value);
y = parseFloat(triangle[i].attributes.getNamedItem('y2').value);
z = parseFloat(triangle[i].attributes.getNamedItem('z2').value);
this.geometry.vertices.push(new THREE.Vector3(x * scale + this.translateVector.x, y * scale + this.translateVector.y, z * scale + this.translateVector.z));
x = parseFloat(triangle[i].attributes.getNamedItem('x3').value);
y = parseFloat(triangle[i].attributes.getNamedItem('y3').value);
z = parseFloat(triangle[i].attributes.getNamedItem('z3').value);
this.geometry.vertices.push(new THREE.Vector3(x * scale + this.translateVector.x, y * scale + this.translateVector.y, z * scale + this.translateVector.z));
var face = new THREE.Face3(vindex, vindex + 1, vindex + 2);
face.color.setHex(this.faceColor || this.defaultcolor);
face.vertexNormals = [];
nx = parseFloat(triangle[i].attributes.getNamedItem('nx1').value);
ny = parseFloat(triangle[i].attributes.getNamedItem('ny1').value);
nz = parseFloat(triangle[i].attributes.getNamedItem('nz1').value);
face.vertexNormals.push(new THREE.Vector3(-nx, -ny, -nz));
nx1 = parseFloat(triangle[i].attributes.getNamedItem('nx2').value);
ny1 = parseFloat(triangle[i].attributes.getNamedItem('ny2').value);
nz1 = parseFloat(triangle[i].attributes.getNamedItem('nz2').value);
face.vertexNormals.push(new THREE.Vector3(-nx1, -ny1, -nz1));
nx2 = parseFloat(triangle[i].attributes.getNamedItem('nx3').value);
ny2 = parseFloat(triangle[i].attributes.getNamedItem('ny3').value);
nz2 = parseFloat(triangle[i].attributes.getNamedItem('nz3').value);
face.vertexNormals.push(new THREE.Vector3(-nx2, -ny2, -nz2));
face.normal.set((nx + nx1 + nx2) / 3, (ny + ny1 + ny2) / 3,(nz + nz1 + nz2) / 3);
this.geometry.faces.push(face);
}
this.material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, overdraw: true , opacity: 1, transparent: 0 });
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.name = this.id;
this.mesh.updateMatrix();
this.mesh.matrixAutoUpdate = false;
scene.add(this.mesh);
the house below, front face is invisible, so front wall and left wall is invisible, we can see through the inside of house, but I want it to show all walls and not see through, could anyone help me?
after I change to Lambert material it still show house inside, I've tried, cw,ccw, or invert index of vertex, invert normal. could any body help?
it is possible there is something wrong with the face UV's. try making the material applied doublesided.
seems find the answer.
that's because part of the house model position.z < 0, and camera's near < 0, maybe three.js z-buffer clear negative = 0, z-buffer determines the sheltery relation.
I am using the following code in MATLAB to find the rectangle containing a car's license plate:
clc
clear
close all
%Open Image
I = imread('plate_1.jpg');
figure, imshow(I);
%Gray Image
Ib = rgb2gray(I);
figure,
subplot(1,2,1), imshow(Ib);
%Enhancement
Ih = histeq(Ib);
subplot(1,2,2), imshow(Ih);
figure,
subplot(1,2,1), imhist(Ib);
subplot(1,2,2), imhist(Ih);
%Edge Detection
Ie = edge(Ih, 'sobel');
figure,
subplot(1,2,1), imshow(Ie);
%Dilation
Id = imdilate(Ie, strel('diamond', 1));
subplot(1,2,2), imshow(Id);
%Fill
If = imfill(Id, 'holes');
figure, imshow(If);
%Find Plate
[lab, n] = bwlabel(If);
regions = regionprops(lab, 'All');
regionsCount = size(regions, 1) ;
for i = 1:regionsCount
region = regions(i);
RectangleOfChoice = region.BoundingBox;
PlateExtent = region.Extent;
PlateStartX = fix(RectangleOfChoice(1));
PlateStartY = fix(RectangleOfChoice(2));
PlateWidth = fix(RectangleOfChoice(3));
PlateHeight = fix(RectangleOfChoice(4));
if PlateWidth >= PlateHeight*3 && PlateExtent >= 0.7
im2 = imcrop(I, RectangleOfChoice);
figure, imshow(im2);
end
end
Plates all have white backgrounds. Currently,I use the rectangles' ratio of width to height to select candidate regions for output. This gives the plate rectangle in addition to several other irrelevant ones in the case of a white car. What method can I use to get only one output: the license plate?
Also, I don't find a plate at all when I run the code on a black car. Maybe that's because the car's color is the same as the plate edge.
Are there any alternatives to edge detection to avoid this problem?
Try this !!!
I = imread('http://8pic.ir/images/88146564605446812704.jpg');
im=rgb2gray(I);
sigma=1;
f=zeros(128,128);
f(32:96,32:96)=255;
[g3, t3]=edge(im, 'canny', [0.04 0.10], sigma);
se=strel('rectangle', [1 1]);
BWimage=imerode(g3,se);
gg = imclearborder(BWimage,8);
bw = bwareaopen(gg,200);
gg1 = imclearborder(bw,26);
imshow(gg1);
%Dilation
Id = imdilate(gg1, strel('diamond', 1));
imshow(Id);
%Fill
If = imfill(Id, 'holes');
imshow(If);
%Find Plate
[lab, n] = bwlabel(If);
regions = regionprops(lab, 'All');
regionsCount = size(regions, 1) ;
for i = 1:regionsCount
region = regions(i);
RectangleOfChoice = region.BoundingBox;
PlateExtent = region.Extent;
PlateStartX = fix(RectangleOfChoice(1));
PlateStartY = fix(RectangleOfChoice(2));
PlateWidth = fix(RectangleOfChoice(3));
PlateHeight = fix(RectangleOfChoice(4));
if PlateWidth >= PlateHeight*1 && PlateExtent >= 0.7
im2 = imcrop(I, RectangleOfChoice);
%figure, imshow(I);
figure, imshow(im2);
end
end