printing to file only prints last line - processing

I'm creating a program in Processing.js to help me make color ramps for pixel art. The ramp generator works, so now I need the program to convert the HSV colors I'm working in to RGB so I can input them into the program I'm using (it doesn't allow me to use the HSV color space for some reason, but I'm ok with that because I'm comfortable with this program).
Here's the function that's causing problems
void convert(float h,float s,float v){
// h will be 0-360, s and v are 0-100
PrintWriter output;
output = createWriter("value.txt");
float S = s/100;
float V = v/100;
//the conversion algorithm I found expects s and v to be 0-1
float c = S*V;
float x = c*(1-abs(((h/60)%2)-1));
float e = V-c;
float R = 0.0;
float G = 0.0;
float B = 0.0;
if(0 <= h && h <= 60) {
R = c;
G = x;
B = 0;
} else if(60 <= h && h <= 120) {
R = x;
G = c;
B = 0;
} else if(120 <= h && h <= 180) {
R = 0;
G = c;
B = x;
} else if(180 <= h && h <= 240) {
R = 0;
G = x;
B = c;
} else if(240 <= h && h <= 300){
R = x;
G = 0;
B = c;
} else if(300 <= h && h <= 360) {
R = c;
G = 0;
B = x;
} else {
}
float r = R + e;
float g = G + e;
float b = B + e;
println(round(r*255)+","+round(g*255)+","+round(b*255));
output.println(round(r*255)+","+round(g*255)+","+round(b*255));
output.flush();
output.close();
}
The println that doesn't write to the file displays just fine in the console, but output.println only writes the last line to the file. I'm expecting 220 lines of output. If needed I can edit the question to have the rest of the code, but this is the only function that's causing problems right now. Here's the source for the conversion algorithm I'm using.

In the future, please try to narrow your problem down to a MCVE like this:
void draw() {
point(mouseX, mouseY);
PrintWriter output = createWriter("positions.txt");
output.println(mouseX);
output.flush();
output.close();
}
This program shows the same problem you're having, but it's much easier to work with.
The problem is that you're creating a new PrintWriter every frame. Instead, you need to create it once at the beginning and continually write to it as your program runs.
From the reference:
PrintWriter output;
void setup() {
// Create a new file in the sketch directory
output = createWriter("positions.txt");
}
void draw() {
point(mouseX, mouseY);
output.println(mouseX); // Write the coordinate to the file
}
void keyPressed() {
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
exit(); // Stops the program
}

Related

Is this implementation of a feedforward comb filter (FFCF) correct?

I'm trying to implement a feedforward comb filter (for use in a reverb) as described here: https://ccrma.stanford.edu/~jos/pasp/Feedforward_Comb_Filters.html
This is my code:
int delay = 1051;
int arraySize = delay + 1;
int n = 0;
double gain = 0.7;
double buffer = new double[arraySize];
double doDelay(double x) {
buffer[n] = x;
double y = buffer[(n + delay) % arraySize];
y += x * gain;
n--;
if (n < 0) n += arraySize;
return y;
}
// per-sample processing function (called for every sample)
void processSample(double& sample) {
sample = doDelay(sample);
}
Aside from it not being the most elegant code, is the application of a feedforward comb filter correct? I suspect I might be missing something.
Thank you.

GLSL - for loop not working

I am playing with GLSL Sandbox somehow the for loop not working as I expected:
float map( vec3 p )
{
p.yz = rotate(p.yz, mouse.y*10.);
float aa = 0.;
float b = box( p, vec3(1.,1.,1.) );
for(int i=0; i<5; i++)
{
float off = float(i);
vec3 q = p+off*.05;//<--pivot go down diagonally
float c = box( q, vec3(off,1.,1.) );//<--scale the box in x
aa = min(c,b);
}
return aa;
}
I expect it to have at least 5 boxes gradually go down with the xscale become bigger. But the result seems like all the duplicated boxes end at the last result of the loop.
How can I resolve this?
You’re never reading from aa, so it just ends up being the minimum of the last c and the original b. Rearranging things like this should work:
float b = box(p, vec3(1., 1., 1.));
float aa = b;
for (int i = 0; i < 5; i++) {
…
aa = min(c, aa);
}

