Pixel reordering is wrong when trying to process and display image copy with lower res - image

I'm currently making an application using processing intended to take an image and apply 8bit style processing to it: that is to make it look pixelated. To do this it has a method that take a style and window size as parameters (style is the shape in which the window is to be displayed - rect, ellipse, cross etc, and window size is a number between 1-10 squared) - to produce results similar to the iphone app pxl ( http://itunes.apple.com/us/app/pxl./id499620829?mt=8 ). This method then counts through the image's pixels, window by window averages the colour of the window and displays a rect(or which every shape/style chosen) at the equivalent space on the other side of the sketch window (the sketch when run is supposed to display the original image on the left mirror it with the processed version on the right).
The problem Im having is when drawing the averaged colour rects, the order in which they display becomes skewed..
Although the results are rather amusing, they are not what I want. Here the code:
//=========================================================
// GLOBAL VARIABLES
//=========================================================
PImage img;
public int avR, avG, avB;
private final int BLOCKS = 0, DOTS = 1, VERTICAL_CROSSES = 2, HORIZONTAL_CROSSES = 3;
public sRGB styleColour;
//=========================================================
// METHODS FOR AVERAGING WINDOW COLOURS, CREATING AN
// 8 BIT REPRESENTATION OF THE IMAGE AND LOADING AN
// IMAGE
//=========================================================
public sRGB averageWindowColour(color [] c){
// RGB Variables
float r = 0;
float g = 0;
float b = 0;
// Iterator
int i = 0;
int sizeOfWindow = c.length;
// Count through the window's pixels, store the
// red, green and blue values in the RGB variables
// and sum them into the average variables
for(i = 0; i < c.length; i++){
r = red (c[i]);
g = green(c[i]);
b = blue (c[i]);
avR += r;
avG += g;
avB += b;
}
// Divide the sum of the red, green and blue
// values by the number of pixels in the window
// to obtain the average
avR = avR / sizeOfWindow;
avG = avG / sizeOfWindow;
avB = avB / sizeOfWindow;
// Return the colour
return new sRGB(avR,avG,avB);
}
public void eightBitIT(int style, int windowSize){
img.loadPixels();
for(int wx = 0; wx < img.width; wx += (sqrt(windowSize))){
for(int wy = 0; wy < img.height; wy += (sqrt(windowSize))){
color [] tempCols = new color[windowSize];
int i = 0;
for(int x = 0; x < (sqrt(windowSize)); x ++){
for(int y = 0; y < (sqrt(windowSize)); y ++){
int loc = (wx+x) + (y+wy)*(img.width-windowSize);
tempCols[i] = img.pixels[loc];
// println("Window loc X: "+(wx+(img.width+5))+" Window loc Y: "+(wy+5)+" Window pix X: "+x+" Window Pix Y: "+y);
i++;
}
}
//this is ment to be in a switch test (0 = rect, 1 ellipse etc)
styleColour = new sRGB(averageWindowColour(tempCols));
//println("R: "+ red(styleColour.returnColourScaled())+" G: "+green(styleColour.returnColourScaled())+" B: "+blue(styleColour.returnColourScaled()));
rectMode(CORNER);
noStroke();
fill(styleColour.returnColourScaled());
//println("Rect Loc X: "+(wx+(img.width+5))+" Y: "+(wy+5));
ellipse(wx+(img.width+5),wy+5,sqrt(windowSize),sqrt(windowSize));
}
}
}
public PImage load(String s){
PImage temp = loadImage(s);
temp.resize(600,470);
return temp;
}
void setup(){
background(0);
// Load the image and set size of screen to its size*2 + the borders
// and display the image.
img = loadImage("oscilloscope.jpg");
size(img.width*2+15,(img.height+10));
frameRate(25);
image(img,5,5);
// Draw the borders
strokeWeight(5);
stroke(255);
rectMode(CORNERS);
noFill();
rect(2.5,2.5,img.width+3,height-3);
rect(img.width+2.5,2.5,width-3,height-3);
stroke(255,0,0);
strokeWeight(1);
rect(5,5,9,9); //window example
// process the image
eightBitIT(BLOCKS, 16);
}
void draw(){
//eightBitIT(BLOCKS, 4);
//println("X: "+mouseX+" Y: "+mouseY);
}
This has been bugging me for a while now as I can't see where in my code im offsetting the coordinates so they display like this. I know its probably something very trivial but I can seem to work it out. If anyone can spot why this skewed reordering is happening i would be much obliged as i have quite a lot of other ideas i want to implement and this is holding me back...
Thanks,

Related

Colored Letters with Colorcycle | Processing

