2017-01-11 5 views
1

私は可能な限り単純な画像比較関数を書こうとしています。 アイデアは、ターゲットイメージとn個の異なるイメージのコレクションを持つことです。processing.orgの単純画像認識

目的は、ターゲット画像に最も類似した画像を選択することです。

これまでのところ私の方法は、サイズ変更されたイメージ内でピクセルからピクセルまでのユークリッド距離を定義することから成り、勝者イメージを返す関数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); 
}} 
+0

画像を比較したいので、**相関**という手法を使用できます。相関は0〜1の範囲にあります。比較される画像がお互いに近接している限り、相関係数は1に近くなり、それ以外は相関係数になります。 –

+0

勝者、つまり距離の最も小さい画像を検索するだけで、並べ替える必要はありません。これ以上簡潔にはなりません。 – Trilarion

+0

@Trilarion私はコンセプトをかなりうまく取りますが、PImageまたはfloat関数を使って勝者の画像を出力することはできません。それについての助け? –

答えて

0

あなたの機能は機能しているように見えます:

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; 
} 

私はあなたのイメージへのアクセス権を持っていないように私はあなたの実際のセットアップをテストすることはできませんが、あなたの私のカウンターがimageKeyの画素数を超えているためArrayIndexOutOfBoundsExceptionは、おそらくです。 i < imageKey.pixels.lengthをチェックすることでこれをテストできます。私の推測では、画像は同じ次元ではないため、ピクセル数は同じではありません。ややオフトピックうとしている

その他の注意事項:

  1. あなたdifference()機能がしっかりimageKeyimageWidth変数に結合されています。関数を疎結合にして、他のコンテキストで簡単に再利用できるようにすることもできます。これらの2つの変数を関数の余分なパラメータ/引数とすることから始めることができます。
  2. 色間のユークリッド距離(L b *などの知覚色空間)を調べることもできます。 this answerを見てください.OpenFrameworksの回答ですが、ProcessingのcolorPVectorのタイプに適応するのは簡単です。