What are Canny thresolds? - opencv

Is it possible to make Canny to ignore short edges or to ignore low gradient edges? In my case I have card lying on wood and see numerous edges of wood structure after canny
What two thresholds in canny functions are for?

Large intensity gradients are more likely to correspond to edges than
small intensity gradients. It is in most cases impossible to specify a
threshold at which a given intensity gradient switches from
corresponding to an edge into not doing so. Therefore Canny uses
thresholding with hysteresis.
Thresholding with hysteresis requires two thresholds – high and low.
Making the assumption that important edges should be along continuous
curves in the image allows us to follow a faint section of a given
line and to discard a few noisy pixels that do not constitute a line
but have produced large gradients. Therefore we begin by applying a
high threshold. This marks out the edges we can be fairly sure are
genuine. Starting from these, using the directional information
derived earlier, edges can be traced through the image. While tracing
an edge, we apply the lower threshold, allowing us to trace faint
sections of edges as long as we find a starting point.
Once this process is complete we have a binary image where each pixel
is marked as either an edge pixel or a non-edge pixel. From
complementary output from the edge tracing step, the binary edge map
obtained in this way can also be treated as a set of edge curves,
which after further processing can be represented as polygons in the
image domain.
See also:
Thresholds: the use of two thresholds with hysteresis allows more
flexibility than in a single-threshold approach, but general problems
of thresholding approaches still apply. A threshold set too high can
miss important information. On the other hand, a threshold set too low
will falsely identify irrelevant information (such as noise) as
important. It is difficult to give a generic threshold that works well
on all images. No tried and tested approach to this problem yet
exists.
In your case you can probably increase the threshold value a bit to see if it reduces the short lines a bit more.
Source:
https://en.wikipedia.org/wiki/Canny_edge_detector#Tracing_edges_through_the_image_and_hysteresis_thresholding
Update:
For this image I would perhaps pre-process it by applying lower contrast to it. This can help reduce the details in the background of the image a bit before you run it through the blurring and line detector.

Using GaussianBlur() before Canny will help remove much of the unwanted detail. And maybe increase the low threshhold as #Ken suggested

Related

What Kind of pre-processing techniques can I apply to make an object more clear?

I applied few techniques of denoising on MRI images and could not realize what techniques are applicable on my data to make the cartilage object more clear. First I applied Contrast-limited adaptive histogram equalization (CLAHE) with this function:
J = adapthisteq(I)
But I got a white image. This is original image and manual segmentation of two thin objects(cartilage):
And then I read a paper that they had used some preprocessing on microscopy images, such as: Anisotropic diffusion filter(ADF), then, K-SVD algorithm, and then Batch-Orthogonal Matching Pursuit (OMP). I applied the first two and the output is as following:
It seems my object is not clear. It should be brighter than other objects. I do not what kind of algorithms are applicable to make the cartilage objects more clear. I really appreciate any help.
Extended:
This is the object:
Edited (now knowing exactly what you are looking for)
The differences between your cartilage and the surrounding tissue is very slight and for that reason I do not think you can afford to do any filtration. What I mean by this is that the two things that I can kinda catch with my eye is that the edge on the cartilage is very sharp (the grey to black drop-off), and also there seems to be a texture regularity in the cartilage that is smoother than the rest of the image. To be honest, these features are incredibly hard to even pick out by eye, and a common rule of thumb is that if you can't do it with your eye, vision processing is going to be rough.
I still think you want to do histogram stretching to increase your contrast.
1:In order to do a clean global contrast stretch you will need to remove bone/skin edge/ whatever that line on the left is from the image (bright white). To do this, I would suggest looking at the intensity histogram and setting a cut-off after the first peak (make sure to limit this so some value well above what cartilage could be in case there is no white signal). After determining that value, cut all pixels above that intensity from the image.
2:There appears to be low frequency gradients in this image (the background seems to vary in intensity), global histogram management (normalization) doesn't handle this well, CLAHE can handle this if set up well. But a far simpler solution worth trying is just hitting the image with a high pass filter as this will help to remove some of those (low frequency) background shifts. (after this step you should see no bulk intensity variation across the image.
3: I think you should try various implementations of histogram stretching, your goal in your histogram stretch implementation is to make the cartilage look more unique in the image compared to all other tissue.
This is by far the hardest step as you need to actually take a stab at what makes that tissue different from the rest of the tissue. I am at work, but when I get off, I will try to brainstorm some concepts for this final segmentation step here. In the meantime, what you want to try to identify is anything unique about the cartilage tissue at this point. My top ideas are cylindrical style color gradient, surface roughness, edge sharpness, location, size/shape