I found a program, that generates random letters in a grid and gives them a random color.
How can I have the letters cange in color or brightness while the program is running?
(sourcecode: https://happycoding.io/examples/processing/for-loops/letters)
I tried making the fill(r, g, b) have a 'r' that cycles from 1 to 255 and back while having 'g' and 'b' at 0, but I could´t get it to update the color. Im cinda new to programming so I´d love to know how I could make that happen.
First, let's change the fill method to accept RGB values:
fill(random(256),random(256),random(256));
To change the colors while the program is running, the changes must be made inside the draw() method, that will constantly loop and update the canvas. Further information about draw here I believe the following code outputs what you asked for:
int rows = 10;
int cols = 10;
int cellHeight;
int cellWidth;
void setup(){
size(500, 500);
cellHeight = height/rows;
cellWidth = width/cols;
textAlign(CENTER, CENTER);
textSize(28);
}
void draw(){
background(32);
for(int y = 0; y < rows; y++){
for(int x = 0; x < cols; x++){
//get a random ascii letter
char c = '!';
c += random(93);
//calculate cell position
int pixelX = cellWidth * x;
int pixelY = cellHeight * y;
//add half to center letters
pixelX += cellWidth/2;
pixelY += cellHeight/2;
fill(random(256),random(256),random(256));
text(c, pixelX, pixelY);
}
}
delay(100);
}

How to slow down random color generator in Processing?

Hi everyone – I want to make a grid pattern of rectangles with random filling colors out of an array.I can get it done the way I want – but the random selection is way too speedy.
I tried to slow everything down with frameRate(); – but this slows down the whole animation. (For example if I want to add something else). Then I tried to slow it down with if(frameCount%20 == 0) {…} but this does not keep the drawn grid – only lets it appear every XXX frames for one frame – does someone have an idea how I could slow down the lets call it "Color Noise"? – Thank you for any kind of help!
float size = 20;
color cbw = color(0, 0, 0); //defines BLACK
color cg = color(0, 255, 0); //defines GREEN
color cb = color(0, 0, 255); //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = { //random selects one of above colors
cbw, cg, cb, cw
};
void setup() {
size(1080, 1080);
}
void draw() {
background(255);
for (int x = 0; x < width/size; x++) {
for (int y = 0; y < height/size; y++) {
color c1 = (colors[int(random(0, 4))]); //assigns a random color from above to c1-4
fill(c1);
noStroke();
rect(size*x, size*y, size, size);
}
}
}
You're on the right track with frameCount % 20. (Alternatively you can use millis())
The main issue is the colour selection is tightly coupled with the rectangle drawing.
In plain English, currently you can only select random colours and render at the same time, but not select colours and render independently (e.g. at different times)
One option is to use an array to store the colours for every rectangle which you can use twice:
to write values to: pick random colours
to read values from: when rendering the rectangles
Here's a modified version of your sketch that illustrated the idea above:
float size = 20;
color cbw = color(0, 0, 0); //defines BLACK
color cg = color(0, 255, 0); //defines GREEN
color cb = color(0, 0, 255); //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = { //random selects one of above colors
cbw, cg, cb, cw
};
// all colors for each rect
color[][] rectColors;
void setup() {
size(1080, 1080);
// allocate invidual rect colours
rectColors = new color[width/(int)size][height/(int)size];
}
void draw() {
background(255);
if(frameCount%20 == 0){
// randomize colours
int numColors = colors.length;
for (int x = 0; x < width/size; x++) {
for (int y = 0; y < height/size; y++) {
rectColors[x][y] = colors[int(random(0, numColors))];
}
}
}
for (int x = 0; x < width/size; x++) {
for (int y = 0; y < height/size; y++) {
color c1 = rectColors[x][y]; //assigns a random color from above to c1-4
fill(c1);
noStroke();
rect(size*x, size*y, size, size);
}
}
}
Personally, I would do a few extra things to make this easier to read and potentially re-use in other sketches:
change float size = 20; to int size = 20; assuming you want the grid cells to land on whole pixels. This removes the need to cast (e.g. width/(int)size)
cache/store data that is often re-used (such as grid rows and columns)
encapsulate the loops that randomize colours and render rectangles into separate functions. Even something as simple as functions that return no values and take no arguments (e.g. much like void setup() for example)
Here is what that could look like:
int size = 20;
color cbw = color(0, 0, 0); //defines BLACK
color cg = color(0, 255, 0); //defines GREEN
color cb = color(0, 0, 255); //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = { //random selects one of above colors
cbw, cg, cb, cw
};
// all colours for each rect
color[][] rectColors;
// grid dimensions
int cols;
int rows;
void setup() {
size(1080, 1080);
// compute grid dimensions
cols = width / size;
rows = height / size;
// allocate invidual rect colours
rectColors = new color[cols][rows];
// call randomize colours function
randomizeColors();
}
// declare randomize colours function
void randomizeColors(){
// read array length, avoding the previosuly hardcoded value (4)
int numColors = colors.length;
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
rectColors[x][y] = colors[int(random(0, numColors))];
}
}
}
void drawRectangles(){
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
color c1 = rectColors[x][y]; //read a random color
fill(c1);
noStroke();
rect(size * x, size * y, size, size);
}
}
}
void draw() {
background(255);
if(frameCount % 20 == 0){
randomizeColors();
}
drawRectangles();
}

Kinect Depth Histogram in Processing

