Overview
- Introduction
- Thresholding
- Segmentation
- Otsu's Method
- Edge Detection
- Canny Edge
- Outlook and Conclusion
4: Primitive Edge-Detection Filters
Similar to Thresholding and Segmentation, Edge-Detection is a commonly used technique in image processing (i.e. to descern boundarys of objects within an image etc.). In your project you will first be implementing a set of primitive edge-detection filters, as well as the more advanced Canny-Edge-Filter (Task 5).
4.1: The Filter-Kernels
There are a variety of different Kernels used for edge detection; some of the most common ones are Sobel, Scharr, and Prewitt - Kernels.

When applying these Filter-Kernels to an image through convolution, you essentially create the derivative of the image. This is because these Kernels result in higher pixel-values in regions, where the image contains a sharp change in brightness (similar to derivatives in analysis). This "derivation" is performed in X- and Y-direction seperately. Using both the X- and Y-derivative of an image, you can then generate the image-gradient by calculating the euclidean norm over both derivatives at each pixel of the image.
$G$ = $\sqrt{G_{x} ^ 2+G_{y} ^ 2}$
This image-gradient will then show the edges as bright and the rest of the image as black.
4.2: Filtering and Gradient
To do:
-
Open the
Task_4_Filters
-class and create a new method:public FloatProcessor applyFilter (FloatProcessor In, int[][] kernel){}
-
Create a new
FloatProcessor
to store the resulting image -
Iterate through the input image and perform the convolution
📝 Note:
Since you are working with a 3x3 kernel, you can't simply iterate through the entire image because you would encounter OutOfBounds-exceptions when getting to the rim of the image. For the sake of simplicity you can therefore ignore the outermost row/column of pixels. -
Return the resulting image
Now that your plugin can perform a convolution (and therefore a derivation), you can calculate the image-gradient.
To do:
-
Create a new method:
public FloatProcessor getGradient (FloatProcessor In_X, FloatProcessor In_Y){}
(In_X and In_Y are the derivatives in X- and Y-direction respectively)
-
Check if the input-images have the same dimensions, if not throw a fitting exception
-
Create a new
FloatProcessor
to store the resulting image -
Iterate through the image and calculate the Gradient value for each pixel in the output-image
-
Return the resulting image-gradient
4.3: User-Dialog
At this point your plugin contains everything needed to perform primitive edge-detection.
As a final step you will implement a simple user-dialog, which will allow the user to select between the three filters mentioned above.
The following code should be implemented in the run
-method
To do:
-
Create a new
GenericDialog
-
Create a
String
-array:String[] Filters = {"Sobel","Scharr","Prewitt"};
-
Add a popup-menu to select which filter you want to use
💡 Tip: Check the ImageJ-API to see how popup-menus are implemented
-
Show the dialog
-
Check if the dialog was cancelled. If it was, terminate the plugin
-
Get the index (in the popup-menu) of the selected filter
-
Perform the edge-detection using the selected filter and the methods you implemented
-
Show your result
4.4: Project-Report
The part of your report concerning Task_4 should contain the following:
- A short description on how these primitive Edge-Detection-Filters work
- Possible limitiations, which would require a more sophisticated approach to edge-detection
- Images you generated with your code