Are there techniques for calibrating thresholds for Canny edge detection by using feedback from Stroke-Width Transform?

As described in the Stroke-Width Transform (SWT) paper, it uses the output of Canny edge detection as its input. This puts the accuracy of the Canny edge detection in a critical position, because if the accuracy is low (say, too much noise, or missing too much correct edges), SWT will either find too much spurious results or miss some text strokes entirely.
The hysteresis parameters used in Canny edge detection is notoriously difficult to tune when the nature of input image is unconstrained.
Are there any documented approaches of using the partially correct (i.e. partially inaccurate) results of SWT to improve on the parameter selection of the Canny edge detection step, such that the two steps can be iterated to produce successive refinement?
(One of my intended usage is on scanned document images. Unfortunately, I do not have any sample images that I can post publicly. Moreover, being able to handle unconstrained images containing text is a side goal that is still moderately important in the long run.)

Canny Edge vs Thresholding for contour estimation in Open CV

I am using Open CV for an image processing application that involves contour estimation in images. What I would like to know is whether Thresholding the image (like how they have done here) or using Canny Edge Algorithm (here) yields a better result. Does this involve algorithmic analysis or am I missing something?
Canny Edge Detection obviously. It does a whole bunch of things to ensure that only strong edges come out of the result. Thresholding just takes a look at intensities and sees whether or not each value is smaller or larger and we get "edge" points respectively. However, depending on the complexity of the scene, thresholding and edge detection would yield the same thing. For example, if you had a clean image with multiple crisp objects that have a clear intensity difference between the foreground and background, then either edge detection or thresholding would work. If you had a more complex image where the contrast is different in different areas, or if you had multiple objects with different intensities, then thresholding will not give you good results because you would inevitably be including in pixels that don't belong to any proper objects. This is why edge detection is better, as it's a local operator, and thresholding is global. Thresholding applies a set principle to every single pixel in the image. Edge detection decomposes your image into patches and figures out whether something is happening in each of the patches.
If you want to take something out of this, the difference between them both is that thresholding is more used for object extraction, while edge detection is a pre-processing step in a processing pipeline, such as contour estimation, object detection and recognition and feature analysis. Thresholding is a rather quick and dirty way to see whether or not something is happening, or extracting out "active" things while edge detection is more for computer vision related tasks.
Instead of explaining how Canny Edge Detection is better, I'm going to refer you to some literature.
This page from Drexel University was a great thing to get me started: http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/can_tut.html
This page from Computer Vision Online goes into more depth: http://homepages.inf.ed.ac.uk/rbf/HIPR2/canny.htm
Hope this helps!

Water Edge Detection

