Bending a plane into a conical surface - matlab

I am currently trying to compute Origami structures on Matlab, and I am looking for a method to bend my crease patterns on a conical surface, in the same way that this answer : Bending a plane into a closed surface/cylinder into a cylinder.
How can I do this, please ?
Cheers,

You should just have to map an (x,y) coordinate into a 3D coordinate for a conical surface. So to do this, it is important to parametrize a conical surface as a function of two variables. Thus:
( r, theta, z ) = ( a * z + c, theta, z ) for some a,c you define
Then you just need to create a relationship between (x,y) and (theta,z) so you can find a given (theta,z) as a function of (x,y). Then it comes down to a simple set of for loops to iterate through the (x,y) points to find the mapped coordinates on the conical surface.
=== Edit ===
So I wrote some codes to illustrate how simple the mapping can be. First, here are some images. The first is the planar mesh that will be mapped, and the second image is the result.
% This is file: gen_mesh.m
function [x, y, tri_mesh] = gen_mesh()
% Initialize output coordinates of points that make up the mesh
y = [];
x = [];
% Initialize mesh
tri_mesh= [];
% Number of points in the x dimension
Nx = 5;
% Number of points in the y dimension
Ny = 17;
% For this mesh, make each row have a slightly
% different number of points
x1 = linspace(0,1,Nx);
dx = x1(2)-x1(1);
x2 = linspace(dx/2, 1-dx/2, Nx-1);
% Create the array with the y values
y1 = linspace(0,1,Ny);
%% Generate the associated (x,y) pairs
for iy = 1:Ny
if( mod(iy,2) == 0 )
y = [y, ones(1,Nx-1)*y1(iy)];
x = [x, x2];
else
y = [y, ones(1,Nx)*y1(iy)];
x = [x, x1];
end
end
%% Generate the Mesh of triangles
% Make sure that the mesh wraps to each
% opposite x bound. This is to make sure that
% the cyclic nature of the conical surface
% doesnt mess up the look of the mesh
count = 1;
curr = 1;
ol = [];
el = [];
for iy = 1:Ny
if( mod(iy, 2) == 0 )
el.x = x(curr:curr+(Nx-2));
el.y = y(curr:curr+(Nx-2));
else
ol.x = x(curr:curr + Nx - 1);
ol.y = y(curr:curr + Nx - 1);
end
if( iy ~= 1 )
for i = 2:Nx
tri_mesh(count).x = [ol.x(i), el.x(i-1), ol.x(i-1)];
tri_mesh(count).y = [ol.y(i), el.y(i-1), ol.y(i-1)];
count = count + 1;
end
for i = 2:(Nx-1)
tri_mesh(count).x = [el.x(i), ol.x(i), el.x(i-1)];
tri_mesh(count).y = [el.y(i), ol.y(i), el.y(i-1)];
count = count + 1;
end
tri_mesh(count).x = [el.x(1), ol.x(1), el.x(end)];
tri_mesh(count).y = [el.y(1), ol.y(1), el.y(end)];
count = count + 1;
end
if( mod(iy, 2) == 0 )
curr = curr + (Nx-1);
else
curr = curr + Nx;
end
end
end
% This is file: map_2D_to_3DCone.m
function [xh, yh, z] = map_2D_to_3DCone( x, x_rng, y, y_rng )
% x: an array of x values part of a planar coordinate
%
% x_rng: the smallest and largest possible x values in the planar domain
% -> x_rng = [min_x, max_x]
%
% y: an array of y values part of a planar coordinate
%
% y_rng: the smallest and largest possible y values in the planar domain
% -> y_rng = [min_y, max_y]
% The bottom z (height) value
zb = 0;
% The top z value
zt = 1;
% The radius value at z = zb
rb = 3;
% The radius value at z = zt
rt = 1;
%% Obtain the Conical Surface 3D coordinates
% Find z as a function of y in the planar domain
% This mapping is a simple 1-D Lagrange interpolation
z = (zt*( y - y_rng(1) ) - zb*( y - y_rng(2) ))/(diff(y_rng));
% Find the parametrized angle as a function of x
% using a 1D Lagrange interpolation
theta = 2*pi*( x - x_rng(1) )/(diff(x_rng));
% Find the radius as a function of z using
% a simple 1D legrange interpolation
r = ( rt*(z - zb) - rb*(z - zt) )/( zt - zb );
% Find the absolute x and y components of the
% 3D conical coordinates
xh = r.*cos(theta);
yh = r.*sin(theta);
end
% This is in file: PlaneMesh_to_ConicalMesh.m
function mesh3d = PlaneMesh_to_ConicalMesh( mesh2d )
% Generate the 3D version of each planar triangle, based
% on the mapping function that takes an (x,y) planar
% coordinate and maps it onto a conical surface
N = length(mesh2d);
mesh3d(N).x = [];
mesh3d(N).y = [];
mesh3d(N).z = [];
for i = 1:N
[xh, yh, z] = map_2D_to_3DCone( mesh2d(i).x, [0,1], mesh2d(i).y, [0,1] );
mesh3d(i).x = xh;
mesh3d(i).y = yh;
mesh3d(i).z = z;
end
end
% This is in file: gen3D_MappedCone.m
% Generate the 3D object
close all
% Generate a 2D planar mesh to morph onto
% a conical surface
[x, y, mesh2d] = gen_mesh();
% Map the 2D mesh into a 3D one based on the
% planar to conical surface mapping
mesh3d = PlaneMesh_to_ConicalMesh( mesh2d );
% Obtain the number of triangles making up
% the mesh
N = length(mesh3d);
% Define a color mapping function for the sake
% of visualizing the mapping
color_map = #(x) [1, 0, 0].*(1-x) + [0, 0, 1].*x;
% Create the first image based on the planar
% mesh
figure(1)
hold on
for i = 1:N
color = color_map( (i-1)/(N-1) );
h = fill( mesh2d(i).x,mesh2d(i).y, color );
set(h, 'facealpha',0.9)
end
axis([0,1,0,1])
% Create the next figure showing the 3D mesh
% based on the planar to conical surface transformation
figure(2)
hold on
for i = 1:N
color = color_map( (i-1)/(N-1) );
h = fill3(mesh3d(i).x,mesh3d(i).y,mesh3d(i).z, color);
set(h, 'facealpha',0.9)
end
grid on
hold off

