Odd bug with replacing pixels in image from camera

edited February 2016 in Android Mode

Hey, so I'm trying to make a sort of "real time" green screen app with the Ketai library. The end goal of this project is to be able to select a color in the camera view and replace all of that color (within a range) with a preselected background image. Currently, it just replaces a color you tap with green.

The odd thing I'm running into is it only replaces colors selected toward the bottom of the screen, while the method for replacing the image scans left to right, top to bottom.

I've uploaded an example to YouTube:

I filmed it with an external camera because a screen recording would just further slow down the app. You can see the current color selected in the top left corner of the screen.

Here's the code:

import ketai.camera.*;

final float SHADELIM = 5; //specifies range +or- to compare to other color

color chosenColor;
color defaultColor = color(0,255,0);
boolean ColorSelected = false;

KetaiCamera cam;

void setup () {
  orientation(LANDSCAPE);
  rectMode(CORNER);
  imageMode(CENTER);
  cam = new KetaiCamera(this, width, height, 24);
}

void draw () {
  if(ColorSelected) {
    replaceColor(cam, chosenColor, defaultColor);
    fill(chosenColor);
    rect(0, 0, 50, 50);
  }
  image(cam, width/2, height/2);
}

void onCameraPreviewEvent () {
  cam.read();
}

void mousePressed () {
  if(!cam.isStarted()) {
   cam.start();
  }
  else {
    ColorSelected = true;
    chosenColor = findColor(cam);
  }
}

void replaceColor (KetaiCamera camIn, color target, color payload) {
  camIn.loadPixels();
  for(int yPlace = 0; yPlace < camIn.height; yPlace++) {
    for(int xPlace = 0; xPlace < camIn.width; xPlace++) {
      if(compareColors(camIn.pixels[singleCoord(xPlace, yPlace, camIn.width)], target)) {
        camIn.pixels[singleCoord(xPlace, yPlace, camIn.width)] = payload;
      }
    }
  }
  camIn.updatePixels();
}

int singleCoord (float xin, float yin, float widin) {
  return int(xin + (yin * widin));
}

boolean compareColors (color c1, color c2) {
  float red1 = red(c1);
  float red2 = red(c2);
  float green1 = green(c1);
  float green2 = green(c2);
  float blue1 = blue(c1);
  float blue2 = blue(c2);
  if(red1 > (red2 - SHADELIM) && red1 < (red2 + SHADELIM)) {
    if(green1 > (green2 - SHADELIM) && green1 < (green2 + SHADELIM)) {
      if(blue1 > (blue2 - SHADELIM) && blue1 < (blue2 + SHADELIM)) {
        return true;
      }
    }
  }
  return false;
}

color findColor (KetaiCamera camIn) {
  camIn.loadPixels();
  float camXStart = (width / 2) - (camIn.width / 2);
  float camXEnd = (width / 2) + (camIn.width / 2);
  float camYStart = (height / 2) - (camIn.height / 2);
  float camYEnd = (height / 2) + (camIn.height / 2);
  float xPlace = map(mouseX, camXStart, camXEnd, 0, camIn.width);
  float yPlace = map(mouseY, camYStart, camYEnd, 0, camIn.height);
  return camIn.pixels[singleCoord(xPlace, yPlace, camIn.width)];
}

Anyone have an idea as to what's going on here?

Answers

  • Ok so I've done some investigating. When I stop the camera stream after a color has been selected, it correctly fills in all related colors, so the issue must be a streaming problem. I'm assuming the onCameraPrviewEvent is running before the replaceColor can run fully run through. Anyway, I guess a continuous stream isn't an option for this project, unless I can find a way to speed up replaceColor

Sign In or Register to comment.