---
title: "GradientOrientationFilter"
language: "en"
type: "Symbol"
summary: "GradientOrientationFilter[data, r] gives the local orientation parallel to the gradient of data, computed using discrete derivatives of a Gaussian of pixel radius r, returning values between -\\[Pi]/2 and \\[Pi]/2. GradientOrientationFilter[data, {r, \\[Sigma]}] uses a Gaussian with standard deviation \\[Sigma]."
keywords: 
- local filtering
- orientation
- orientation filtering
- gradient orientation
- edge detection
- canny
- shen
- castan
- sobel
- nonmax
- non maxiumum
- non-max
- non-maximum
- suppression
- DiZenzo
- Zenzo
canonical_url: "https://reference.wolfram.com/language/ref/GradientOrientationFilter.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Image Filtering & Neighborhood Processing"
    link: "https://reference.wolfram.com/language/guide/ImageFilteringAndNeighborhoodProcessing.en.md"
related_functions: 
  - 
    title: "GradientFilter"
    link: "https://reference.wolfram.com/language/ref/GradientFilter.en.md"
  - 
    title: "EdgeDetect"
    link: "https://reference.wolfram.com/language/ref/EdgeDetect.en.md"
  - 
    title: "ArcTan"
    link: "https://reference.wolfram.com/language/ref/ArcTan.en.md"
  - 
    title: "Arg"
    link: "https://reference.wolfram.com/language/ref/Arg.en.md"
  - 
    title: "ImageAdjust"
    link: "https://reference.wolfram.com/language/ref/ImageAdjust.en.md"
---
# GradientOrientationFilter

GradientOrientationFilter[data, r] gives the local orientation parallel to the gradient of data, computed using discrete derivatives of a Gaussian of pixel radius r, returning values between $-\pi /2$ and $\pi /2$.

GradientOrientationFilter[data, {r, σ}] uses a Gaussian with standard deviation σ.

## Details and Options

* ``GradientOrientationFilter`` is used to obtain the orientation of rapid-intensity change for applications such as texture and fingerprint analysis, as well as object detection and recognition.

[image]

* The ``data`` can be any of the following:

|       |                                   |
| ----- | --------------------------------- |
| list  | arbitrary-rank numerical array    |
| image | arbitrary Image or Image3D object |

* ``GradientOrientationFilter[data, r]`` uses standard deviation $\sigma =r/2$.

* ``GradientOrientationFilter[data, …]`` returns the orientation as hyperspherical polar coordinate angles. For data arrays of dimensions $n_1\times n_2\times \ldots \times n_k$, for $k>1$, the resulting array will be of dimensions $n_1\times n_2\times \ldots \times n_k\times (k-1)$. The $k-1$ tuples in the resulting array denote the $(k-1)$-spherical angles.

* By default, defined angles are returned in the interval $\left.\left(-\frac{\pi }{2},\frac{\pi }{2}\right.\right]$ and the value $-\frac{\pi }{2}$ is used for undefined orientation angles.

* For a single channel image and for data, the gradient $g$ at a pixel position is approximated using discrete derivatives of Gaussians in each dimension.

* For multichannel images, define the Jacobian matrix $J$ to be $\left(
\begin{array}{c}
 g_1 \\
 g_2 \\
 \vdots  \\
\end{array}
\right)$, where $g_i$ is the gradient for channel $i$. The orientation is based on the direction of the eigenvector of $J ^TJ$ that has the largest magnitude eigenvalue. This is the direction that maximizes the variation of pixel values.

* For ``data`` arrays with $n$ dimensions, a coordinate system that corresponds to ``Part`` indices is assumed such that a coordinate ``{x1, …, xn}`` corresponds to ``data[[x1, …, xn]]``. For images, the filter is effectively applied to ``ImageData[image]``.

* In 1D, the orientation for nonzero gradients is always ``{0}``, and undefined otherwise.

