2

I'm working on a school project for the graphics class. My task is detecting edges on a colored image, we received the suggestion to use the Canny edge detection algorithm.

I've decided to write the entire program by myself in Java, because it looks easy with the given formulas. I've created a window with Java Swing, I'm reading in the input image as an sRGB image, converting it to CIELab* (because thats part of the task). I have managed to apply the Sobel kernels (Cx,Cy) which determines the partial derivative. However I'm stuck with the direction formula, and coding it.

My first problem is, I don't know if I should calculate the directions in every separate color channel, or do it in one piece.

Here are the formulas for the calculations (first is the direction, I'm stuck with, and on the right size there is the magnitude which requires the direction -theta)

pic

Here is the source code for calculating the direction:

//Returns the gradients direction from Cx,Cy
public LabImg direction(LabImg Cx, LabImg Cy) {
    LabImg result = new LabImg(Cx.getWidth(),Cx.getHeight());
    for(int x = 0; x < result.getWidth(); x++) {
        for(int y = 0; y < result.getHeight(); y++) {
            float CxL = Cx.getPixel(x, y).getL();
            float Cxa = Cx.getPixel(x, y).getA();
            float Cxb = Cx.getPixel(x, y).getB();

            float CyL = Cy.getPixel(x, y).getL();
            float Cya = Cy.getPixel(x, y).getA();
            float Cyb = Cy.getPixel(x, y).getB();

            float dirL = (float) ((2*CxL*CyL)/((CxL*CxL)-(CyL*CyL)));
            float dira = (float) ((2*Cxa*Cya)/((Cxa*Cxa)-(Cya*Cya)));
            float dirb = (float) ((2*Cxb*Cyb)/((Cxb*Cxb)-(Cyb*Cyb)));

            //float dir = (2*CxL*CyL+Cxa*Cya+Cxb*Cyb)/((CxL*CxL+Cxa*Cxa+Cxb*Cxb)-(CyL*CyL+Cya*Cya+Cyb*Cyb));

            result.setLab(x, y, dirL, dira, dirb);
        }
    }
    return result;
}

LabImg is a data type, which contains the size of the image, a 2D array of pixel values, and a buffered image.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • I don't know where you got those equations, but they're rubbish.You have the two partial derivatives. These form the gradient vector. The magnitude of this vector and its orientation are easy to compute using `hypot` and `atan2`. – Cris Luengo Apr 24 '18 at 15:18
  • I've got this from our teacher. That was the only help he sent. this is from the ieee signal processing magazine (january 2005) -page 66. He said i need to use those equations as well, but it did'nt work for me... I will try it with the suggested ones now. Thx for the help! – thepalacsinta007 Apr 24 '18 at 15:57

1 Answers1

2

If you want to do color edge detection, then you will need to process each color channel separately. So, you will have to find gradient directions for the three color channels separately.

Secondly, you can compute magnitude and directions as:

magnitude = Math.sqrt(Xgrad*Xgrad + Ygrad*Ygrad)
theta = Math.atan2(Ygrad,Xgrad)
user8190410
  • 1,264
  • 2
  • 8
  • 15
  • 1
    Sobel computes the first derivatives. Roberts's operator is worse than Sobel's in terms of noise sensitivity and rotation invariance. But your code for magnitude and orientation is correct. For the magnitude I'd recommend to use `Math.hypot`, which avoids underflow and overflow. – Cris Luengo Apr 24 '18 at 15:15
  • Thanks for the answer. So can i use those equations, if i used the sobel kernels for Cx and Cy? – thepalacsinta007 Apr 24 '18 at 17:18
  • yes, you can use these equation. For reference, https://en.wikipedia.org/wiki/Sobel_operator – user8190410 Apr 24 '18 at 17:25
  • And where do i use the theta, for the magnitude, those things are not clear for me, cause in the linked picture(magnitude), there is an input for the theta. – thepalacsinta007 Apr 24 '18 at 17:33
  • there is no use of theta in computing magnitude – user8190410 Apr 24 '18 at 17:35
  • So, the equations i've got was all wrong? Wow, thanks for the answers! – thepalacsinta007 Apr 24 '18 at 17:51