Is there a robust way to detect the water line, like the edge of a river in this image, in OpenCV?
(source: pequannockriver.org)
This task is challenging because a combination of techniques must be used. Furthermore, for each technique, the numerical parameters may only work correctly for a very narrow range. This means either a human expert must tune them by trial-and-error for each image, or that the technique must be executed many times with many different parameters, in order for the correct result to be selected.
The following outline is highly-specific to this sample image. It might not work with any other images.
One bit of advice: As usual, any multi-step image analysis should always begin with the most reliable step, and then proceed down to the less reliable steps. Whenever possible, the less reliable step should make use of the result of more-reliable steps to augment its own accuracy.
Detection of sky
Convert image to HSV colorspace, and find the cyan located at the upper-half of the image.
Keep this HSV image, becuase it could be handy for the next few steps as well.
Detection of shrubs
Run Canny edge detection on the grayscale version of image, with suitably chosen sigma and thresholds. This will pick up the branches on the shrubs, which would look like a bunch of noise. Meanwhile, the water surface would be relatively smooth.
Grayscale is used in this technique in order to reduce the influence of reflections on the water surface (the green and yellow reflections from the shrubs). There might be other colorspaces (or preprocessing techniques) more capable of removing that reflection.
Detection of water ripples from a lower elevation angle viewpoint
Firstly, mark off any image parts that are already classified as shrubs or sky. Since shrub detection would be more reliable than water detection, shrub detection's result should be used to inform the less-reliable water detection.
Observation
Because of the low elevation angle viewpoint, the water ripples appear horizontally elongated. In fact, every image feature appears stretched horizontally. This is called Anisotropy. We could make use of this tendency to detect them.
Note: I am not experienced in anisotropy detection. Perhaps you can get better ideas from other people.
Idea 1:
Use maximally-stable extremal regions (MSER) as a blob detector.
The Wikipedia introduction appears intimidating, but it is really related to connected-component algorithms. A naive implementation can be done similar to Dijkstra's algorithm.
Idea 2:
Notice that the image features are horizontally stretched, a simpler approach is to just sum up the absolute values of horizontal gradients and compare that to the sum of absolute values of vertical gradients.

Remove high frequency vertical shear noise from image

I have a some scanned images, where the scanner appears to have introduced a certain kind of noise that I've not encountered before. I would like to find a way to remove it automatically. The noise looks like high frequency vertical shear. In other words, a horizontal line that should look like ------------ shows up as /\/\/\/\/\/\/\/\/\, where the amplitude and frequency of the shear seem pretty regular.
Can someone suggest a way of doing the following steps?
Given an image, identify the frequency and amplitude of the shear noise. One can assume that it is always vertical and the characteristic frequency is higher than other frequencies that naturally appear in the image.
Given the above parameters, apply an opposite, vertical, periodic shear to the image to cancel this noise.
It would also be helpful to know how these could be implemented using the tools implemented by a freely available image processing package. (Netpbm, ImageMagick, Gimp, some Python library are some examples.)
Update: Here's a sample from an image with this kind of distortion. Actually, this sample shows that the shear amplitude need not be uniform throughout the image. :-(
The original images are higher resolution (600 dpi).
My solution to the problem would be to convert the image to frequency domain using FFT. The result will be two matrices: the image signal amplitude and the image signal phase. These two matrices should have the same dimensions of the input image.
Now, you should use the amplitude matrix to detect a spike in the area tha corresponds to the noise frequency. Note that the top left of this corner of this matrix should correspond to low frequency components and bottom right to high frequencies.
After you have indentified the spike, you should set the corresponding coefficients (amplitude matrix entries) to zero. After you apply the inverse FFT you should get the input image without the noise.
Please provide an example image for a more concrete (a practical) solution to your problem.
You could use a Hough fit or RANSAC to fit lines first. For Hough to work you may need to "smear" the points using Gaussian blur or morphological dilation so that you get more hits for a given (rho, theta) line in parameter space.
Once you have line fits, you can determine the relative distance of the original points to each line. From that spatial information you can use FFT to find help find a "best fit" spatial frequency and then shift pixels up/down accordingly.
As a first take, you might even skip FFT and use more of a brute force method:
Find the best fit lines using Hough or RANSAC.
Determine the orientation of the lines.
Sampling perpendicular to the (nominally) horizontal lines, find the points along that column with respect to the closest best fit lines.
If the points along one sample are on average a distance +N away from their best fit lines, shift all the pixels in that column (or along that perpendicular sample) by -N.
This sort of technique should work if the shear is consistent along a vertical sample, but not necessarily from left to right. If the shear is always exactly vertical, then finding horizontal lines should be relatively easy.
Judging from your sample image, it looks as though the shear may be consistent across a horizontal line segment between a 3-way or 4-way intersection with a nominally vertical line segment. You could use corner detectors or other methods to find these intersections to limit the extent over which a pixel shifting operation takes place.
A technique I posted here is another way to find horizontal stretches of dark pixels in case they don't fall on a line:
Is there an efficient algorithm for segmentation of handwritten text?
All that aside, is there a chance you could have the scanner fixed?

Resources