Search code examples
imageimage-processing2dcomputer-visionedge-detection

One dimensional edge detection


Instead of edge detection of a 2D image, I would like to detect edges on every single row (i.g. a line) of an image separately. That is detection of edges from an input 1D vector whose values are pixel intensities ranging from 0 to 255 ( image below): enter image description here

I would like to detect the major edges as appear in the sample input( image below) enter image description here


Solution

  • One way to get to your desired result is to adapt the 2D Canny edge detector as follows (code in Mathematica):

    First, compute the spatial derivative using a Gaussian derivative filter, setting the sigma value relative to the scale of the edges you want to detect. Take the absolute value of the result.

    d = Abs@GaussianFilter[data, {{10, 5}}, 1];
    

    Then, determine a threshold automatically to cluster the previous derivative values in two groups (here using Otsu's method).

    thrd = FindThreshold[d];
    

    Then, detect the steps of the derivative values (transitions into/from the "dead band").

    steps = Flatten@Image`StepDetect[d, thrd]["NonzeroPositions"];
    

    At this point you have the ends of the edges:

    ListLinePlot[data, Epilog -> {Red, PointSize[Large], Map[Point[{#, data[[#]]}] &, steps]}]
    

    enter image description here

    Optionally--it seems that's what you'd like--keep only the lowest ends of the edges. Clustering the data points at the ends of the edges works in this case, but I'm not sure how robust it is.

    t = FindThreshold@data[[steps]];
    steps2 = Select[steps, data[[#]] <= t &];
    
    ListLinePlot[data, Epilog -> {Red, PointSize[Large], Map[Point[{#, data[[#]]}] &, steps2]}]
    

    enter image description here