* In 2D, the orientation is the angle $\phi$ such that $\{\cos (\phi ),\sin (\phi )\}$ is a unit vector parallel to $g$.

* In 3D, the orientation is represented by the angles $\left\{\phi _1,\phi _2\right\}$ such that $\left\{\cos \left(\phi _1\right),\sin \left(\phi _1\right) \cos \left(\phi _2\right),\sin \left(\phi _1\right) \sin \left(\phi _2\right)\right\}$ is a unit vector parallel to the computed gradient.

[image]

* For $n$-dimensional data with $n>1$, the orientation is given by angles $\left\{\phi _1,\phi _2,\text{...},\phi _{n-1}\right\}$ such that $\left\{\cos \left(\phi _1\right),\sin \left(\phi _1\right) \cos \left(\phi _2\right),\sin \left(\phi _1\right) \sin \left(\phi _2\right) \cos \left(\phi
_3\right),\text{...}, \sin \left(\phi _1\right) \sin \left(\phi _2\right) \text{...}\sin \left(\phi _{n-1}\right)\right\}$ is a unit vector in the direction of the computed gradient.

* ``GradientOrientationFilter[image, …]`` always returns a single-channel image for 2D images and a two-channel image for 3D images. The result is of the same dimensions as ``image``.

* The following options can be specified:

|                   |           |                      |
| ----------------- | --------- | -------------------- |
| Method            | Automatic | convolution kernel   |
| Padding           | "Fixed"   | padding method       |
| WorkingPrecision  | Automatic | the precision to use |

* The following suboptions can be given to ``Method`` :

|                             |             |                                            |
| --------------------------- | ----------- | ------------------------------------------ |
| "DerivativeKernel"          | "Bessel"    | convolution kernel                         |
| "UndefinedOrientationValue" | $$-\pi /2$$ | return value when orientation is undefined |

* Possible settings for ``"DerivativeKernel"`` include:

|                       |                                                                        |
| --------------------- | ---------------------------------------------------------------------- |
| "Bessel"              | standardized Bessel derivative kernel, used for Canny edge detection   |
| "Gaussian"            | standardized Gaussian derivative kernel, used for Canny edge detection |
| "ShenCastan"          | first-order derivatives of exponentials                                |
| "Sobel"               | binomial generalizations of the Sobel edge-detection kernels           |
| {kernel1, kernel2, …} | explicit kernels specified for each dimension                          |

* With a setting ``Padding -> None``, ``GradientOrientationFilter[data, …]`` normally gives an array or image smaller than ``data``.

## Examples (26)

### Basic Examples (3)

Gradient orientation of a multichannel image:

```wl
In[1]:= GradientOrientationFilter[[image], 4]//ImageAdjust

Out[1]= [image]
```

---

Gradient orientation of a 3D image:

```wl
In[1]:= GradientOrientationFilter[[image], 2]

Out[1]= [image]
```

---

Gradient orientation filter of a 2D array:

```wl
In[1]:=
GradientOrientationFilter[(⁠|   |   |   |   |   |
| - | - | - | - | - |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 0 | 0 | 1 | 0 | 0 |⁠), 1]//MatrixForm

Out[1]//MatrixForm=
(⁠|               |               |             |               |               |
| ------------- | ------------- | ----------- | ------------- | ------------- |
| (⁠0.785398⁠)  | (⁠0.8953⁠)    | (⁠0.⁠)      | (⁠-0.8953⁠)   | (⁠-0.785398⁠) |
| (⁠0. ... 6⁠) |
| (⁠1.5708⁠)    | (⁠1.5708⁠)    | (⁠-1.5708⁠) | (⁠1.5708⁠)    | (⁠1.5708⁠)    |
| (⁠-0.675496⁠) | (⁠-0.785398⁠) | (⁠0.⁠)      | (⁠0.785398⁠)  | (⁠0.675496⁠)  |
| (⁠-0.785398⁠) | (⁠-0.8953⁠)   | (⁠0.⁠)      | (⁠0.8953⁠)    | (⁠0.785398⁠)  |⁠)
```

