Простое распознавание изображений в processing.org

Я пытаюсь написать простейшую функцию сравнения изображений. Идея состоит в том, чтобы иметь целевое изображение и набор из n различных изображений.

Цель состоит в том, чтобы выбрать изображение, которое наиболее похоже на целевое изображение.

Пока что мой метод состоит в определении евклидова расстояния HSB от пикселя к пикселю в измененном изображении, и я пытаюсь сделать PImage функция, которая возвращает изображение победителя. Я уже написала 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);
}}

1 ответ

Решение

Похоже, ваша функция работает:

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 вероятно, потому что ваш счетчик я выходит за рамки количества пикселей в imageKey, Вы можете проверить это, поставив проверку, если i < imageKey.pixels.length, Я предполагаю, что изображения не имеют одинаковые размеры и, следовательно, не имеют одинаковое количество пикселей.

Другие заметки, которые идут немного не по теме:

  1. Ваш difference() функция тесно связана с imageKey а также imageWidth переменные. Возможно, вы захотите сделать свои функции слабо связанными, чтобы их можно было легко использовать в других контекстах. Вы можете начать с этих двух переменных, добавив дополнительные параметры / аргументы функции
  2. Вы также можете посмотреть на евклидово расстояние между цветами (в воспринимаемом цветовом пространстве, таком как La b *). Посмотрите на этот ответ. Даже если это ответ OpenFrameworks, его легко адаптировать к обработке color а также PVector типы.
Другие вопросы по тегам