processing.org 中的简单图像识别

Simple Image Recognition in processing.org

我正在尝试编写最简单的图像比较函数。 这个想法是有一个目标图像和 n 个不同图像的集合。

目标是选择与目标图像最相似的图像。

到目前为止,我的方法包括在调整大小后的图像中定义像素与像素之间的欧氏 HSB 距离,并且一直在尝试执行 PImage 函数以 returns 获胜图像。我已经编写了一个 float 函数来对图像列表从赢家到输家进行排名,但我想跳过这一步以使过程更加简洁。

问题在 PImage difference(PImage){ 函数,程序在行上输出错误:

        float x1 = brightness(imageKey.pixels[i]);

错误是 ArrayIndexOutOfBoundsException

完整代码如下:

//CLICK ON S TO SAVE FRAMES TO FOLDER


int series = 50; //
PImage[] collection = new PImage[series];

PImage imageKey,imageKey2, imageKeyHUE, imageKeySUM, imageKeySAT; //target image alias with ready operations
int imageWidth = 800;
int leftAlign = 850  ;

void setup()
{
size(1200,600);
background(255);
frameRate(random(1,10.0));

for ( int i = 0; i< collection.length; i++ )
{
collection[i] = loadImage( "Image_"+ i + ".jpg" );  
}

//_____________________________________________TARGET IMAGE AND NAME TEXT

textSize(10);
fill(0);
text("target image", leftAlign, 220);
textSize(15);
text("central london", leftAlign, 240);
text("comparison methods", leftAlign, 290);
//_____________________________________________________________________BUTTONS
imageKey = loadImage("Image_0.jpg");
imageKey.resize(240, 180);
image(imageKey, leftAlign,25);

   imageKeySAT= loadImage("Image_0.jpg");
    imageKeySAT.resize(60,60);
    imageKeySAT = saturation(imageKeySAT);
    image(imageKeySAT, leftAlign+140,300);

      imageKeySUM = loadImage("Image_0.jpg");
      imageKeySUM.resize(60,60);
      imageKeySUM = sum(imageKeySUM);
      image(imageKeySUM, leftAlign+70,300);

          imageKeyHUE = loadImage("Image_0.jpg");
          imageKeyHUE.resize(60,60);
          imageKeyHUE = hue(imageKeyHUE);
          image(imageKeyHUE, leftAlign,300);

          textSize(20);
          text("CLICK HERE TO", leftAlign, 430);
          text("STOP AT WINNER", leftAlign, 450);



}


void draw()
{

//______________________________________________SHOW IMAGES ARRAY
image(collection[int(random(0,series))],0,0);

//______________________________________________HISTOGRAMS
histogramhue();
histogramsat();
histogrambright();

//______________________________________________SUM METHOD
//float Vector_Approach(PImage sumSatin){


//}

}


void keyPressed()
{
  if(key=='s') saveFrame("images/image-######.jpg");
}


PImage difference(PImage satin)
{
  colorMode(HSB);

    satin.loadPixels();
    imageKey.loadPixels();

    PImage satout = createImage(satin.width, satin.height, RGB);

    satout.loadPixels();
    for(int i = imageWidth; i<satout.pixels.length-imageWidth; i++)
    {
        float x1 = brightness(imageKey.pixels[i]);
        float b0 = brightness(satin.pixels[i]);
       // float y1 = brightness(satin.pixels[i+1]);

        float value = x1-b0;

        satout.pixels[i] = color(0,0,value);

    }
    satout.updatePixels();

    return satout;    
}

void mouseReleased(){
//______________________________________________BUTTON OVER
for ( int i = 0; i< collection.length; i++ )
  if (mouseX > leftAlign && mouseX < (leftAlign + 60) && mouseY > 300 && mouseY < 360){

            collection[i] = loadImage( "Image_"+ i + ".jpg" );  
            collection[i] = hue(collection[i]); histogramhue();
                  noStroke(); fill(255); rect(leftAlign,360,200,40); fill(0);
                  textSize(10);text("comparison by hue", leftAlign, 380);

} else if (mouseX > (leftAlign + 70) && mouseX < (leftAlign + 130) && mouseY > 300 && mouseY < 360)
{

            collection[i] = loadImage( "Image_"+ i + ".jpg" );  
            collection[i] = sum(collection[i]);
                  noStroke(); fill(255); rect(leftAlign,360,200,40); fill(0);
                  textSize(10);text("comparison by sum", leftAlign, 380);

}else if (mouseX > (leftAlign + 140) && mouseX < (leftAlign + 200) && mouseY > 300 && mouseY < 360)
{

          collection[i] = loadImage( "Image_"+ i + ".jpg" );  
          collection[i] = saturation(collection[i]);
                  noStroke(); fill(255); rect(leftAlign,360,200,40); fill(0);
                  textSize(10);text("comparison by saturation", leftAlign, 380);


}else if (mouseX > leftAlign && mouseX < 1200 && mouseY > 340 && mouseY < 600)
{

          collection[i] = loadImage( "Image_"+ i + ".jpg" );  
          collection[i] = difference(collection[i]);
                  noStroke(); fill(255); rect(leftAlign,360,200,40); fill(0);
                  textSize(10);text("WINNER IMAGE!!!!", leftAlign, 380);
}else{

    collection[i] = loadImage( "Image_"+ i + ".jpg" );  
    noStroke(); fill(255); rect(leftAlign,360,200,40); fill(0);

}
}



/*          HSB PImage Methods             */

 //HUE              ------->    /** CHOSEN METHOD**/
 //SATURATION       ------->    /** CHOSEN METHOD**/
 //SUM              ------->    /** CHOSEN METHOD**/





PImage hue(PImage satin)
{
      colorMode(HSB);
      satin.loadPixels();

      PImage satout = createImage(satin.width, satin.height, HSB);

      satout.loadPixels();

      for (int j = 0; j < satout.pixels.length; j++)
      {
      satout.pixels[j] = color(hue(satin.pixels[j]),255,255);
      }

satout.updatePixels();

return satout;
} 

PImage saturation(PImage satin)
{
      colorMode(HSB);
      satin.loadPixels();
      PImage satout = createImage(satin.width, satin.height, RGB);
      satout.loadPixels();
      for (int j = 0; j < satout.pixels.length; j++)
      {
      satout.pixels[j] = color(saturation(satin.pixels[j]));
      }

satout.updatePixels();
//colorMode(RGB);
return satout;
} 



PImage sum(PImage satin)
{
  colorMode(HSB);

    satin.loadPixels();

    PImage satout = createImage(satin.width, satin.height, RGB);

    satout.loadPixels();
    for(int i = imageWidth; i<satout.pixels.length-imageWidth; i++)
    {
        float b0 = brightness(satin.pixels[i]);
        float x1 = brightness(satin.pixels[i-1]);
        float y1 = brightness(satin.pixels[i-imageWidth]);

        float xdiff = b0-x1;
        float ydiff = b0-y1;

        float value = (510 + xdiff + ydiff)/3;

        satout.pixels[i] = color(0,0,value);

    }
    satout.updatePixels();

    return satout;    
}

//REFERENCE HISTOGRAM TAKEN FROM A PROGRAMMING HANDBOOK FOR VISUAL DESIGNERS AND ARTISTS BY BEN FRY ET AL

void histogramhue(){
PImage img = loadImage("Image_0.jpg");
int[] hist = new int[600];

// Calculate the histogram
for (int i = 0; i < img.width; i++) {
  for (int j = 0; j < img.height; j++) {
    int hue = int(hue(get(i, j)));
    hist[hue]++; 
  }
}

int histMax = max(hist);

stroke(255,250); strokeWeight(5);
// Draw half of the histogram (skip every second value)
for (int i = 0; i < img.width; i += 20) {
  int which = int(map(i, 0, img.width, 0, 255));
  int y = int(map(hist[which], 0, histMax, img.height, 0));
  line(i, img.height, i, y);
}}


void histogramsat(){
PImage img = loadImage("Image_0.jpg");

int[] hist = new int[600];

for (int i = 0; i < img.width; i++) {
  for (int j = 0; j < img.height; j++) {
    int sat = int(saturation(get(i, j)));
    hist[sat]++; 
  }
}

int histMax = max(hist);

stroke(255,150);strokeWeight(10);
for (int i = 0; i < img.width; i += 20) {
  int which = int(map(i, 0, img.width, 0, 255));
  int y = int(map(hist[which], 0, histMax, img.height, 0));
  line(i, img.height, i, y);
}}

void histogrambright(){
PImage img = loadImage("Image_0.jpg");

int[] hist = new int[600];


for (int i = 0; i < img.width; i++) {
  for (int j = 0; j < img.height; j++) {
    int bright = int(brightness(get(i, j)));
    hist[bright]++; 
  }
}
int histMax = max(hist);

stroke(255, 150);strokeWeight(20);
for (int i = 0; i < img.width; i += 20) {
  int which = int(map(i, 0, img.width, 0, 255));
  int y = int(map(hist[which], 0, histMax, img.height, 0));
  line(i, img.height, i, y);
}}

单独来看,您的功能似乎确实有效:

PImage imageKey,testImage;
int imageWidth = 800;
int imageHeight = 600;

void setup(){
  size(1600,600);
  //fake imageKey
  imageKey = getNoise(imageWidth,imageHeight);

  //fake test image
  testImage = getNoise(imageWidth,imageHeight);

  image(testImage,0,0);
  image(difference(testImage),800,0);
}

PImage getNoise(int width,int height){
  PImage out = createImage(width,height,RGB);

  for(int i = 0 ; i < out.pixels.length; i++) 
    out.pixels[i] = color(random(255),random(255),random(255));

  out.updatePixels();

  return out;
}

PImage difference(PImage satin)
{
  colorMode(HSB);

  satin.loadPixels();
  imageKey.loadPixels();

  PImage satout = createImage(satin.width, satin.height, RGB);

  satout.loadPixels();
  for (int i = imageWidth; i<satout.pixels.length-imageWidth; i++)
  {
    float x1 = brightness(imageKey.pixels[i]);
    float b0 = brightness(satin.pixels[i]);
    // float y1 = brightness(satin.pixels[i+1]);

    float value = x1-b0;
    //println(i,x1,b0,x1-b0,value);

    satout.pixels[i] = color(0, 0, value);
  }
  satout.updatePixels();

  return satout;
}

我无法测试您的实际设置,因为我无法访问您的图像,但 ArrayIndexOutOfBoundsException 可能是因为您的 i 计数器超出了 imageKey 中的像素数。您可以通过检查 i < imageKey.pixels.length 来测试这一点。我的猜测是图像尺寸不同,因此像素数不同。

其他略有进展的笔记off-topic:

  1. 您的 difference() 函数与 imageKeyimageWidth 变量紧密耦合。您可能希望使您的函数松散耦合,以便它们可以在其他上下文中轻松重用。您可以首先使这两个变量成为函数
  2. 的额外 parameters/arguments
  3. 您可能还想查看颜色之间的欧氏距离(在感知颜色 space 中,例如 Lab*)。看看 this answer。即使它是一个 OpenFrameworks 答案,它应该很容易适应 Processing 的 colorPVector 类型。