【发布时间】:2017-07-11 04:55:06
【问题描述】:
我正在尝试编写最简单的图像比较函数。 这个想法是有一个目标图像和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);
}}
【问题讨论】:
-
由于您想比较图像,您可以使用称为相关的技术。相关范围在 0 - 1 之间。只要被比较的图像彼此接近,则相关因子将接近 1,否则。
-
只搜索获胜者,即距离最小的图像,无需排序。它不再简洁了。
-
@Trilarion 我很好地理解了这个概念,我只是无法获得 PImage 或 float 函数来输出获胜者图像。有什么帮助吗?
-
@MercedesLanda 根据可用于此任务的时间,您可能还需要考虑比较两个图像之间的平均结构相似性指数。应该可以使用OpenCV PSNR/SSIM example 中的
getMSSIM函数。示例代码是 c++,您不需要 GPU 部分,但您可以使用 OpenCV Processing library 将您的PImages转换为 OpenCV 的Mat格式,计算 SSIM 然后将结果转换回来
标签: image-processing processing image-recognition