### Scope (7)

#### Data (5)

Gradient orientation of a vector:

```wl
In[1]:= GradientOrientationFilter[{1, 1, 0, 1, 0, 1, 1}, 1]

Out[1]= {{-1.5708}, {0}, {-1.5708}, {-1.5708}, {-1.5708}, {0}, {-1.5708}}
```

---

Compute gradient orientation symbolically:

```wl
In[1]:= GradientOrientationFilter[{{a, b}, {a, b}}, 1]//Simplify

Out[1]= {{{ArcTan[0, (a - b) Conjugate[Sign[a - b]]]}, {ArcTan[0, (a - b) Conjugate[Sign[a - b]]]}}, {{ArcTan[0, (a - b) Conjugate[Sign[a - b]]]}, {ArcTan[0, (a - b) Conjugate[Sign[a - b]]]}}}
```

---

Gradient orientation of a binary image:

```wl
In[1]:= GradientOrientationFilter[[image], 1]

Out[1]= [image]
```

---

Gradient orientation of a grayscale image:

```wl
In[1]:= GradientOrientationFilter[[image], 11]

Out[1]= [image]
```

---

Gradient orientation of a diamond-shaped object:

```wl
In[1]:= GradientOrientationFilter[[image], 2]

Out[1]= [image]
```

#### Parameters (2)

Gradient orientation filtering using increasing radii:

```wl
In[1]:= GradientOrientationFilter[[image], #]& /@ {1, 3, 5}

Out[1]= [image]
```

---

Gradient orientation filtering using different standard derivations:

```wl
In[1]:= ImageAdjust@GradientOrientationFilter[[image], {5, #}]& /@ {1, (5/2), 5}

Out[1]= [image]
```

### Options (8)

#### Padding (3)

By default, a ``"Fixed"`` padding is used:

```wl
In[1]:= GradientOrientationFilter[[image], 5]//ImageAdjust

Out[1]= [image]
```

---

Specify a custom padding:

```wl
In[1]:= GradientOrientationFilter[[image], 5, Padding -> "Periodic"]//ImageAdjust

Out[1]= [image]
```

---

``Padding -> None`` normally returns an image smaller than the input image:

```wl
In[1]:= GradientOrientationFilter[[image], {19, 3}, Padding -> None]

Out[1]= [image]
```

#### Method (2)

By default, the ``"Bessel"`` kernel is used to compute the gradient derivatives:

```wl
In[1]:= b = GradientOrientationFilter[[image], 2]

Out[1]= [image]
```

Use the ``"ShenCastan"`` derivative kernel:

```wl
In[2]:= s = GradientOrientationFilter[[image], 2, Method -> "ShenCastan"]

Out[2]= [image]
```

The difference between the two methods:

```wl
In[3]:= b - s

Out[3]= [image]
```

---

Specify the value for undefined orientation:

```wl
In[1]:= GradientOrientationFilter[{1, 1, 0, 1}, 1, Method -> {"UndefinedOrientationValue" -> None}]

Out[1]= {{None}, {0}, {None}, {0}}
```

#### WorkingPrecision (3)

``MachinePrecision`` is by default used with integer arrays:

```wl
In[1]:= GradientOrientationFilter[{1, 1, 0, 1, 0, 1, 1}, 1]

Out[1]= {{-1.5708}, {0}, {-1.5708}, {-1.5708}, {-1.5708}, {0}, {-1.5708}}
```

Perform exact computation instead:

```wl
In[2]:= GradientOrientationFilter[{1, 1, 0, 1, 0, 1, 1}, 1, WorkingPrecision -> ∞]

Out[2]= {{-(π/2)}, {0}, {-(π/2)}, {-(π/2)}, {-(π/2)}, {0}, {-(π/2)}}
```

