Harris Corner Detection
in
Programming Questions
•
9 months ago
Hi I've been doing some investigations into edge detection and corner detection. I am trying to use the Harris/Plessey Operator to grab corners from images, in this code I have used the Sobel operator to get the change dx and dy for each pixel and then applied the Harris operator to get a gaussian distribution of "cornerness". Unfortunately it seems to work well across the x-axis but along the y-axis it is far too sensitive. Doing a bit googling I see that I can use non-maximal suppression to reduce this.
I was wondering if anybody could either have a look at my code and see if they can see anything glaringly wrong with it (other than it's general hackiness) or point me towards somewhere that can tell me about non-maximal suppression in terms for the stupid. :)
Cheers
Richard
My code:
float[][] sobelpixelarray;
float sigma = 0.05;
float[][] sobel() {
float[][] pixelarray = new float[width*height][2];
color px;
float Gx, Gy;
float greyvalue;
float intensity = 0;
float glength = 0;
loadPixels();
// iterate over each pixel in the image
for (int x = 1 ; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
Gx = 0;
Gy = 0;
//top left Pixel
px = pixels[((y-1)*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -intensity;
Gy += intensity;
//middle left pixel
px = pixels[(y*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -2 * intensity;
//bottom left
px = pixels[((y+1)*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -intensity;
Gy += -intensity;
//top middle
px = pixels[((y-1)*width)+x];
greyvalue = color(px);
intensity = greyvalue;
Gy += 2 * intensity;
//bottom middle
px = pixels[((y+1)*width)+x];
greyvalue = color(px);
intensity = greyvalue;
Gy += -2 * intensity;
// top right
px = pixels[((y-1)*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += +intensity;
Gy += +intensity;
//middle right
px = pixels[(y*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += 2 * intensity;
//bottom right
px = pixels[((y+1)*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += +intensity;
Gy += -intensity;
pixelarray[x+(width*y)][0] = Gx;
pixelarray[x+(width*y)][1] = Gy;
//print(" " + x+(width*y));
}
}
return pixelarray;
}
float returnIval(float ix, float x, float y) {
//Gaussian Equation
float weightingValue = -exp(-1*((x*x)+(y*y))/(2*(sigma*sigma)));
weightingValue = ix*ix*weightingValue;
return weightingValue;
}
float returnIXYval(float ix, float iy, float x, float y) {
//Gaussian Equation
float weightingValue = -exp(-1*((x*x)+(y*y))/(2*(sigma*sigma)));
weightingValue = ix*iy*weightingValue;
return weightingValue;
}
void setup() {
size(375,500);
PImage img = loadImage("richard2.jpg");
image(img,0,0);
filter(GRAY);
//get average values for all pixels
sobelpixelarray = sobel();
int[] CornernessPixelArray = new int[width*height];
float Cxy;
for (int x = 1 ; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
float AVal = 0;
float BVal = 0;
float CVal = 0;
//get A value
AVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y-1))][0]);
AVal += returnIval(0,1,sobelpixelarray[x+(width*(y-1))][0]);
AVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y-1))][0]);
AVal += returnIval(1,0,sobelpixelarray[x-1+(width*y)][0]);
AVal += returnIval(0,0,sobelpixelarray[x+(width*y)][0]);
AVal += returnIval(1,0,sobelpixelarray[x+1+(width*y)][0]);
AVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y+1))][0]);
AVal += returnIval(0,1,sobelpixelarray[x+(width*(y+1))][0]);
AVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y+1))][0]);
//get B value
BVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y-1))][1]);
BVal += returnIval(0,1,sobelpixelarray[x+(width*(y-1))][1]);
BVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y-1))][1]);
BVal += returnIval(1,0,sobelpixelarray[x-1+(width*y)][1]);
BVal += returnIval(0,0,sobelpixelarray[x+(width*y)][1]);
BVal += returnIval(1,0,sobelpixelarray[x+1+(width*y)][1]);
BVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y+1))][1]);
BVal += returnIval(0,1,sobelpixelarray[x+(width*(y+1))][1]);
BVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y+1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x-1+(width*(y-1))][0],
sobelpixelarray[x-1+(width*(y-1))][1]);
CVal += returnIXYval(0,1,sobelpixelarray[x+(width*(y-1))][0],
sobelpixelarray[x+(width*(y-1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x+1+(width*(y-1))][0],
sobelpixelarray[x+1+(width*(y-1))][1]);
CVal += returnIXYval(1,0,sobelpixelarray[x-1+(width*y)][0],
sobelpixelarray[x-1+(width*y)][1]);
CVal += returnIXYval(0,0,sobelpixelarray[x+(width*y)][0],
sobelpixelarray[x+(width*y)][1]);
CVal += returnIXYval(1,0,sobelpixelarray[x+1+(width*y)][0],
sobelpixelarray[x+1+(width*y)][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x-1+(width*(y+1))][0],
sobelpixelarray[x-1+(width*(y+1))][1]);
CVal += returnIXYval(0,1,sobelpixelarray[x+(width*(y+1))][0],
sobelpixelarray[x+(width*(y+1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x+1+(width*(y+1))][0],
sobelpixelarray[x+1+(width*(y+1))][1]);
// Same as C(x,y) = det(M) - k(trace(M)^2
Cxy = (AVal*BVal-(CVal*CVal))-(0.14*(AVal+BVal)*(AVal+BVal));
Cxy = Cxy*-255;
//I have been experimenting here on trying to reduce the sensitivity to no avail.
if (Cxy < 0.1) {
if (CornernessPixelArray[x+(width*y)] < CornernessPixelArray[x+1+(width*y)])
CornernessPixelArray[x+(width*y)] = color(255,0,0);
else
CornernessPixelArray[x+(width*y)] = color(255,0,0);
} else
CornernessPixelArray[x+(width*y)] = color(0);
}
}
for(int i = 0; i<width*height;i++) {
if (CornernessPixelArray[i] != color(0))
pixels[i] = CornernessPixelArray[i];
}
//background(0);
updatePixels();
}
I was wondering if anybody could either have a look at my code and see if they can see anything glaringly wrong with it (other than it's general hackiness) or point me towards somewhere that can tell me about non-maximal suppression in terms for the stupid. :)
Cheers
Richard
My code:
float[][] sobelpixelarray;
float sigma = 0.05;
float[][] sobel() {
float[][] pixelarray = new float[width*height][2];
color px;
float Gx, Gy;
float greyvalue;
float intensity = 0;
float glength = 0;
loadPixels();
// iterate over each pixel in the image
for (int x = 1 ; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
Gx = 0;
Gy = 0;
//top left Pixel
px = pixels[((y-1)*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -intensity;
Gy += intensity;
//middle left pixel
px = pixels[(y*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -2 * intensity;
//bottom left
px = pixels[((y+1)*width)+(x-1)];
greyvalue = color(px);
intensity = greyvalue;
Gx += -intensity;
Gy += -intensity;
//top middle
px = pixels[((y-1)*width)+x];
greyvalue = color(px);
intensity = greyvalue;
Gy += 2 * intensity;
//bottom middle
px = pixels[((y+1)*width)+x];
greyvalue = color(px);
intensity = greyvalue;
Gy += -2 * intensity;
// top right
px = pixels[((y-1)*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += +intensity;
Gy += +intensity;
//middle right
px = pixels[(y*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += 2 * intensity;
//bottom right
px = pixels[((y+1)*width)+x+1];
greyvalue = color(px);
intensity = greyvalue;
Gx += +intensity;
Gy += -intensity;
pixelarray[x+(width*y)][0] = Gx;
pixelarray[x+(width*y)][1] = Gy;
//print(" " + x+(width*y));
}
}
return pixelarray;
}
float returnIval(float ix, float x, float y) {
//Gaussian Equation
float weightingValue = -exp(-1*((x*x)+(y*y))/(2*(sigma*sigma)));
weightingValue = ix*ix*weightingValue;
return weightingValue;
}
float returnIXYval(float ix, float iy, float x, float y) {
//Gaussian Equation
float weightingValue = -exp(-1*((x*x)+(y*y))/(2*(sigma*sigma)));
weightingValue = ix*iy*weightingValue;
return weightingValue;
}
void setup() {
size(375,500);
PImage img = loadImage("richard2.jpg");
image(img,0,0);
filter(GRAY);
//get average values for all pixels
sobelpixelarray = sobel();
int[] CornernessPixelArray = new int[width*height];
float Cxy;
for (int x = 1 ; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
float AVal = 0;
float BVal = 0;
float CVal = 0;
//get A value
AVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y-1))][0]);
AVal += returnIval(0,1,sobelpixelarray[x+(width*(y-1))][0]);
AVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y-1))][0]);
AVal += returnIval(1,0,sobelpixelarray[x-1+(width*y)][0]);
AVal += returnIval(0,0,sobelpixelarray[x+(width*y)][0]);
AVal += returnIval(1,0,sobelpixelarray[x+1+(width*y)][0]);
AVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y+1))][0]);
AVal += returnIval(0,1,sobelpixelarray[x+(width*(y+1))][0]);
AVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y+1))][0]);
//get B value
BVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y-1))][1]);
BVal += returnIval(0,1,sobelpixelarray[x+(width*(y-1))][1]);
BVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y-1))][1]);
BVal += returnIval(1,0,sobelpixelarray[x-1+(width*y)][1]);
BVal += returnIval(0,0,sobelpixelarray[x+(width*y)][1]);
BVal += returnIval(1,0,sobelpixelarray[x+1+(width*y)][1]);
BVal += returnIval(1,1,sobelpixelarray[x-1+(width*(y+1))][1]);
BVal += returnIval(0,1,sobelpixelarray[x+(width*(y+1))][1]);
BVal += returnIval(1,1,sobelpixelarray[x+1+(width*(y+1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x-1+(width*(y-1))][0],
sobelpixelarray[x-1+(width*(y-1))][1]);
CVal += returnIXYval(0,1,sobelpixelarray[x+(width*(y-1))][0],
sobelpixelarray[x+(width*(y-1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x+1+(width*(y-1))][0],
sobelpixelarray[x+1+(width*(y-1))][1]);
CVal += returnIXYval(1,0,sobelpixelarray[x-1+(width*y)][0],
sobelpixelarray[x-1+(width*y)][1]);
CVal += returnIXYval(0,0,sobelpixelarray[x+(width*y)][0],
sobelpixelarray[x+(width*y)][1]);
CVal += returnIXYval(1,0,sobelpixelarray[x+1+(width*y)][0],
sobelpixelarray[x+1+(width*y)][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x-1+(width*(y+1))][0],
sobelpixelarray[x-1+(width*(y+1))][1]);
CVal += returnIXYval(0,1,sobelpixelarray[x+(width*(y+1))][0],
sobelpixelarray[x+(width*(y+1))][1]);
CVal += returnIXYval(1,1,sobelpixelarray[x+1+(width*(y+1))][0],
sobelpixelarray[x+1+(width*(y+1))][1]);
// Same as C(x,y) = det(M) - k(trace(M)^2
Cxy = (AVal*BVal-(CVal*CVal))-(0.14*(AVal+BVal)*(AVal+BVal));
Cxy = Cxy*-255;
//I have been experimenting here on trying to reduce the sensitivity to no avail.
if (Cxy < 0.1) {
if (CornernessPixelArray[x+(width*y)] < CornernessPixelArray[x+1+(width*y)])
CornernessPixelArray[x+(width*y)] = color(255,0,0);
else
CornernessPixelArray[x+(width*y)] = color(255,0,0);
} else
CornernessPixelArray[x+(width*y)] = color(0);
}
}
for(int i = 0; i<width*height;i++) {
if (CornernessPixelArray[i] != color(0))
pixels[i] = CornernessPixelArray[i];
}
//background(0);
updatePixels();
}
1