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):
I would like to detect the major edges as appear in the sample input( image below)
Canny Edge Detection This is the most commonly used highly effective and complex compared to many other methods. It is a multi-stage algorithm used to detect/identify a wide range of edges. Reduce noise – as the edge detection that using derivatives is sensitive to noise, we reduce it.
Edge Detection Operators are of two types: Gradient – based operator which computes first-order derivations in a digital image like, Sobel operator, Prewitt operator, Robert operator. Gaussian – based operator which computes second-order derivations in a digital image like, Canny edge detector, Laplacian of Gaussian.
Common edge detection algorithms include Sobel, Canny, Prewitt, Roberts, and fuzzy logic methods. Image segmentation using the Sobel method. Image segmentation using the Canny method. Image segmentation using a Fuzzy Logic method.
Sobel edge detection method cannot produce smooth and thin edge compared to canny method. But same like other method, Sobel and Canny methods also very sensitive to the noise pixels. Sometime all the noisy image can not be filtered perfectly. Unremoved noisy pixels will effect the result of edge detection.
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]}]
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]}]
Given the nice contrast of these edges, there is an easy solution that will work robustly: detect all monotonous sequences of pixel values (strictly increasing or decreasing). You will keep the sequences having a total height above a threshold (50 in your case) to reject the noisy peaks.
As a byproduct, you'll get the starting and ending points (not exactly where you expect them though, but this can be improved on if needed).
Barcodes ?
So you are looking for a particular change in slope - ie a certain change in Y per sample?
Isn't it simply look at the difference in Y between two samples and if it's absolute value changed by more than some limit mark that as an edge?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With