---

With real arrays, the precision of the input is used by default:

```wl
In[1]:= GradientOrientationFilter[N[{1, 1, 0, 1, 0, 1, 1}, 2], 1]

Out[1]= {{-1.6}, {0}, {-1.6}, {-1.6}, {-1.6}, {0}, {-1.6}}
```

---

``WorkingPrecision`` is ignored when filtering images:

```wl
In[1]:= GradientOrientationFilter[[image], 5, WorkingPrecision -> Infinity]

Out[1]= [image]
```

An image of a real type is always returned:

```wl
In[2]:= ImageType[%]

Out[2]= "Real32"
```

### Applications (5)

Identify the dominant orientations in a noisy image:

```wl
In[1]:=
img = [image];
o = Flatten@ImageData@GradientOrientationFilter[img, 3];
w = Flatten@ImageData@GradientFilter[img, 3];
```

Compute and visualize the histogram distribution of weighted orientations:

```wl
In[2]:=
\[ScriptCapitalA] = WeightedData[o, w];
\[ScriptCapitalD] = HistogramDistribution[\[ScriptCapitalA]];
Plot[PDF[\[ScriptCapitalD], x], {x, -π / 2, π / 2}, Filling -> Axis, PlotRange -> All, Ticks -> {Range[-π / 2, π / 2, π / 4]}]

Out[2]= [image]
```

---

Compute the histogram of oriented gradient (HOG) for an image, where each pixel casts a vote weighted by its gradient magnitude in the bin corresponding to its local orientation:

```wl
In[1]:=
HOG[img_, nbins_] := 
	Module[{mag, ori, mat}, 
	mag = GradientFilter[img, 1];
	ori = GradientOrientationFilter[img, 1, Method -> {"UndefinedOrientationValue" -> 0}];
	mat = ImageCooccurrence[{mag, ImageAdjust[ori]}, 
	nbins, {{1}}];
	BarChart[Total[mat * Range[0, 1 - 1 / nbins, 1 / nbins]], ChartLabels -> Join[{-(π/2)}, Table["", {nbins - 2}], {(π/2)}], Axes -> {True, False}]
	];hog = HOG[[image], 10]

Out[1]= [image]
```

---

Visualize the gradient vectors of an image:

```wl
In[1]:=
img = [image];
dims = ImageDimensions[img];
dirs = ImageData[GradientOrientationFilter[img, 5]];
magnitudes = ImageData[GradientFilter[img, 5]];
orientations = MapThread[#1{-Sin[#2], Cos[#2]}&, {magnitudes, dirs}, 2];
Show[img, ListVectorPlot[MapIndexed[{{#2[[2]], dims[[2]] - #2[[1]]}, #1}&, orientations, {2}], VectorColorFunction -> (Yellow&), VectorScaling -> Automatic]]

Out[1]= [image]
```

---

Express orientations in the standard image coordinate system:

```wl
In[1]:=
i = [image];
orientation = ImageData[GradientOrientationFilter[i, 5]];
orientation = Image@ArcTan[Sin[orientation], -Cos[orientation]];
```

Visualize the orientation of points on the boundary of the glyph:

```wl
In[2]:=
pos = RandomChoice[ImageValuePositions[MorphologicalPerimeter[Binarize[i, {0, .5}]], 1], 25];
Show[i, Graphics[Table[{Orange, Arrowheads[{-.02, .02}], 
	o = ImageValue[orientation, p];
	Arrow[p + # * {Cos[o], Sin[o]}& /@ {-15, 15}]}, {p, pos}]]]

Out[2]= [image]
```

---

Show the orientation of features in a fingerprint:

```wl
In[1]:= i = [image];

In[2]:= r = RidgeFilter[i, 1.5]//ImageAdjust

Out[2]= [image]

In[3]:= c = (o = GradientOrientationFilter[%, 4])//ImageAdjust//Colorize

Out[3]= [image]

In[4]:= ImageCompose[i, {c, .5}]

Out[4]= [image]
```