Related

Would like to generate surface of revolution from bezier curve

I would like to generate surface of revolution from bezier curve. I have made bezier curve in MATLAB but beyond this point I am stuck and do not know how to proceed. Please help.
Below is the code that I have made.
clc
clear
close all
% Name : Savla Jinesh Shantilal
% Bits ID : 2021HT30609
%% Define inout parameters
B = [1,1; 2,3; 4,3; 3,1]; % Creating matrix for polygon vertices
[r,s] = size(B); % getting size of matrix in terms of rows and columns
n = r-1; % n+1 represents number of vertices of the polygon
np = 20; % represents number of equi-distance points on the bezier curve
t = linspace(0,1,np);
%% Plot polygon
for k = 1:n
plot([B(k,1),B(k+1,1)], [B(k,2),B(k+1,2)], 'r', 'LineWidth', 2)
hold on
grid on
end
%% Generate the points on the bezier curve
for j = 1:np
P = [0,0];
for i = 0:n
M(i+1) = (factorial(n)/(factorial(i)*factorial(n-i)))*((t(j))^i)*((1-t(j))^(n-i));
P = P + B(i+1,:)*M(i+1);
end
Q(j,:) = P;
end
%% Plot the bezier curve from the obtained points
for l = 1:np-1
plot([Q(l,1),Q(l+1,1)],[Q(l,2),Q(l+1,2)], '-- b', 'LineWidth', 2);
hold on
end
Usually one can use the built-in cylinder function for monotonically increasing x-values. Here, the bezier curve has non monotonic values from max(x) so we break it to two parts to parameterize it, and then add an angle rotation.
% first define the x and y coordinate from your Q info:
xx = Q(:,1);
yy = Q(:,2);
N = 1e2;
[~, id] = max(xx); % the position where we split
t = linspace(xx(1),xx(id),N);
% Parameterize the function:
t = linspace(0,2*(xx(id)-xx(1)),N);
x = zeros(1, N);
L = t <= ( xx(id)-xx(1) ); % the "Left" side of the curve
x(L) = t(L)+xx(1);
x(~L) = flip(x(L));
%define the r value
r = x;
r(L) = interp1(xx(1:id) ,yy(1:id) , x(L) ); % Left side
r(~L) = interp1(xx(id:end),yy(id:end), x(~L)); % right side (not left)
% define your x values
x = repmat(x', [1 N]);
% define the theta that will perform the rotation
theta = linspace(0,2*pi, N);
% initialize values for y and z
y = zeros(N);
z = zeros(N);
% calculate the y and z values
for i=1:N
y(i,:) = r(i) *cos(theta);
z(i,:) = r(i) *sin(theta);
end
%plot the surface of revolution and the original curve
s = surf(x,y,z);
alpha 0.4
hold on
plot(xx,yy,'k','LineWidth',3)

How can I make a cylindrical 3D contour plot in Matlab?

I have an axisymmetric flow with m x n grid points in r and z direction and I want to plot the temperature that is stored in a matrix with size mxn in a 3D cylindrical plot as visualized in the link below (My reputation is not high enough to include it as a picture).
I have managed to plot it in 2D (r,z plane) using contour but I would like to add the theta plane for visualization. How can I do this?
You can roll your own with multiple calls to surface().
Key idea is: for each surface: (1) theta=theta1, (2) theta=theta2, (3) z=zmax, (4) z=0, (5) r=rmax, generate a 3D mesh (xx,yy,zz) and the temperature map on that mesh. So you have to think about how to construct each surface mesh.
Edit: completed code is now provided. All magic number and fake data are put at (almost) the top of the code so it's easy to convert it into a general purpose Matlab function. Good luck!
% I have adjusted the range values to show the curved cylinder wall
% display a variable temperature
r = 0:0.1:2.6; % you can also try r = 0:0.1:3.0
z = 0:0.1:10; % you can also try z = 0:0.1:15;
[rr, zz] = meshgrid(r,z);
% fake temperature data
temp = 100 + (10* (3-rr).^0.6) .* (1-((zz - 7.5)/7.5).^6) ;
% visualize in 2D
figure(1);
clf;
imagesc(r,z,temp);
colorbar;
% set cut planes angles
theta1 = 0;
theta2 = pi*135/180;
nt = 40; % angle resolution
figure(2);
clf;
xx1 = rr * cos(theta1);
yy1 = rr * sin(theta1);
h1 = surface(xx1,yy1,zz,temp,'EdgeColor', 'none');
xx2 = rr * cos(theta2);
yy2 = rr * sin(theta2);
h2 = surface(xx2,yy2,zz,temp,'EdgeColor', 'none');
% polar meshgrid for the top end-cap
t3 = linspace(theta1, (theta2 - 2*pi), nt);
[rr3, tt3] = meshgrid(r,t3);
xx3 = rr3 .* cos(tt3);
yy3 = rr3 .* sin(tt3);
zz3 = ones(size(rr3)) * max(z);
temp3 = zeros(size(rr3));
for k = 1:length(r)
temp3(:,k) = temp(end,k);
end
h3 = surface(xx3,yy3,zz3,temp3,'EdgeColor', 'none');
% polar meshgrid for the bottom end-cap
zz4 = ones(size(rr3)) * min(z);
temp4 = zeros(size(rr3));
for k = 1:length(r)
temp4(:,k) = temp(1,k);
end
h4 = surface(xx3,yy3,zz4,temp4,'EdgeColor', 'none');
% generate a curved meshgrid
[tt5, zz5] = meshgrid(t3,z);
xx5 = r(end) * cos(tt5);
yy5 = r(end) * sin(tt5);
temp5 = zeros(size(xx5));
for k = 1:length(z)
temp5(k,:) = temp(k,end);
end
h5 = surface(xx5, yy5, zz5,temp5,'EdgeColor', 'none');
axis equal
colorbar
view(125,25); % viewing angles

Ordered Isoline Calculation from 3D Triangular Surface in MATLAB

I need to extract the isoline coordinates of a 4D variable from a 3D surface defined using a triangulated mesh in MATLAB. I need the isoline coordinates to be a ordered in such a manner that if they were followed in order they would trace the path i.e. the order of the points a 3D printer would follow.
I have found a function that can calculate the coordinates of these isolines (see Isoline function here) but the problem is this function does not consider the isolines to be joined in the correct order and is instead a series of 2 points separated by a Nan value. This makes this function only suitable for visualisation purposes and not the path to follow.
Here is a MWE of the problem of a simplified problem, the surface I'm applying it too is much more complex and I cannot share it. Where x, y and z are nodes, with TRI providing the element connectivity list and v is the variable of which I want the isolines extracted from and is not equal to z.
If anyone has any idea on either.....
A function to extract isoline values in the correct order for a 3D tri mesh.
How to sort the data given by the function Isoline so that they are in the correct order.
.... it would be very much appreciated.
Here is the MWE,
% Create coordinates
[x y] = meshgrid( -10:0.5:10, -10:0.5:10 );
z = (x.^2 + y.^2)/20; % Z height
v = x+y; % 4th dimension value
% Reshape coordinates into list to be converted to tri mesh
x = reshape(x,[],1); y = reshape(y,[],1); z = reshape(z,[],1); v = reshape(v,[],1);
TRI = delaunay(x,y); % Convertion to a tri mesh
% This function calculates the isoline coordinates
[xTows, yTows, zTows] = IsoLine( {TRI,[x, y, z]}, v, -18:2:18);
% Plotting
figure(1); clf(1)
subplot(1,2,1)
trisurf(TRI,x,y,z,v)
hold on
for i = 1:size(xTows,1)
plot3( xTows{i,1}, yTows{i,1}, zTows{i,1}, '-k')
end
hold off
shading interp
xlabel('x'); ylabel('y'); zlabel('z'); title('Isolines'), axis equal
%% This section is solely to show that the isolines are not in order
for i = 1:size(xTows,1)
% Arranging data into colums and getting rid of Nans that appear
xb = xTows{i,1}; yb = yTows{i,1}; zb = zTows{i,1};
xb = reshape(xb, 3, [])'; xb(:,3) = [];
yb = reshape(yb, 3, [])'; yb(:,3) = [];
zb = reshape(zb, 3, [])'; zb(:,3) = [];
subplot(1,2,2)
trisurf(TRI,x,y,z,v)
shading interp
view(2)
xlabel('x'); ylabel('y'); zlabel('z'); title('Plotting Isolines in Order')
axis equal; axis tight; hold on
for i = 1:size(xb,1)
plot3( [xb(i,1) xb(i,2)], [yb(i,1) yb(i,2)], [zb(i,1) zb(i,2)], '-k')
drawnow
end
end
and here is the function Isoline, which I have slightly adpated.
function [xTows, yTows, zTows] = IsoLine(Surf,F,V,Col)
if length(Surf)==3 % convert mesh to triangulation
P = [Surf{1}(:) Surf{2}(:) Surf{3}(:)];
Surf{1}(end,:) = 1i;
Surf{1}(:,end) = 1i;
i = find(~imag(Surf{1}(:)));
n = size(Surf{1},1);
T = [i i+1 i+n; i+1 i+n+1 i+n];
else
T = Surf{1};
P = Surf{2};
end
f = F(T(:));
if nargin==2
V = linspace(min(f),max(f),22);
V = V(2:end-1);
elseif numel(V)==1
V = linspace(min(f),max(f),V+2);
V = V(2:end-1);
end
if nargin<4
Col = 'k';
end
H = NaN + V(:);
q = [1:3 1:3];
% -------------------------------------------------------------------------
% Loop over iso-values ----------------------------------------------------
xTows = [];
yTows = [];
zTows = [];
for k = 1:numel(V)
R = {[],[]};
G = F(T) - V(k);
C = 1./(1-G./G(:,[2 3 1]));
f = unique(T(~isfinite(C))); % remove degeneracies by random perturbation
F(f) = F(f).*(1+1e-12*rand(size(F(f)))) + 1e-12*rand(size(F(f)));
G = F(T) - V(k);
C = 1./(1-G./G(:,[2 3 1]));
C(C<0|C>1) = -1;
% process active triangles
for i = 1:3
f = any(C>=0,2) & C(:,i)<0;
for j = i+1:i+2
w = C(f,q([j j j]));
R{j-i} = [R{j-i}; w.*P(T(f,q(j)),:)+(1-w).*P(T(f,q(j+1)),:)];
end
end
% define isoline
for i = 1:3
X{i} = [R{1}(:,i) R{2}(:,i) nan+R{1}(:,i)]';
% X{i} = [R{1}(:,i) R{2}(:,i)]'; % Changed by Matt
X{i} = X{i}(:)';
end
% plot isoline
if ~isempty(R{1})
% hold on
% H(k) = plot3(X{1},X{2},X{3},Col);
% Added by M.Thomas
xTows{k,1} = X{1};
yTows{k,1} = X{2};
zTows{k,1} = X{3};
end
end
What you will notice is that the isolines (xTows, yTows and zTows) are not in order there "jump around" when plotted sequentially. I need to sort the tows so that they give a smooth plot in order.

super resolution of low resolution images using delaunay triangulation, negative pixel values for the resultant High resolution image

i have to do super resolution of two low resolution images to obtain a high resolution image.
2nd image is taken as base image and the first image is registered with respect to it . i used SURF algorithm for image registration . A Delaunay triangulation is
constructed over the points using a built-in MATLAB delaunay
function . The HR grid of size is
constructed for a prespecified resolution enhancement factor R Then HR algorithm for interpolating the pixel values on the
HR grid is summarized next.
HR Algorithm Steps:
1. Construct the Delaunay triangulation
over the set of scattered vertices in the
irregularly sampled raster formed from the
LR frames.
Estimate the gradient vector at each
vertex of the triangulation by calculating the unit normal vector of neighbouring vector using cross product method.Sum of the unit normal vector of each triangle multiplied by its area is divided by summation of area of all neighbouring triangles to get the vertex normal.
Approximate each triangle patch in
the triangulation by a continuous and,
possibly, a continuously differentiable
surface, subject to some smoothness constraint.
Bivariate polynomials or splines
could be the approximants as explained
below.
Set the resolution enhancement factor
along the horizontal and vertical directions
and then calculate the pixel value
at each regularly spaced HR grid point to
construct the initial HR image
The bivariate polynomial i used is mentioned in the code, using pixel values at each vertex of a triangle and corresponding gradient in x and y directions i calculated the nine constants associated with each triangle then defined a high resolution grid , calculated the pixel values at each point using the constants calculated
i am attaching my code with it, the problem i am facing is that i am just getting a gray image as out put HR image , because the constants i have calculated have negative values resulting in negative pixel values
another problem i realized with my code is in gradient estimation i get a lot of 'NaN' as a result of gradient calculation.
if any one can please spent some time to help me out
close all
clear all
K = 2;
P1 = imread('C:\Users\Javeria Farooq\Desktop\project images\a.pgm');
%reads the image to be registered
P2 = imread('C:\Users\Javeria Farooq\Desktop\project images\b.pgm');
%reads the base image
image1_gray = makelr(P1, 1, 100, 1/2);
%image1_gray = P1;
% makes lr image of first
image2_gray= makelr(P2, 1, 100, 1/2);
%image2_gray= P2;
%makes lr image of second
figure(1),imshow(image1_gray)
axis on;
grid on;
title('Unregistered image');
figure(2),imshow(image2_gray)
axis on;
grid on;
title('Base image ');
impixelinfo
% both image displayed with pixel info
hold on
points_image1= detectSURFFeatures(image1_gray, 'NumScaleLevels', 100, 'NumOctaves', 12, 'MetricThreshold', 500 );
%detects surf features of first image
points_image2 = detectSURFFeatures(image2_gray, 'NumScaleLevels', 100, 'NumOctaves', 12, 'MetricThreshold', 500 );
%detects surf features of second image
[features_image1, validPoints_image1] = extractFeatures(image1_gray, points_image1);
[features_image2, validPoints_image2] = extractFeatures(image2_gray, points_image2);
%extracts features of both images
indexPairs = matchFeatures(features_image1, features_image2, 'Prenormalized', true) ;
% get matching points
matched_pts1 = validPoints_image1(indexPairs(:, 1));
matched_pts2 = validPoints_image2(indexPairs(:, 2));
figure; showMatchedFeatures(image1_gray,image2_gray,matched_pts1,matched_pts2,'montage');
%matched features of both images are displayed
legend('matched points 1','matched points 2');
% Compute the transformation matrix
tform = estimateGeometricTransform(matched_pts1,matched_pts2,'projective')
%calculate transformation matrix using projective transform
T=tform.T;
r=[];
A=[];
l=1
[N1 N2]=size(image2_gray)
registeredPts = zeros(N1*N2,2);
% s= zeros(N1*N2,2);
pixelVals = zeros(N1*N2,1);
[N1 N2]=size(image2_gray)
for row = 1:N1
for col = 1:N2
pixNum = (row-1)*N2 + col;
pixelVals(pixNum,1) = image2_gray(row,col);
registeredPts(pixNum,:) = [col,row];
end
end
[r]=transformPointsForward(tform,registeredPts);
%coordinates of base image
image2_gray=double(image2_gray);
R=2;
r1=r(:,1);
r2=r(:,2);
for row = 1:N1
for col = 1:N2
pixNum = N1*N2 + (row-1)*N2 + col;
pixelVals(pixNum,1) = image1_gray(row,col);
registeredPts(pixNum,:) = [r1(row,1),r2(row,1)];
end
end
% all pixel values are saved in pixelVals
%all registered points are saved first base image then unregistered image
%delaunay triangulation of all coordinates passing x and y coordinates from registered Points
tri = delaunay(registeredPts(:,1),registeredPts(:,2));
figure(3), triplot(tri,registeredPts(:,1),registeredPts(:,2))
save tri
% Estimate the gradient vector at each vertex
[totalTris,three] = size(tri);
[totalPoints,two] = size(registeredPts);
vGradientVecs = zeros(totalPoints,2);
triAreas = zeros(totalTris,1);
triUnitNormals = zeros(totalTris,3);
vUnitNormals = zeros(totalPoints,3);
% 1. Find the unit normal vectors and the areas of all triangles,
% then find the product of these two numbers for each triangle
for triNum = 1:totalTris
v = tri(triNum,:);
% 3D triangle points: x,y,pixel
b=pixelVals(v);
b=b(:);
p = [registeredPts(v,:),b];
% triangle area
triAreas(triNum) = polyarea([p(:,1)],[p(:,2)]);
% directional vectors representing the surface of the plane
d1 = p(2,:)-p(1,:);
d2 = p(3,:)-p(1,:);
% cross product of these vectors
crossp = cross(d1,d2);
% If u = [u1 u2 u3] and v = [v1 v2 v3], we know that the product w is defined as w = [(u2v3 – u3v2) (u3v1 - u1v3) (u1v2 - u2v1)]
% normalized cross product = unit normal vector for the triangle
dist = sqrt(sum(crossp.^2));
triUnitNormals(triNum,:) = crossp./dist;
end
% %2. %Estimate the unit normal vector at each vertex
% a. Find the triangle patches that neighbor the vertex
% b. Find the unit normal vectors of these regions
% c. Multiply each of these vectors by the area of the
% associated region, then sum these numbers and divide
% by the total area of all the regions
for pointNum = 1:totalPoints
[neighbors,x] = find(tri==pointNum);
areas = triAreas(neighbors);
areas3 = [areas,areas,areas];
triNormsSum = sum(triUnitNormals(neighbors,:).*areas3);
triAreasSum = sum(areas);
vUnormalized = triNormsSum./triAreasSum;
vUnitNormals(pointNum,:) = ...
vUnormalized./sqrt(sum(vUnormalized.^2));
if( triAreasSum == 0 )
triAreasSum = 0.0001;
vUnormalized = triNormsSum./triAreasSum;
% re-normalize
vUnitNormals(pointNum,:) = ...
vUnormalized./sqrt(sum(vUnormalized.^2));
end
% 3. Find the gradients along the x and y directions for each vertex
% vertex's unit normal: n = [nx,ny,nz]
% x-direction gradient: dz/dx = -nx/nz
% y-direction gradient: dz/dy = -ny/nz
%
for pointNum = 1:totalPoints
nz = vUnitNormals(pointNum,3);
if( nz == 0 )
nz = 0.0001;
end
vGradientVecs(pointNum,1) = -vUnitNormals(pointNum,1)./nz;
vGradientVecs(pointNum,2) = -vUnitNormals(pointNum,2)./nz;
% end
end
end
% 1. Find the 3 equations for each vertex, and
% place them in c_equations matrix;
% c_equations = [A for vertex 1;
% A for vertex 2; ...
% A for vertex totalPoints]
% c(point,row,:) gives one row from an A matrix
Btotal = zeros(3,totalPoints);
c_equations = zeros(3*totalPoints,3,9);
for pointNum = 1:totalPoints
% % B = [pixVal; x gradient; y gradient] at this vertex
z = pixelVals(pointNum);
B = [z; vGradientVecs(pointNum,1); vGradientVecs(pointNum,2)];
%
% % Compile all B matrices into a vector
Btotal(:,pointNum) = B;
% B = Ac to calculate c which is c=[c1 c2 .....c9]' take invA and
% multiply by B
x = registeredPts(pointNum,1);
y = registeredPts(pointNum,2);
A = [1 x y x^2 y^2 x^3 (x^2)*y x*(y^2) y^3; ...
0 1 0 2*x 0 3*(x^2) 2*x*y y^2 0; ...
0 0 1 0 2*y 0 x^2 2*x*y 3*(y^2)];
% Compile all A matrices into a vector
c_equations(pointNum,1,:) = A(1,:);
c_equations(pointNum,2,:) = A(2,:);
c_equations(pointNum,3,:) = A(3,:);
end
% 2. Find the c values for each triangle patch
c = zeros(totalTris,9);
c9 = zeros(9,9);
for triNum = 1:totalTris
p1 = tri(triNum,1);
p2 = tri(triNum,2);
p3 = tri(triNum,3);
B9 = [Btotal(:,p1); Btotal(:,p2); Btotal(:,p3)];
c9 = [(c_equations(p1,1,:)); (c_equations(p1,2,:)); (c_equations(p1,3,:)); ...
(c_equations(p2,1,:)); (c_equations(p2,2,:));( c_equations(p2,3,:)); ...
(c_equations(p3,1,:)); (c_equations(p3,2,:));( c_equations(p3,3,:))];
C9=squeeze(c9);
c(triNum,:) = pinv(C9)*B9; %linsolve(c9,B9);
end
% xc = findBPolyCoefficients1(tri,registeredPts,pixelVals,vGradientVecs);
% save xc
% % 2. For each point on the HR grid, find the associated triangle patch,
% % extract its c values, and use these values as the coefficients
% % in a bivariate polynomial to calculate the HR pixel value at
% % each grid point (x,y)
[N1,N2]=size(image1_gray);
[totalTris,three] = size(tri);
M = N1*R-1;
N = N2*R-1;
HRimage = zeros(M,N);
HRtriangles = zeros(M,N);
[X,Y] = meshgrid(1:1/R:N2,1:1/R:N1);
% Check all the triangles in order noting in which triangle each HR
% grid point occurs.
for triNum = 1:totalTris
pts = registeredPts(tri(triNum,:),:);
IN = inpolygon(X,Y,pts(:,1),pts(:,2)); % NxM
HRtriangles(ind2sub(size(IN),find(IN==1))) = triNum;
end
% there is a problem with this part of code ,
for y = 1:M % row
for x = 1:N % col
% For testing, average the pixels from the vertices of the
% triangle the HR point is in.
% pix = pixelVals(tri(HRtriangles(x,y),:));
% HRimage(x,y) = (pix(1) + pix(2) + pix(3))/3;
% Extract appropriate set of 9 c values
HRptC = c(HRtriangles(x,y),:);
% Bivariate polynomial
HRimage(x,y) = sum(HRptC.*[1,x,y,x^2,y^2,x^3,(x^2)*y,x*(y^2),y^3]);
g(x,y)=HRimage(x,y);
%changd xy with yx
end
end
% HRimage = estimateGridVals1(tri,registeredPts,R,N1,N2,pixelVals);
% %Estimating Grid values at each patch
% %save HRimage
g(g(:,:)<0)=0;
figure(8),imshow(g,[]);

Generalized Hough R-Table

I am trying to implement the generalized Hough transform as presented in this paper in MATLAB. I've also tried using this document to understand the algorithm. I am stuck on figuring out how to calculate the gradient angle to find Φ to use in the R-Table.
I have tried to run this matlab implementation, but the contour function tries to access negative indices. The missing functions are below.
distance.m
function [ d ] = distance( x1, y1, x2, y2 )
d = sqrt( (x2-x1)^2 + (y2-y1)^2 );
end
barycenter.m
function [ xo, yo ] = barycenter( img )
% gravitational center coordinates of a shape
[rows, cols] = size(img);
x = ones(rows, 1)*(1:cols);
y = (1:rows)'*ones(1,cols);
area = sum(sum(img));
xo = sum(sum(double(img) .* x)) / area;
yo = sum(sum(double(img) .* y)) / area;
end
modelHough.m
function [H]=ModelHough(imgRGB)
% Generalized Hough Transform Modeling
% Image Binarization
imgBW = rgb2gray(imgRGB);
imgBI = imgBW < 255;
% Retrieving information about the contour: points and number (N)
N = contour(imgBI);
% Model initialization:
% row = beta value * 100
% column = number of the couple (alpha, distance)
% 3rd dimension: 1 = alpha, 2 = distance
H=zeros(round(100*2*pi),N,2);
% Compute of the barycenter coordinates
[ xo, yo ] = barycenter(imgBI);
% for each contour point
for i=1:N
% beta compute for ith contour point
b = beta(N, imgBI, i);
% research of the first column
k=1;
while H(b+1,k,2)~=0
k=k+1;
end
% compute of the alpha value
H(b+1, k, 1) = alpha(N, i, imgBI);
% compute of the distance value
H(b+1, k, 2) = distance( xo, yo, i, b );
end
Use a suitable edge detector. You could start off with the Sobel operator. The gradient angle is atan(Gy/Gx) as described in the wiki article.
If you use a common edge detector for detecting edges you should change countor.m on row 14 to something like below:
while (img(i,j)~=1)