I made a processing program that generates a mandelbrot set but don't know how to effectively implement a zoom method

I'm not sure if it is possible in processing but I would like to be able to zoom in on the fractal without it being extremely laggy and buggy. What I currently have is:
int maxIter = 100;
float zoom = 1;
float x0 = width/2;
float y0 = height/2;
void setup(){
size(500,300);
noStroke();
smooth();
}
void draw(){
translate(x0, y0);
scale(zoom);
for(float Py = 0; Py < height; Py++){
for(float Px = 0; Px < width; Px++){
// scale pixel coordinates to Mandelbrot scale
float w = width;
float h = height;
float xScaled = (Px * (3.5/w)) - 2.5;
float yScaled = (Py * (2/h)) - 1;
float x = 0;
float y = 0;
int iter = 0;
while( x*x + y*y < 2*2 && iter < maxIter){
float tempX = x*x - y*y + xScaled;
y = 2*x*y + yScaled;
x = tempX;
iter += 1;
}
// color pixels
color c;
c = pickColor(iter);
rect(Px, Py,1,1);
fill(c);
}
}
}
// pick color based on time pixel took to escape (number of iterations through loop)
color pickColor(int iters){
color b = color(0,0,0);
if(iters == maxIter) return b;
int l = 1;
color[] colors = new color[maxIter];
for(int i = 0; i < colors.length; i++){
switch(l){
case 1 : colors[i] = color(255,0,0); break;
case 2 : colors[i] = color(0,0,255); break;
case 3 : colors[i] = color(0,255,0); break;
}
if(l == 1 || l == 2) l++;
else if(l == 3) l = 1;
else l--;
}
return colors[iters];
}
// allow zooming in and out
void mouseWheel(MouseEvent event){
float direction = event.getCount();
if(direction < 0) zoom += .02;
if(direction > 0) zoom -= .02;
}
// allow dragging back and forth to change view
void mouseDragged(){
x0+= mouseX-pmouseX;
y0+= mouseY-pmouseY;
}
but it doesn't work very well. It works alright at the size and max iteration I have it set to now (but still not well) and is completely unusable at larger sizes or higher maximum iterations.
The G4P library has an example that does exactly this. Download the library and go to the G4P_MandelBrot example. The example can be found online here.
Hope this helps!

How can I write the Matlab "filter"-function myself?