### Properties & Relations (2)

``GradientOrientationFilter`` is invariant to the size of numbers in the data:

```wl
In[1]:=
GradientOrientationFilter[(⁠|   |   |   |   |   |
| - | - | - | - | - |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 0 | 0 | 1 | 0 | 0 |⁠), 1]//MatrixForm

Out[1]//MatrixForm=
(⁠|               |               |             |               |               |
| ------------- | ------------- | ----------- | ------------- | ------------- |
| (⁠0.785398⁠)  | (⁠0.8953⁠)    | (⁠0.⁠)      | (⁠-0.8953⁠)   | (⁠-0.785398⁠) |
| (⁠0. ... 6⁠) |
| (⁠1.5708⁠)    | (⁠1.5708⁠)    | (⁠-1.5708⁠) | (⁠1.5708⁠)    | (⁠1.5708⁠)    |
| (⁠-0.675496⁠) | (⁠-0.785398⁠) | (⁠0.⁠)      | (⁠0.785398⁠)  | (⁠0.675496⁠)  |
| (⁠-0.785398⁠) | (⁠-0.8953⁠)   | (⁠0.⁠)      | (⁠0.8953⁠)    | (⁠0.785398⁠)  |⁠)

In[2]:=
GradientOrientationFilter[10(⁠|   |   |   |   |   |
| - | - | - | - | - |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 0 | 0 | 1 | 0 | 0 |⁠), 1]//MatrixForm

Out[2]//MatrixForm=
(⁠|               |               |             |               |               |
| ------------- | ------------- | ----------- | ------------- | ------------- |
| (⁠0.785398⁠)  | (⁠0.8953⁠)    | (⁠0.⁠)      | (⁠-0.8953⁠)   | (⁠-0.785398⁠) |
| (⁠0. ... 6⁠) |
| (⁠1.5708⁠)    | (⁠1.5708⁠)    | (⁠-1.5708⁠) | (⁠1.5708⁠)    | (⁠1.5708⁠)    |
| (⁠-0.675496⁠) | (⁠-0.785398⁠) | (⁠0.⁠)      | (⁠0.785398⁠)  | (⁠0.675496⁠)  |
| (⁠-0.785398⁠) | (⁠-0.8953⁠)   | (⁠0.⁠)      | (⁠0.8953⁠)    | (⁠0.785398⁠)  |⁠)
```

---

Gradient orientation filtering of an image gives a grayscale image of a real type:

```wl
In[1]:= GradientOrientationFilter[[image], 3]

Out[1]= [image]

In[2]:= ImageType[%]

Out[2]= "Real"
```

### Possible Issues (1)

Gradient orientation filtering usually returns out-of-range pixel values:

```wl
In[1]:= GradientOrientationFilter[[image], 2]

Out[1]= [image]
```

Adjusting for brightness creates a more visible gradient orientation image:

```wl
In[2]:= ImageAdjust[%]

Out[2]= [image]
```

## See Also

* [`GradientFilter`](https://reference.wolfram.com/language/ref/GradientFilter.en.md)
* [`EdgeDetect`](https://reference.wolfram.com/language/ref/EdgeDetect.en.md)
* [`ArcTan`](https://reference.wolfram.com/language/ref/ArcTan.en.md)
* [`Arg`](https://reference.wolfram.com/language/ref/Arg.en.md)
* [`ImageAdjust`](https://reference.wolfram.com/language/ref/ImageAdjust.en.md)

## Related Guides

* [Image Filtering & Neighborhood Processing](https://reference.wolfram.com/language/guide/ImageFilteringAndNeighborhoodProcessing.en.md)

## History

* [Introduced in 2012 (9.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn90.en.md) \| [Updated in 2014 (10.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn100.en.md) ▪ [2015 (10.1)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn101.en.md)