I'm trying to create a histogram displaying the distances scanned by a Kinect vs. their occurrences. I've adapted the Histogram example code to create a depth histogram, but it's currently displaying the depth at each pixel (from left to right) multiple times across the depth image width.
What I'm looking to do is reorder the depth information so that it ranges from the lowest value (that isn't 0) to the highest on the x axis, and shows their occurrences on the y. I'm using Processing, so I'm unsure if this is the right site to be posting on, but I've tried on the posting forum and not gotten any help. If anyone can show me where I'm going wrong, that'd be awesome. My current code is below, and a screenshot of my current output can be found here
import SimpleOpenNI.*;
SimpleOpenNI kinect;
void setup() {
size(1200, 580);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
}
void draw () {
kinect.update();
PImage depthImage = kinect.depthImage();
image (depthImage, 11, 0);
int[] depthValues = kinect.depthMap();
int[] hist = new int[716800];
for (int x = 11; x < depthImage.width; x++) {
for (int y = 0; y < depthImage.height; y++) {
int i = x + y * 640;
hist[i] = depthValues[i];
}
}
int histMax = max(hist);
stroke(20);
for (int i = 0; i < depthImage.width; i += 2) {
int which = int(map(i, 0, depthImage.width, 0, histMax));
int y = int(map(hist[which], 0, histMax, depthImage.height, 0));
line(i, depthImage.height, i, y);
}
}
I think you're asking two questions here.
How to get the histogram to go from 0-N:
Use Processing's sort() function to sort the array.
hist = sort(hist); // sorts your array numerically
How to get the histogram to fill the screen:
I'm not entirely sure why it's drawing twice, but I think you can clean up your code quite a bit.
// how far apart are the bars - set based on screen dimensions
int barSpacing = width / hist.length;
for (int i=0; i<hist.length; i++) {
// get value and map into usable range (note 10 not 0 for min)
int h = int(map(hist[i], 0,histMax, 10,height));
// set x position onscreen
int x = i * barSpacing;
// draw the bar
line(x,height, x,height-h);
}

How do I get a random number to stay fixed with slick?

I'm a beginner in Java as well as with the slick tools. I want to make a game that has different coloured cubes randomly placed within a certain area of the window.
I use two for-loops and call for a random number in render. I get the cubes placed exactly as I want, but the problems is that they flicker in all colours. I guess it has to do with how I call for a random number and that it gets updated with FPS?!
Please help me!!
public void render(GameContainer gc, StateBasedGame sdg, Graphics g) throws SlickException {
//set background
Image background = (new Image("res/background.png")).getScaledCopy(800, 500);
g.drawImage(background, 0, 0);
//set gamescape
blue = (new Image("res/blue.png")).getScaledCopy(20,20);
green = (new Image("res/green.png")).getScaledCopy(20,20);
red = (new Image("res/red.png")).getScaledCopy(20,20);
int xvalue = 300;
int yvalue = 400;
for (int a = 1; a < 20; a++) {
for (int i = 1; i < 10; i++) {
r = rand.nextInt(3);
if(r==0){g.drawImage(blue,xvalue,yvalue);}
else if(r==1){g.drawImage(red, xvalue, yvalue);}
else{g.drawImage(green, xvalue, yvalue);}
xvalue = xvalue+20;
}
yvalue = yvalue - 20;
xvalue = xvalue -180;
}
}
Your problem is that you generate a new random number each time you redraw the scene.
To resolve this, you may have to create an array in which you store the generated color of each cube. And each time you redraw your images, you just read each color value in the array.

How can I return to the original image after change the color pixels on my image in processing?

In the program below, I try to change the pixel colors form a image with the click of the mouse, however, I'm trying to return to the original image with the second click but I haven't been able to find the rigth argument to do it...
PImage pic;
void setup(){
pic=loadImage("road.jpg"); // Loading the image from a folder "date" attached to the sketch
size (pic.width,pic.height);
image(pic,0,0);
}
void draw(){
}
void mousePressed(){
loadPixels();
pic.loadPixels();
for (int y = 0; y < height; y++ ) {
for (int x = 0; x < width; x++ ) {
int loc = x + y*width;
if(red(pixels[loc]) >170 && red(pixels[loc])<215){
pixels[loc]=color(187,0,0); //changing the pixels color from red to green
}
}
}
for (int y = 0; y < height; y++ ) {
for (int x = 0; x < width; x++ ) {
int loc = x + y*width;
if(green(pixels[loc]) >120 && green(pixels[loc])<160){
pixels[loc]=color(0,192,0); //changing the pixels color form green to red
}
}
}
// I belive that here I have to add an argument that returns to the original image
updatePixels();
}
I will appreciate any help.
Thanks.
What I typically do for this sort of thing is to create /two/ images, one being the file (target) and the other being a blank Image.
PImage target;
PImage destination;
target = loadImage("file.jpg");
destination = createImage(target.width, target.height, RGB);
And then I copy the target's information into the destination's pixels. If I want to switch back, I can just call target; I'm able to freely swap back and forth by saving them as two separate images.
For an example, check out a sketch of mine on openprocesing: http://openprocessing.org/visuals/?visualID=49301

Resources