I would like to use a Butterworth filter on a 1D-Signal. In Matlab the script would look like this:
f=100;
f_cutoff = 20;
fnorm =f_cutoff/(f/2);
[b,a] = butter(8,fnorm,'low');
filteredData = filter(b,a,rawData); % I want to write this myself
Now I don't want to directly use the filter-function given in Matlab but write it myself.
In the Matlab documentation it's described as follows:
The filter function is implemented as a direct form II transposed structure,
y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)
- a(2)*y(n-1) - ... - a(na+1)*y(n-na)
where n-1 is the filter order, which handles both FIR and IIR filters [1], na is the feedback filter order, and nb is the feedforward filter order.
So I've already tried to write the function like that:
f=100;
f_cutoff = 20;
fnorm =f_cutoff/(f/2);
[b,a] = butter(8,fnorm,'low');
for n = 9:size(rawData,1)
filteredData(n,1) = b(1)*n + b(2)*(n-1) + b(3)*(n-2) + b(4)*(n-3) + b(5)*(n-4) ...
- a(2)*rawData(n-1,1) - a(3)*rawData(n-2,1) - a(4)*rawData(n-3,1) - a(5)*accel(n-4,1);
end
But that's not working. Can you please help me? What am I doing wrong?
Sincerely,
Cerdo
PS: the filter documentation can be foud here: http://www.mathworks.de/de/help/matlab/ref/filter.html#f83-1015962 when expanding More About -> Algorithms
Check my Answer
filter
public static double[] filter(double[] b, double[] a, double[] x) {
double[] filter = null;
double[] a1 = getRealArrayScalarDiv(a,a[0]);
double[] b1 = getRealArrayScalarDiv(b,a[0]);
int sx = x.length;
filter = new double[sx];
filter[0] = b1[0]*x[0];
for (int i = 1; i < sx; i++) {
filter[i] = 0.0;
for (int j = 0; j <= i; j++) {
int k = i-j;
if (j > 0) {
if ((k < b1.length) && (j < x.length)) {
filter[i] += b1[k]*x[j];
}
if ((k < filter.length) && (j < a1.length)) {
filter[i] -= a1[j]*filter[k];
}
} else {
if ((k < b1.length) && (j < x.length)) {
filter[i] += (b1[k]*x[j]);
}
}
}
}
return filter;
}
conv
public static double[] conv(double[] a, double[] b) {
double[] c = null;
int na = a.length;
int nb = b.length;
if (na > nb) {
if (nb > 1) {
c = new double[na+nb-1];
for (int i = 0; i < c.length; i++) {
if (i < a.length) {
c[i] = a[i];
} else {
c[i] = 0.0;
}
}
a = c;
}
c = filter(b, new double [] {1.0} , a);
} else {
if (na > 1) {
c = new double[na+nb-1];
for (int i = 0; i < c.length; i++) {
if (i < b.length) {
c[i] = b[i];
} else {
c[i] = 0.0;
}
}
b = c;
}
c = filter(a, new double [] {1.0}, b);
}
return c;
}
deconv
public static double[] deconv(double[] b, double[] a) {
double[] q = null;
int sb = b.length;
int sa = a.length;
if (sa > sb) {
return q;
}
double[] zeros = new double[sb - sa +1];
for (int i =1; i < zeros.length; i++){
zeros[i] = 0.0;
}
zeros[0] = 1.0;
q = filter(b,a,zeros);
return q;
}
deconvRes
public static double[] deconvRes(double[] b, double[] a) {
double[] r = null;
r = getRealArraySub(b,conv(a,deconv(b,a)));
return r;
}
getRealArraySub
public static double[] getRealArraySub(double[] dSub0, double[] dSub1) {
double[] dSub = null;
if ((dSub0 == null) || (dSub1 == null)) {
throw new IllegalArgumentException("The array must be defined or diferent to null");
}
if (dSub0.length != dSub1.length) {
throw new IllegalArgumentException("Arrays must be the same size");
}
dSub = new double[dSub1.length];
for (int i = 0; i < dSub.length; i++) {
dSub[i] = dSub0[i] - dSub1[i];
}
return dSub;
}
getRealArrayScalarDiv
public static double[] getRealArrayScalarDiv(double[] dDividend, double dDivisor) {
if (dDividend == null) {
throw new IllegalArgumentException("The array must be defined or diferent to null");
}
if (dDividend.length == 0) {
throw new IllegalArgumentException("The size array must be greater than Zero");
}
double[] dQuotient = new double[dDividend.length];
for (int i = 0; i < dDividend.length; i++) {
if (!(dDivisor == 0.0)) {
dQuotient[i] = dDividend[i]/dDivisor;
} else {
if (dDividend[i] > 0.0) {
dQuotient[i] = Double.POSITIVE_INFINITY;
}
if (dDividend[i] == 0.0) {
dQuotient[i] = Double.NaN;
}
if (dDividend[i] < 0.0) {
dQuotient[i] = Double.NEGATIVE_INFINITY;
}
}
}
return dQuotient;
}
Example Using
Example Using
double[] a, b, q, u, v, w, r, z, input, outputVector;
u = new double [] {1,1,1};
v = new double [] {1, 1, 0, 0, 0, 1, 1};
w = conv(u,v);
System.out.println("w=\n"+Arrays.toString(w));
a = new double [] {1, 2, 3, 4};
b = new double [] {10, 40, 100, 160, 170, 120};
q = deconv(b,a);
System.out.println("q=\n"+Arrays.toString(q));
r = deconvRes(b,a);
System.out.println("r=\n"+Arrays.toString(r));
a = new double [] {2, -2.5, 1};
b = new double [] {0.1, 0.1};
u = new double[31];
for (int i = 1; i < u.length; i++) {
u[i] = 0.0;
}
u[0] = 1.0;
z = filter(b, a, u);
System.out.println("z=\n"+Arrays.toString(z));
a = new double [] {1.0000,-3.518576748255174,4.687508888099475,-2.809828793526308,0.641351538057564};
b = new double [] { 0.020083365564211,0,-0.040166731128422,0,0.020083365564211};
input = new double[]{1,2,3,4,5,6,7,8,9};
outputVector = filter(b, a, input);
System.out.println("outputVector=\n"+Arrays.toString(outputVector));
OUTPUT
w=
[1.0, 2.0, 2.0, 1.0, 0.0, 1.0, 2.0, 2.0, 1.0]
q=
[10.0, 20.0, 30.0]
r=
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
z=
[0.05, 0.1125, 0.115625, 0.08828125, 0.0525390625, 0.021533203124999997, 6.469726562499979E-4, -0.009957885742187502, -0.012770843505859377, -0.010984611511230471, -0.007345342636108401, -0.003689372539520266, -9.390443563461318E-4, 6.708808243274683E-4, 0.0013081232085824014, 0.0012997135985642675, 9.705803939141337E-4, 5.633686931105333E-4, 2.189206694310998E-4, -8.033509766391922E-6, -1.195022219235398E-4, -1.453610225212288E-4, -1.219501671897661E-4, -7.975719772659323E-5, -3.8721413563358476E-5, -8.523168090901481E-6, 8.706746668052387E-6, 1.5145017380516224E-5, 1.4577898391619086E-5, 1.0649864299265747E-5, 6.023381178272641E-6]
outputVector=
[0.020083365564211, 0.11083159422936348, 0.31591188140651166, 0.648466936215357, 1.0993782391344866, 1.6451284697769106, 2.25463601232057, 2.8947248889603028, 3.534126758562552]
Please give me your feedbacks!!
I have found a text described the Direct Form II Transposed used in the Matlab filter function and it works perfectly. See script below. Other implementations are also available but with error of around 1e-15, you'll see this by running the script yourself.
%% Specification of the Linear Chebysev filters
clc;clear all;close all
ord = 5; %System order (from 1 to 5)
[bq,aq] = cheby1(ord,2,0.2);theta = [bq aq(2:end)]';
figure;zplane(bq,aq); % Z-Pole/Zeros
u = [ones(40,1); zeros(40,1)];
%% Naive implementation of the basic algorithm
y0 = filter(bq,aq,u); % Built-in filter
b = fliplr(bq);a = fliplr(aq);a(end) = [];
y1 = zeros(40,1);pad = zeros (ord,1);
yp = [pad; y1(:)];up = [pad; u(:)];
for i = 1:length(u)
yp(i+ord) = sum(b(:).*up(i:i+ord))-sum(a(:).*yp(i:i+ord-1));
end
y1 = yp(ord+1:end); % Naive implementation
err = y0(:)-y1(:);
figure
plot(y0,'r')
hold on
plot(y1,'*g')
xlabel('Time')
ylabel('Response')
legend('My code','Built-in filter')
figure
plot(err)
xlabel('Time')
ylabel('Error')
%% Direct Form II Transposed
% Direct realization of rational transfer functions
% trps: 0 for direct realization, 1 for transposed realisation
% b,a: Numerator and denominator
% x: Input sequence
% y: Output sequence
% u: Internal states buffer
trps = 1;
b=theta(1:ord+1);
a=theta(ord+2:end);
y2=zeros(size(u));
x=zeros(ord,1);
%%
if trps==1
for i=1:length(u)
y2(i)=b(1)*u(i)+x(1);
x=[x(2:ord);0];
x=x+b(2:end)*u(i)-a*y2(i);
end
else
for i=1:length(u)
xnew=u(i)-sum(x(1:ord).*a);
x=[xnew,x];
y2(i)=sum(x(1:ord+1).*b);
x=x(1:ord);
end
end
%%
err = y2 - filter(bq,aq,u);
figure
plot(y0,'r')
hold on
plot(y2,'*g')
xlabel('Time')
ylabel('Response')
legend('Form II Transposed','Built-in filter')
figure
plot(err)
xlabel('Time')
ylabel('Error')
% end
I implemented filter function used by Matlab in Java :
The filter function is implemented as a direct form II transposed
structure,
y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) - a(2)*y(n-1) -
... - a(na+1)*y(n-na)
where n-1 is the filter order, which handles both FIR and IIR filters
[1], na is the feedback filter order, and nb is the feedforward filter
order.
public void filter(double [] b,double [] a, ArrayList<Double> inputVector,ArrayList<Double> outputVector){
double rOutputY = 0.0;
int j = 0;
for (int i = 0; i < inputVector.size(); i++) {
if(j < b.length){
rOutputY += b[j]*inputVector.get(inputVector.size() - i - 1);
}
j++;
}
j = 1;
for (int i = 0; i < outputVector.size(); i++) {
if(j < a.length){
rOutputY -= a[j]*outputVector.get(outputVector.size() - i - 1);
}
j++;
}
outputVector.add(rOutputY);
}
and Here is an example :
ArrayList<Double>inputVector = new ArrayList<Double>();
ArrayList<Double>outputVector = new ArrayList<Double>();
double [] a = new double [] {1.0000,-3.518576748255174,4.687508888099475,-2.809828793526308,0.641351538057564};
double [] b = new double [] { 0.020083365564211,0,-0.040166731128422,0,0.020083365564211};
double []input = new double[]{1,2,3,4,5,6,7,8,9};
for (int i = 0; i < input.length; i++) {
inputVector.add(input[i]);
filter(b, a, inputVector, outputVector);
}
System.out.println(outputVector);
and output was :
[0.020083365564211, 0.11083159422936348, 0.31591188140651166, 0.6484669362153569, 1.099378239134486, 1.6451284697769086, 2.254636012320566, 2.894724888960297, 3.534126758562545]
as in Matlab output
That's it
I found my mistake. Here's the working code (as a function):
function filtered = myFilter(b, a, raw)
filtered = zeros(size(raw));
for c = 1:3
for n = 9:size(raw,1)
filtered(n,c) = b(1)* raw(n,c) + b(2)* raw(n-1,c) + b(3)* raw(n-2,c) ...
+ b(4)* raw(n-3,c) + b(5)* raw(n-4,c) + b(6)* raw(n-5,c) ...
+ b(7)* raw(n-6,c) + b(8)* raw(n-7,c) + b(9)* raw(n-8,c) ...
- a(1)*filtered(n,c) - a(2)*filtered(n-1,c) - a(3)*filtered(n-2,c) ...
- a(4)*filtered(n-3,c) - a(5)*filtered(n-4,c) - a(6)*filtered(n-5,c) ...
- a(7)*filtered(n-6,c) - a(8)*filtered(n-7,c) - a(9)*filtered(n-8,c);
end
end
Now the filter works nearly fine, but at the first 40 values i've got divergent results. I'll have to figure that out...
BlackEagle's solution does not reproduce the same results as MATLAB with other arrays. For example:
b = [0.1 0.1]
a = [2 -2.5 1]
u = [1, zeros(1, 30)];
z = filter(b, a, u)
Gives you completely other results. Be careful.

