How generate checkerboard with Octave? - octave

I need to generate a checkerboard black/white with Octave.
I want use this virtual image for conversion cartesian to polar or perspective projections.
Anyone can show a script? Thanks
I've tried this:
clear all
close all
clc
img = magic(16);
%# convert coordinates from cartesian to polar
[r c] = size(img);
[X Y] = meshgrid(1:c,1:r);
[theta rho] = cart2pol(X, Y);
figure
subplot(121), image(img), axis square
colormap(gray(256))
subplot(122), surf(theta, rho,img),axis square;
view(0,90)

this does what the OP was looking for. But this question was asked months ago!
slight modification to OP's code.
clear all
close all
clc
%my changes start
img = zeros(8,8);
img(1:2:end,1:2:end)=255;
img(2:2:end,2:2:end)=255;
%my changes end
%# convert coordinates from cartesian to polar
[r c] = size(img);
[X Y] = meshgrid(1:c,1:r);
[theta rho] = cart2pol(X, Y);
figure
subplot(121), image(img), axis square
colormap(gray(256))
subplot(122), surf(theta, rho,img),axis square;
view(0,90)

Related

How to solve the numerical instability to a solution of a system of ordinary differential equations

I have been trying to get the numerical solution to the following system of ordinary differential equations:
Equations for the movement of a body through air in a inclined lunch:
(apparently LaTeX doesn't work on stack overflow)
u'= -F(u, theta, t)*cos(theta)
v'= -F(v, theta, t)*sin(theta)-mg
by the Runge-Kutta-Fehlberg Algorithm, but in the middle of the computation i have to calculate theta, that is calculated by
arccos(u/sqrt(u^2+v^2)) or arcsin(v/sqrt(u^2+v^2)),
but eventually theta gets too small and I need it to solve the function F( v, theta, t) and to find the value V = sqrt(v^2 + u^2) I use V = (v/sin(theta)), but as theta gets small so does sin(theta) and I get a numerical error from a given iteration forward -1.IND00, It is problably because theta is too small, i tried to make theta go from a small positive angle like 0.00001 to a small negative angle like -0.00001 (if(fabs(theta)<0.00001) theta = -0.00001) but it seems that theta gets trapped into this negative value, does anyone have an indication on what to do to resolve this numerical instability ?
It is a bad idea to use the inverse cosine or sine functions to determine the angle of a point. To get
theta = arg ( u + i*v)
use
theta = atan2(v,u).
This still has the problem that it jumps on the negative half axis, that is for v=0, u<0. That can be solved by making theta a third dynamical variable, so that
theta' = Im( (u'+i*v')/(u+i*v) ) = (u*v' - u'*v) / (u^2+v^2)
But really, the equation for the free fall with air friction is easiest implemented as
def friction(vx, vy):
v = hypot(vx, vy)
return k*v
def freefall_ode(t, u):
rx, ry, vx, vy = u
f=friction(vx, vy)
ax = -f*vx
ay = -f*vy - g
return array([ vx, vy, ax, ay ])
so that you do not need any angle or to try to weaken the coupling of the velocity components by reducing it to the angle of the velocity vector. This you can now plug into the integration method of your choice, applied as a method for vector-valued systems.

Explanation of a Hough accumulator that does not match image

I was having fun with image processing and hough transforms on Octave but the results are not the expected ones.
Here is my edges image:
and here is my hough accumulator (x-axis is angle in deg, y-axis is radius):
I feel like I am missing the horizontal streaks but there is no local maximum in the accumulator for the 0/180 angle values.
Also, for the vertical streaks, the value of the radius should be equal to the x value of the edge's image, but instead the values of r are very high:
exp: the first vertical line on the left of the image has an equation of x=20(approx) -> r.r = x.x + y.y -> r=x -> r=20
The overall resulting lines detected do not match the edges at all:
Acculmulator with detected maxima:
Resulting lines:
As you can see the maximas of the accumulator are satisfyingly detected but the resulting lines' radius values are too high and theta values are missing.
It almost looks like the hough transform accumulator does not correspond to the image...
Can someone help me figure out why and how to correct it?
Here is my code:
function [r, theta] = findScratches (img, edge)
hough = houghtf(edge,"line", pi*[0:360]/180);
threshHough = hough>.5*max(hough(:));
[r, theta] = find(threshHough>0);
%deg to rad for the trig functions
theta = theta/180*pi;
%according to octave doc r range is 2*diagonal
%-> bring it down to 1*diagonal or all lines are out of the picture
r = r/2;
%coefficients of the line y=ax+b
a = -cos(theta)./sin(theta);
b = r./sin(theta);
x = 1:size(img,2);
y = a * x + b;
figure(1)
imagesc(edge);
colormap gray;
hold on;
for i=1:size(y,1)
axis ij;
plot(y(i,:),x,'r','linewidth',1);
end
hold off;
endfunction
Thank you in advance.
You're definitely on the right track. Blurring the accumulator image would help before looking for the hotspots. Also, why not do a quick erode and dilate before doing the hough transform?
I had the same issue - detected lines had the correct slope but were shifted. The problem is that the r returned by the find(threshHough>0) function call is in the interval of [0,2*diag] while the Hough transform operates with values of r from the interval of [-diag,diag]. Therefore if you change the line
r=r/2
to
r=r-size(hough,1)/2
you will get the correct offset.
Lets define a vector of angles (in radians):
angles=pi*[0:360]/180
You should not take this operation: theta = theta/180*pi.
Replace it by: theta = angles(theta), where theta are indices
Some one commented above suggesting adjusting r to -diag to +diag range by
r=r-size(hough,1)/2
This worked well for me. However another difference was that I used the default angle to compute Hough Transform with angles -90 to +90. The theta range in the vector is +1 to +181. So It needs to be adjusted by -91, then convert to radian.
theta = (theta-91)*pi/180;
With above 2 changes, rest of the code works ok.

Shading regions/inequalities of a 2D function in MATLAB

I've defined my own function with two input arguments (call it z(x,y) say) and managed to produce a contour plot. What I'd like to do now is to shade the region where, for example, z > 5. The main problem is that z is too complicated to be able to deduce the restrictions on x,y myself. Is there any simple way of doing this?
Did you try to use NaN?
z(condition) = nan;
before calling contour(), where condition can be on any combination of z, x, y, resulting binary matrix, for instance:
z(abs(z) > x - y) = nan;

Create a function to generate random points in a parallelogram

I hope someone can help me here, I have been asked to write some code for an Lua script for a game. Firstly i am not an Lua Scripter and I am defiantly no mathematician.
What i need to do is generate random points within a parallelogram, so over time the entire parallelogram becomes filled. I have played with the scripting and had some success with the parallelogram (rectangle) positioned on a straight up and down or at 90 degrees. My problem comes when the parallelogram is rotated.
As you can see in the image, things are made even worse by the coordinates originating at the centre of the map area, and the parallelogram can be positioned anywhere within the map area. The parallelogram itself is defined by 3 pairs of coordinates, start_X and Start_Y, Height_X and Height_Y and finally Width_X and Width_Y. The random points generated need to be within the bounds of these coordinates regardless of position or orientation.
Map coordinates and example parallelogram
An example of coordinates are...
Start_X = 122.226
Start_Y = -523.541
Height_X = 144.113
Height_Y = -536.169
Width_X = 128.089
Width_Y = -513.825
In my script testing i have eliminated the decimals down to .5 as any smaller seems to have no effect on the final outcome. Also in real terms the start width and height could be in any orientation when in final use.
Is there anyone out there with the patients to explain what i need to do to get this working, my maths is pretty basic, so please be gentle.
Thanks for reading and in anticipation of a reply.
Ian
In Pseudocode
a= random number with 0<=a<=1
b= random number with 0<=b<=1
x= Start_X + a*(Width_X-Start_X) + b*(Height_X-Start_X)
y= Start_Y + a*(Width_Y-Start_Y) + b*(Height_Y-Start_Y)
this should make a random point at coordinates x,y within the parallelogram
The idea is that each point inside the parallelogram can be specified by saying how far you go from Start in the direction of the first edge (a) and how far you go in the direction of the second edge (b).
For example, if you have a=0, and b=0, then you do not move at all and are still at Start.
If you have a=1, and b=0, then you move to Width.
If you have a=1, and b=1, then you move to the opposite corner.
You can use something like "texture coordinates", which are in the range [0,1], to generate X,Y for a point inside your parallelogram. Then, you could generate random numbers (u,v) from range [0,1] and get a random point you want.
To explain this better, here is a picture:
The base is formed by vectors v1 and v2. The four points A,B,C,D represent the corners of the parallelogram. You can see the "texture coordinates" (which I will call u,v) of the points in parentheses, for example A is (0,0), D is (1,1). Every point inside the parallelogram will have coordinates within (0,0) and (1,1), for example the center of the parallelogram has coordinates (0.5,0.5).
To get the vectors v1,v2, you need to do vector subtraction: v1 = B - A, v2 = C - A. When you generate random coordinates u,v for a random point r, you can get back the X,Y using this vector formula: r = A + u*v1 + v*v2.
In Lua, you can do this as follows:
-- let's say that you have A,B,C,D defined as the four corners as {x=...,y=...}
-- (actually, you do not need D, as it is D=v1+v2)
-- returns the vector a+b
function add(a,b)
return {x = a.x + b.x, y = a.y + b.y} end
end
-- returns the vector a-b
function sub(a,b)
return {x = a.x - b.x, y = a.y - b.y} end
end
-- returns the vector v1*u + v2*v
function combine(v1,u,v2,v)
return {x = v1.x*u + v2.x*v, y = v1.y*u + v2.y*v}
end
-- returns a random point in parallelogram defined by 2 vectors and start
function randomPoint(s,v1,v2)
local u,v = math.random(), math.random() -- these are in range [0,1]
return add(s, combine(v1,u,v2,v))
end
v1 = sub(B,A) -- your basis vectors v1, v2
v2 = sub(C,A)
r = randomPoint(A,v1,v2) -- this will be in your parallelogram defined by A,B,C
Note that this will not work with your current layout - start, width, height. How do you want to handle rotation with these parameters?

Using GNU Octave FFT functions

I'm playing with octave's fft functions, and I can't really figure out how to scale their output: I use the following (very short) code to approximate a function:
function y = f(x)
y = x .^ 2;
endfunction;
X=[-4096:4095]/64;
Y = f(X);
# plot(X, Y);
F = fft(Y);
S = [0:2047]/2048;
function points = approximate(input, count)
size = size(input)(2);
fourier = [fft(input)(1:count) zeros(1, size-count)];
points = ifft(fourier);
endfunction;
Y = f(X); plot(X, Y, X, approximate(Y, 10));
Basically, what it does is take a function, compute the image of an interval, fft-it, then keep a few harmonics, and ifft the result. Yet I get a plot that is vertically compressed (the vertical scale of the output is wrong). Any ideas?
You are throwing out the second half of the transform. The transform is Hermitian symmetric for real-valued inputs and you have to keep those lines. Try this:
function points = approximate(inp, count)
fourier = fft(inp);
fourier((count+1):(length(fourier)-count+1)) = 0;
points = real(ifft(fourier)); %# max(imag(ifft(fourier))) should be around eps(real(...))
endfunction;
The inverse transform will invariably have some tiny imaginary part due to numerical computation error, hence the real extraction.
Note that input and size are keywords in Octave; clobbering them with your own variables is a good way to get really weird bugs down the road!
You are probably doing it wrong. You remove all the "negative" frequencies in your code. You should keep both positive and negative low frequencies. Here is a code in python and the result. The plot has the right scale.
alt text http://files.droplr.com/files/35740123/XUl90.fft.png
The code:
from __future__ import division
from scipy.signal import fft, ifft
import numpy as np
def approximate(signal, cutoff):
fourier = fft(signal)
size = len(signal)
# remove all frequencies except ground + offset positive, and offset negative:
fourier[1+cutoff:-cutoff] = 0
return ifft(fourier)
def quad(x):
return x**2
from pylab import plot
X = np.arange(-4096,4096)/64
Y = quad(X)
plot(X,Y)
plot(X,approximate(Y,3))