For a class I have to implement the sobel edge detector in java, and do I did. But something isnt right, and after 3 hours trying to figure it out I still havent.
public static Color[][] sobelBorder (Color[][] img) {
Color[][] original = ImageUtils.cloneArray(img);
Color[][] tmp = grayscale(original);
int[][] kernel1 = {
{1,0,-1},
{2,0,-2},
{1,0,-1}
};
int[][] kernel2 = {
{1,2,1},
{0,0,0},
{-1,-2,-1}
};
for( int i = 1; i < tmp.length -1; i++) {
for( int j = 1; j < tmp[0].length -1; j++) {
int r1 = 0;
int r2 = 0;
int g1 = 0;
int g2 = 0;
int b1 = 0;
int b2 = 0;
for( int x = 0; x < 3; x++) {
for( int y = 0; y < 3; y++) {
int aR = (tmp[i + (x - 1)][j + (y - 1)].getRed());
int aG = (tmp[i + (x - 1)][j + (y - 1)].getGreen());
int aB = (tmp[i + (x - 1)][j + (y - 1)].getBlue());
r1 = r1 + (aR * kernel1[x][y]);
r2 = r2 + (aR * kernel2[x][y]);
g1 = g1 + (aG * kernel1[x][y]);
g2 = g2 + (aG * kernel2[x][y]);
b1 = b1 + (aB * kernel1[x][y]);
b2 = b2 + (aB * kernel2[x][y]);
}
}
int finalR = (int) Math.sqrt((r1 * r1) + (r2 * r2));
int finalG = (int) Math.sqrt((g1 * g1) + (g2 * g2));
int finalB = (int) Math.sqrt((b1 * b1) + (b2 * b2));
finalR = threshold(finalR, 100);
finalG = threshold(finalG, 100);
finalB = threshold(finalB, 100);
tmp[i][j] = new Color(finalR, finalG, finalB);
}
}
return tmp;
}
The final RBG values are coming way to high, and the result always come mostly white.
What I am doing wrong?
*Edit: Here are the threshold and greyscale funcs:
public static Color[][]grayscale(Color[][] img) {
Color[][] tmp = ImageUtils.cloneArray(img);
for( int i = 0; i < tmp.length; i++)
{
for( int j = 0; j< tmp[i].length;j++) {
Color pixel = tmp[i][j];
int r = pixel.getRed();
int g = pixel.getGreen();
int b = pixel.getBlue();
int grayNum = (r + g + b)/3;
tmp[i][j] = new Color (grayNum, grayNum, grayNum);
}
}
return tmp;
}
public static int threshold (int pixel, int threshold) {
if(pixel > threshold){
return 255;
}else return 0;
}
I don't see any issues. Your threshold may be too low. The largest value to be expected is
sqrt((5 * 255) ^ 2) = 1275
for a single channel. Assuming that we're right at an edge (horizontal or vertical) between intensities 0 and 255, the weights of 1, 2 and 1 when all added together will be(5 * 255)
and so the dynamic range of expected values can be high. 100 is probably too low. You should play around with this threshold and make it higher.