reading and writing an image simultaneously Processing

I'm generating probability tables for one color appearing to the right of another. I have accomplished all of this. I store the tables in objects which are created for each color value. My problem is, that when I generate a new image, I'd like to create pixel 0, then make a weighted random decision for the color that will appear to the right. I think my problem is that I'm trying to read data from image I'm constructing, and write to it in the same loop. I'm not sure how processing deals with this, and I seem to be getting strange errors, often, many of my pixels are black. I believe all of my problems are occurring the third time I loop through all of the pixels (lines 60-78), and try to write pixels to the new image.
you can see in the output of println statement the colors that should be written to the new image.
Is there something I'm missing?
This is the first time I've used classes and objects to code, so please forgive any clunkiness.
Thanks in advance for any help anyone can offer.
PImage src;
PImage dstn;
HashMap library;
int counter;
color d = (0);
color seed = (0);
color ds = (0);
void setup() {
library = new HashMap<Integer, Object>();
size(200, 200);
src = loadImage("sunflower.jpg");
dstn = createImage(src.width, src.height, RGB);
src.loadPixels();
int acc = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + y*width;
color d = src.get(x,y); // get pixel color at desired location
if (library.containsKey(d)) {
// Get the AColor object and increase the count
// We access objects from the library via its key, the String
AColor c = (AColor) library.get(d);
c.count(); // touch the counter everytime the a color is read
c.the_color(d); // add the color to the object
//c.output();
} else {
// Otherwise make a new entry in library
AColor c = new AColor(d);
// And add to the library
// put() takes two arguments, "key" and "value"
// The key for us is the String and the value is the AColor object
library.put(d, c);
} // all colors are in library now
AColor c = (AColor) library.get(d);
if (x < width - 1 ) { //If statement to ensure null pixles are not added to transition matrix
color z = src.get(x+1,y);
c.access_matrix_right(z);
} else { // this is a nasty shortcut that wraps the probability of the rightmost pixel to the leftmost pixel
color z = src.get(x,y);
c.access_matrix_right(z);
}
}
}
}
void draw() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
color d = src.get(x,y);
AColor c = (AColor) library.get(d);
c.sort_matrix(); // add and construct all of the ArrayLists for each object
println("first loop");
}
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc1 = ((x + y*width));
color seed = src.get(x,y);
dstn.pixels[0] = seed;
color ds = src.get(x,y); // copy pixel 0 from src to dstn image
AColor c = (AColor) library.get(ds);
float chance;
int acc = 0;
chance = random(1);
float probAccum = (c.probs.get(acc));
while (chance > probAccum) {
acc++;
probAccum = probAccum + (c.probs.get(acc));
int colorToTheRight = c.colors.get(acc);
dstn.pixels[loc1] = colorToTheRight; // <-If I put this outside of the while lopp, the image is more or less normal looking.
}
println(acc + " " + c.colors.get(acc) + " , " + c.colors + " - " + c.probs + " Chance = " + chance +" -color should be" + (c.colors.get(acc)));
dstn.updatePixels();
}
}
dstn.updatePixels();
image(dstn,0,0);
noLoop();
}
class AColor {
float count;
int theColor;
int colorRight;
int acc = 0;
int z;
HashMap<Object, Integer> matrix = new HashMap<Object, Integer>();
ArrayList<Float> probs;
ArrayList<Integer> colors = new ArrayList<Integer>(); //an ArrayList is used here. Perhaps it would be better to use an Array and iterate over the hashmap to set the length
AColor(int theColorTemp) {
theColor = theColorTemp;
count = 1;
}
void the_color(int theColorTemp) {
theColor = theColorTemp;
}
void count() {
count++;
}
void access_matrix_right(int colorRightTemp) {
colorRight = colorRightTemp;
if (matrix.containsKey(colorRight)) { // if library has entry for current pixel
int val = ((Integer) matrix.get(colorRight)).intValue(); //accumulator
matrix.put(colorRight, new Integer(val + 1)); // add 1 to
}
else {
matrix.put(colorRight,1); //adds entry & a value of 1 if entry does not exist
colors.add(colorRight);
}
}
void sort_matrix() {
probs = new ArrayList<Float>();
for (int i = 0; i <= colors.size()-1; i++) { //for number elements in list
probs.add((matrix.get(colors.get(i))) / count); // add element in array probs (number of occurrances of a color on the right/ total pixels on right )
}
}
}
Why not read all your pixels into a second image write to that, then write that back to the original one?
wouldn't something like this work? (untested)
int numPixelsX = 500;
int numPixelsY = 500;
PImage captureImage = createImage (numPixelsX,numPixelsY, ARGB);
void setup(){
size(500,500);
}
void draw(){
captureImage.loadPixels();
captureImage = pushPixels(captureImage);
captureImage.updatePixels();
image(captureImage, 0, 0);
}
PImage pushPixels(PImage readImage){
PImage writeImage = createImage(numPixelsX,numPixelsY,ARGB);
writeImage.loadPixels();
writeImage = readImage();
//do your stuff here from the read image to the write image
writeImage.updatePixels();
return writeImage;
}

Resources