detection of 2D lines in gradient images using extension of Hough algorithm based on gradient orientation
This algorithm detects 2D lines in an input image using an extension of Hough algorithm based on gradient orientation. Differences with the implementation of regular Hough detector HoughLines2d are:
the algorithm takes as inputs 2 images, corresponding to the images of gradients, respectively along x-axis and y-axis. From these 2 images, the image of gradient magnitude is computed. It will be used to compute the accumulation matrix, but instead of accumulating intensity of each pixel on the whole range of possible line orientations of the
parameter space , the range is restricted to
, with:
a tolerance specified by the user (equals to
radians (10°) by default)
the gradient orientation at current pixel, in radians, computed from the 2 input images of gradient.
Indeed, if the pixel is on a line, gradient orientation should be close to the orientation of the normal to the line. Thus, the accumulator matrix is not polluted with accumulation of intensities that are not relevant
- using the gradient orientation, the total range of orientations can be extended to
(instead of
for HoughLines2d algorithm). Considering a straight-lined edge separating the space in 2 distinct half-spaces
and
, this extension enables to clearly distinguish the case where
is bright and
is dark from the case where
is dark and
is bright, what regular Hough transform cannot. We can deduce potential advantages of this property on 2 different examples:
- let's assume that we want to find only transitions from left black to right white in the image of stripes displayed below. It would not be easy with regular Hough lines detector, because all borders would have the same orientation (they would correspond to points aligned on the same row in the accumulator matrix). With the current algorithm, on the contrary, black/white transitions and white/black transitions respectively correspond to points aligned on 2 different rows of the accumulator matrix. To filter lines we are not interested in, we just have to restrict the range of orientations to [0, 10°], for instance
- let's consider the image displayed below (original image on the left, zoomed image on the right):
In this image, we would like to detect lines corresponding to the 2 borders of the thin straight-lined object. With the regular Hough algorithm applied on image of gradient magnitude, the problem is that, depending on the resolution chosen for
and
, the 2 expected peaks may be merged into a single one, as shown in the following accumulator matrix obtained with RhoStep=1 pixel and ThetaStep=1° (which are the default parameters) :
It results in one single line detected instead of the two expected. With the extended Hough algorithm, the two peaks are very distant one from each other, and there is no risk to observe this issue. The 2 borders of the thin stripes are correctly detected:
- See also
- https://www.fer.unizg.hr/_download/repository/0012-0007.pdf
Example of Python code :
Example imports
import PyIPSDK
import PyIPSDK.IPSDKIPLFeatureDetection as fd
import PyIPSDK.IPSDKIPLFiltering as filter
Code Example
inImg = PyIPSDK.loadTiffImageFile(inputImgPath)
gxImg, gyImg = filter.gaussianGradient2dImg(inImg, 1.0)
rhoStep = 2.0
thetaRange = PyIPSDK.createEvenlySpacedRange(math.pi/2, 3*math.pi/4, 15)
intensityThreshold = 70.0
orientationTolerance = math.pi / 18
imgParams = PyIPSDK.createHoughLinesGradientImgParams(
rhoStep, thetaRange, intensityThreshold)
extractionParams = PyIPSDK.createDefaultHoughLinesExtractionParams()
outLines, outImg = fd.houghLinesGradient2d(
gxImg, gyImg, imgParams, extractionParams, orientationTolerance)
Example of C++ code :
Example informations
Header file
#include <IPSDKIPL/IPSDKIPLFeatureDetection/Processor/HoughLinesGradient2d/HoughLinesGradient2d.h>
Code Example
GradientXYImg xyImg = sobelGradient2dImg(pInImg);
const ipReal64 rhoStep = 1.0;
M_PI / 2, 3 * M_PI / 4, 15);
const ipReal32 intensityThreshold = 10.0f;
const ipReal64 accumThresholdValue = 0.5f;
const ipUInt32 localMaxSearchWindowRadius = 10;
accumThresholdType, accumThresholdValue, localMaxSearchWindowRadius);
const ipReal32 orientationTolerance = static_cast<ipReal32>(M_PI / 18);
HoughLinesResult res = houghLinesGradient2d(
xyImg._pXGradImg,
xyImg._pYGradImg,
pInImgPrms,
pInExtractPrms,
orientationTolerance);
const ImagePtr pAccumulationMatrix = res._pOutImg;