Im sure there is a pretty straight forward answer to this...cant quite figure it out though.
In my processing sketch's data folder, there is a folder named test_segments. test_segments contains a bunch of images.
I need to load an image from test_segments into my PImage.
It looks like this: http://imgur.com/a/iG3B6
My code:
final int len=25;
final float thresh=170;
boolean newDesign=false;
PImage pic;
ArrayList<PImage> imgContainer;
int n=3;
void setup() {
size(800, 800, P2D);
colorMode(RGB, 255);
background(250, 250, 250);
rectMode(CENTER);
//imageMode(CENTER);
pic=loadImage("hand.jpg");
pic.resize(width, height);
color c1 = color(200,25,25);
color c2 = color(25, 255, 200);
imgContainer=new ArrayList<PImage>();
PImage pimg1=loadImage("this is where test_0.png needs to go")
pimg1.resize(50, 50);
imgContainer.add(pimg1);
noLoop();
noStroke();
}
void draw() {
if (newDesign==false) {
return;
}
pic.loadPixels();
for (int y = 0; y < height; y+=40) {
for (int x = 0; x < width; x+=40) {
int index=y*width+x;
color pixelValue = pic.pixels[index];
color rgb = pixelValue;
int r = (rgb >> 16) & 0xFF; // Faster way of getting red(argb)
int g = (rgb >> 8) & 0xFF; // Faster way of getting green(argb)
int b = rgb & 0xFF;
//How far is the current color from white
float dista=dist(r,g,b,255,255,255);
//50 is a threshold value allowing close to white being identified as white
//This value needs to be adjusted based on your actual background color
//Next block is processed only if the pixel not white
if(dista>30){
float pixelBrightness = brightness(pixelValue);
float imgPicked=constrain(pixelBrightness/thresh, 0, n-1);
image(imgContainer.get((int)imgPicked),x,y);
}
}
}
}
void mouseReleased() {
newDesign=!newDesign;
redraw();
}
Thanks!
You should just be able to do:
PImage pimg1 = loadImage("test_segments/test_0.png");
If that doesn't work, please try to post a MCVE like we talked about before. Here's an example of an MCVE that would demonstrate your problem:
PImage pimg1 = loadImage("test_segments/test_0.png");
image(pimg1, 0, 0);
Don't forget to include exactly what you expect to happen, and exactly what's happening instead. Good luck.
Related
Clarifying my last question:
I would like to display, in Processing, many photos fading up and fading down over 15 seconds, with one second between their start times, so there are about 15 images on the screen at a time, at various levels of fading.
This example displays 15 objects, but they all start together:
PImage[] imgs = new PImage[42];
Pic[] pics = new Pic[15];
void setup() {
size(1000, 880);
for (int i = 0; i < pics.length; i++) {
pics[i] = new Pic(int(random(0, 29)), random(0, 800), random(0, height));
}
for (int i = 0; i < imgs.length; i++) {
imgs[i] = loadImage(i+".png");
}
}
void draw() {
background(255);
for (int i = 0; i < pics.length; i++) {
pics[i].display();
}
}
class Pic {
float x;
float y;
int num;
int f = 0;
boolean change = true;
Pic(int tempNum, float tempX, float tempY) {
num = tempNum;
x = tempX;
y = tempY;
}
void display() {
imageMode(CENTER);
if (change)f++;
else f--;
if (f==0||f==555)change=!change;
tint(0, 153, 204, f);
image(imgs[num], x, y);
}
}
If you can fade an image, then you can also cross fade an image by subtracting the fade amount from the maximum fade value (e.g. inverting the fade value).
In your case you're using tint so it's a value from 0-255.
Let's say tint is your variable: 255 - tint would be the inverted value.
Here's a basic sketch you can run that illustrates this (using fill() instead of tint()):
void draw(){
float fade = map(sin(frameCount * 0.03), -1.0, 1.0, 0, 255);
background(0);
noStroke();
// use fade value
fill(192, 0, 192, fade);
ellipse(45, 50, 60, 60);
// invert the fade value (by subtracting it from the max value)
fill(0, 192, 192, 255 - fade);
ellipse(60, 50, 60, 60);
}
Continuing from the previous question and answer you can tweak the code to use an inverted tint value to crossfade. The catch is you'd need to store a reference to the previous image to apply the inverted tint to:
PImage[] imgs = new PImage[42];
ImagesFader fader;
void setup(){
size(255, 255);
frameRate(60);
// load images
for (int i = 0; i < imgs.length; i++) {
imgs[i] = loadImage(i+".png");
}
// setup fader instance
// constructor args: PImage[] images, float transitionDurationSeconds, int frameRate
// use imgs as the images array, transition in and out within 1s per image at 60 frames per second
fader = new ImagesFader(imgs, 3.0, 60);
}
void draw(){
background(0);
fader.draw();
}
class ImagesFader{
int numFrames;
int numFramesHalf;
int frameIndex = 0;
PImage[] images;
int maxImages = 15;
int randomImageIndex;
float randomX, randomY;
PImage previousImage;
float previousX, previousY;
ImagesFader(PImage[] images, float transitionDurationSeconds, int frameRate){
numFrames = (int)(frameRate * transitionDurationSeconds);
numFramesHalf = numFrames / 2;
println(numFrames);
this.images = images;
// safety check: ensure maxImage index isn't larger than the total number of images
maxImages = min(maxImages, images.length - 1);
// pick random index
randomizeImage();
}
void draw(){
updateFrameAndImageIndices();
PImage randomImage = imgs[randomImageIndex];
// isolate drawing style (so only the image fades, not everything in the sketch)
pushStyle();
// if there is a previous image, cross fade it
float tintAlpha = tintFromFrameIndex();
if(previousImage != null){
// invert tint -> max(255) - value
tint(255, 255 - tintAlpha);
image(previousImage, previousX, previousY);
}
// render current random image (on top of the previous one, if any)
tint(255, tintAlpha);
image(randomImage, randomX, randomY);
popStyle();
}
float tintFromFrameIndex(){
int frameIndexToTint = abs(frameIndex - numFramesHalf);
return map(frameIndexToTint, 0, numFramesHalf, 255, 0);
}
void updateFrameAndImageIndices(){
// increment frame
frameIndex++;
// reset frame (if larger than transition frames total)
if(frameIndex >= numFrames){
// update previous image before generating another random image
previousImage = imgs[randomImageIndex];
previousY = randomX;
previousY = randomY;
frameIndex = 0;
// randomize index and position
randomizeImage();
println("fade transition complete, next image: ", randomImageIndex);
}
}
void randomizeImage(){
randomImageIndex = int(random(0, 29));
randomX = random(width);
randomY = random(height);
}
}
The above skeetch might not be 100% accurate (as I don't fully get the randomisation logic), but hopefully it illustrates the mechanism of crossfading.
I am trying to make a spinning cube in Processing's P3D with this code:
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
background(0);
box(sizes/2);
rotation = (rotation + 1);
}
When I run it the cube does spin as I wanted, but there are strange 'artifacts' (for lack of a better name) left behind its edges.
What causes this issue, and can it be solved?
I tried this and it worked. Maybe instead of using backround(0), set every pixel to black like the background function does manually.
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
fill(255);
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
loadPixels();
for(int i = 0; i < pixels.length; i++) pixels[i] = color(0);
box(sizes/2);
rotation = (rotation + 1);
}
I cant figure this out. I have a sketch with little rotating rectangles on it. They rotate on every draw(). However the previous rectangle remains visible. I tried moving background() around but it either gets rid of all the rectangles apart from one or it doesn't clear the screen. I would like to be able to clear all the rectangles after each draw.
Here is the code:
//Create array of objects
ArrayList<Circle> circles = new ArrayList<Circle>();
ArrayList<Connector> centrePoint = new ArrayList<Connector>();
void setup(){
size(800, 800);
frameRate(1);
rectMode(CENTER);
background(204);
for(int i = 1; i < 50; i++){
float r = random(100,height-100);
float s = random(100,width-100);
float t = 20;
float u = 20;
println("Print ellipse r and s " + r,s);
circles.add(new Circle(r,s,t,u,color(14,255,255),random(360),random(5),random(10)));
}
//Draw out all the circles from the array
for(Circle circle : circles){
circle.draw();
float connectStartX = circle.x1;
float connectStartY = circle.y1;
println("PrintconnectStartX and Y " + connectStartX,connectStartY);
for(Circle circleEnd : circles){
float connectEndX = (circleEnd.x1);
float connectEndY = (circleEnd.y1);
centrePoint.add(new Connector(connectStartX,connectStartY,connectEndX,connectEndY));
}
}
//For each ellipse, add the centre point of the ellipse to array
for(Connector connectUp : centrePoint){
println(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
stroke(100, 0, 0);
if (dist(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY) < 75){
connectUp.draw(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
}
}
//For the line weight it should equal the fat of the node it has come from ie
//for each circle, for each connectUp if the x==connectStartX and y==connectStartY then make the line strokeWeight==fat
for(Circle circle : circles){
for(Connector connectUp : centrePoint){
if (connectUp.connectStartX == circle.x1 & connectUp.connectStartY == circle.y1 & (dist(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY) < 75)){
print(" true "+ circle.fat);
float authority = circle.fat;
strokeWeight(authority*1.5);
connectUp.draw(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
}
}
}
}
void update(){
}
void draw() {
for(Circle circle : circles){
circle.rot =+0.02;
circle.draw();
circle.rot = random(-6,6);
}
}
//Need to connect each ellipse to all the other ellipses
class Connector {
public float connectStartX;
public float connectStartY;
public float connectEndX;
public float connectEndY;
public color cB;
public float thickness;
public Connector(float connectStartX, float connectStartY, float connectEndX, float connectEndY){
this.connectStartX = connectStartX;
this.connectStartY = connectStartY;
this.connectEndX = connectEndX;
this.connectEndY = connectEndY;
//this.cB = tempcB;
//this.thickness = thickness;
}
void draw(float connectStartX, float connectStartY, float connectEndX, float connectEndY){
line(connectStartX, connectStartY, connectEndX, connectEndY);
// float fat = random(255);
//fill(fat);
stroke(100, 0, 0);
}
}
class Circle{
public float x1;
public float y1;
public float x2;
public float y2;
public color cB;
public float rot;
public float fat = random(5);
public float fert = 0.1;
public Circle(float x1, float y1, float x2, float y2, color tempcB, float rot, float fat, float fert){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.cB = tempcB;
//Tilt - I think this is done in radians
this.rot = rot;
//Authority -this is the fill
this.fat = fat;
//Fertility- this is a multiplier for the tilt
this.fert = fert;
}
void draw(){
pushMatrix();
translate(x1, y1);
fert = random(0.5);
rot = random(-6,6);
rotate(rot*fert);
translate(-x1, -y1);
//float fat = random(255);
fill(fat);
rect(x1, y1, 24, 36);
popMatrix();
}
}
You've got a few things going on in your code that I've seen in your previous posts. The way you're doing your drawing doesn't make a ton of sense, and I'll explain why.
Here's what most Processing sketches do:
Use the setup() function to setup any data structures you'll use in your program. Don't do any drawing from the setup() function.
Call background() every frame to clear out old frames.
Draw everything you want to be drawn in the frame in the draw() function.
Modify the data structures to change what you're drawing on the screen.
Your code is a bit too long for an MCVE, so here's a little example that handles the drawing in a more standard way:
ArrayList<PVector> circles = new ArrayList<PVector>();
void setup() {
size(500, 500);
ellipseMode(RADIUS);
//setup your data structures here
circles.add(new PVector(250, 250));
//don't do any drawing yet
}
void mousePressed() {
//modify the data structure whenever you want to change what's on the screen
circles.add(new PVector(mouseX, mouseY));
}
void keyPressed() {
//modify the data structure whenever you want to change what's on the screen
if (!circles.isEmpty()) {
circles.remove(0);
}
}
void draw() {
//call background every frame to clear out old frames
background(0);
//draw everything
for (PVector p : circles) {
ellipse(p.x, p.y, 20, 20);
}
}
Notice how this is different from what you're doing. Here's what you do:
You use the setup() function to setup your data structures, but then you draw the background and some of the objects to the screen.
You then don't call background() from draw(), so you're always stuck with whatever has already been drawn.
You then only draw a subset of what you want on the screen, so you can't redraw your whole scene.
You have to modify your code to no longer draw anything from setup(), to call the background() function every frame, and to draw everything you want on the screen every frame.
What you are doing is printing every single circle or line...ect. You need to have a timer that removes them every so often. If you do it too fast you get a strobe like look. So have a timer that removes the first rect from the array list every so often.
I am tinkering with Processing and cannot figure out how to write text over an image I created using the image buffer (rotating squares)...when the square becomes smaller than the text, the changing digits wrote on top of each other. Cannot use resetting the bkg as a solution because that erases the overlapping images. Still having a hard time understanding this area...
Question: How to get the text to appear on top of the rotating squares without resetting the bkg and without the text writing over itself
Code below
Thank you!
float rotateAmount;
int boxColorR = 255;
int boxColorG = 255;
int boxColorB = 255;
int boxW = 480;
void setup () {
size(640,480);
rectMode(CENTER);
}
void drawText() {
//translate(width/2,height/2);
textAlign(LEFT, CENTER);
fill(255, 255, 255);
textSize(32);
text("RED: " + boxColorR,width/2,height/2);
text("GREEN: " + boxColorG,width/2,height/2+30);
text("BLUE: " + boxColorB,width/2,height/2+60);
text("Box Width: " + boxW,width/2,height/2+90);
}
void drawBox() {
translate(width/2,height/2);
rotateAmount += 12;
if (boxColorR <= 0) {
boxColorG--;
}
if (boxColorG <= 0) {
boxColorB--;
}
boxColorR--;
boxW--;
rotateAmount += .05;
rotate(rotateAmount);
fill(boxColorR,boxColorG,boxColorB);
rect(0,0,boxW,boxW);
resetMatrix();
}
void draw() {
//rect(width/2,height/2,640,480); //this solves the text overlapping but erases the cool effect
drawBox();
drawText();
}
Most Processing sketches use a call to the background() function as the first line in the draw() function. This clears out anything drawn in previous frames.
However, you want to keep the stuff drawn in previous frames, so you don't want to clear them out. The problem with this is that since your text isn't cleared out either, your text ends up looking garbled.
The solution to this is to use the PGraphics class to create an off-screen buffer. You draw the squares to the buffer instead of to the screen. Then you draw the buffer to the screen, and finally, you draw the text on top of the buffer.
Since you draw the buffer to the screen each frame, it clears away the old text, but the squares you've previously drawn are maintained in the buffer.
Code speaks louder than words:
float rotateAmount;
int boxColorR = 255;
int boxColorG = 255;
int boxColorB = 255;
int boxW = 480;
//create a buffer to draw boxes to
PGraphics buffer;
void setup () {
size(640, 480);
buffer = createGraphics(640, 480);
}
void drawText() {
//translate(width/2,height/2);
textAlign(LEFT, CENTER);
fill(255, 255, 255);
textSize(32);
text("RED: " + boxColorR, width/2, height/2);
text("GREEN: " + boxColorG, width/2, height/2+30);
text("BLUE: " + boxColorB, width/2, height/2+60);
text("Box Width: " + boxW, width/2, height/2+90);
}
//draw boxes to buffer
void drawBox() {
buffer.beginDraw();
buffer.rectMode(CENTER);
buffer.translate(width/2, height/2);
rotateAmount += 12;
if (boxColorR <= 0) {
boxColorG--;
}
if (boxColorG <= 0) {
boxColorB--;
}
boxColorR--;
boxW--;
rotateAmount += .05;
buffer.rotate(rotateAmount);
buffer.fill(boxColorR, boxColorG, boxColorB);
buffer.rect(0, 0, boxW, boxW);
buffer.resetMatrix();
buffer.endDraw();
}
void draw() {
//draw the boxes to the buffer
drawBox();
//draw the buffer to the screen
image(buffer, 0, 0);
//draw the text on top of the buffer
drawText();
}
I am working on a robotics project in which I have to some image processing in order to recognize blue colored objects, red colored obstacles, and green colored destination. I am using java for Image Processing.
Right now, I have been able to locate Red, Green, and Blue colored objects using Blobscanner library. But the difficulty is that, my algorithm only works fine when the background is pure Black. Because I am using RGB color model, and in RGB, black is represented as 0,0,0 and white as 255,255,255 and gray color also has some red component in it, so it also gets detected by the algorithm. I don't know the algorithm which exactly pinpoints the red color ignoring others.
Please help me detect only red color (and its other shades) in any image.
Well, while #geotheroy were posting I also gave this a try, it works and also is cool to see :) so I'm posting it anyway... Same base idea thought...
drag vertically to set the threshold, any key to view original.
PImage original, result;
float t = 0.9;
void setup() {
//image linked from this question in processing forum
//http://forum.processing.org/topic/help-random-distribution-of-non-overlapping-circles#25080000001787197
original = loadImage("http://24.media.tumblr.com/tumblr_lzi0y7OpsC1r87izio1_1280.png");
if (original != null) {
size(original.width, original.height);
result = createImage(original.width, original.height, RGB);
result = original.get(0, 0, original.width, original.height);
}
else
{
println("unable to load the image. Are you connected?");
exit();
}
}
void draw() {
if (keyPressed) {
image (original, 0, 0);
}
else {
image(result, 0, 0);
}
}
void mouseDragged() {
t = map(mouseY, 0, height, 0, 1);
findReds(original, t);
}
void findReds(PImage orig, float thresh) {
result = orig.get(0, 0, orig.width, orig.height);
result.loadPixels();
for (int i = 0; i < result.pixels.length; i++) {
color c = result.pixels[i];
float r = c >> 16 & 0xFF;
float g = c >> 8 & 0xFF;
float b = c & 0xFF;
float limitR = r - r*thresh;
if ( g < limitR && b < limitR) {
result.pixels[i] = color(255);
}
}
result.updatePixels();
}
Does this help give you some ideas:
PImage moog;
void setup() {
String url = "http://bananamondaes.files.wordpress.com/2013/02/the-moog.jpg";
moog = loadImage(url, "jpg");
size(moog.width, moog.height);
noStroke();
strokeWeight(10);
textSize(18);
textAlign(CENTER);
}
void draw() {
image(moog, 0, 0);
color c = moog.pixels[mouseY*width + mouseX];
fill(c);
ellipse(450,285,30,17);
ellipse(430,250,50,30);
ellipse(400,200,70,40);
ellipse(360,120,320,60);
fill(0);
text("Red: "+int(red(c))+", Green: "+int(green(c))+", Blue: "+int(blue(c)),360,125);
text("Check out Moog's ears..", 300, 50);
if(red(c)>200 & green(c)<100 & blue(c)<100) {
noFill();
stroke(c);
rect(5,5,width-10,height-10);
noStroke();
}
}