# 5. 图像形态学
> 图像形态学是指使用滤波等方式,使图片更模糊化,将一些噪声滤掉,以便于算法后期降低图像处理复杂程度。形态学掌握的知识要求有腐蚀膨胀、开闭运算和几种滤波方式。
## 1. 滤波
图像滤波增强处理实质上就是运用滤波技术来增强图像的某些空间频率特征,以改善地物目标与领域或背景之间的灰度反差。遥感系统成像过程中可能产生的”模糊”作用,常使遥感图像上某些用户感兴趣的线性形迹、纹理与地物边界等信息显示得不够清晰,不易识别。需要通过采用领域处理方法来分析、比较和调整像元与其周围相邻像元间的对比度关系,图像才能得到增加,也就是说需要采用滤波增加技术处理。
| 滤波方法 | 滤波公式(卷积核) | 滤波类型 |
| ------------------------- | ------------------------------------------------------------ | ---------- |
| 盒式滤波boxFilter() | `$ \begin{matrix}\texttt{K} = \alpha \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \cdots \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix} \\ \alpha = \begin{cases} \frac{1}{\texttt{ksize.width*ksize.height}} & \texttt{when } \texttt{normalize=true} \\1 & \texttt{otherwise}\end{cases}\end{matrix} $` | 线性滤波 |
| 均值滤波blur() | `$ \texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \cdots \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix} $` | 线性滤波 |
| 高斯滤波GaussianBlur() | 高斯滤波有生成卷积核的函数,下文详述 | 线性滤波 |
| 中值滤波medianBlur() | `$ \texttt{ksize×ksize} $` | 非线性滤波 |
| 双边滤波bilateralFilter() | 双边滤波并不是采用卷积核,而是采用特殊的方式 | 非线性滤波 |
### 常用函数
#### 盒式滤波
```C++
void cv::boxFilter ( InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT
)
/**
@brief Blurs an image using the box filter.
简介 使用长方体过滤器使图像模糊。
Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives (used in dense optical flow algorithms, and so on). If you need to compute pixel sums over variable-size windows, use #integral.
非正规化盒滤波器用于计算每个像素邻域上的各种积分特性,例如图像导数的协方差矩阵(用于密集光流算法等)。如果需要计算可变大小窗口上的像素和,请使用#积分。
@param src input image.
@param dst output image of the same size and type as src.
@param ddepth the output image depth (-1 to use src.depth()).
@param ksize blurring kernel size.
@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel center.
@param normalize flag, specifying whether the kernel is normalized by its area or not.
@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes. #BORDER_WRAP is not supported.
@sa blur, bilateralFilter, GaussianBlur, medianBlur, integral
*/
```
#### 均值滤波
```C++
void cv::blur ( InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
/**
@brief Blurs an image using the normalized box filter.
简介 使用规格化长方体过滤器模糊图像。
@param src input image; it can have any number of channels, which are processed independently, but
the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param ksize blurring kernel size.
@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel center.
@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes. #BORDER_WRAP is not supported.
@sa boxFilter, bilateralFilter, GaussianBlur, medianBlur
*/
```
The call `blur(src, dst, ksize, anchor, borderType)` is equivalent to `boxFilter(src, dst, src.type(), ksize, anchor, true, borderType)`.
#### 中值滤波
```C++
void cv::medianBlur ( InputArray src,
OutputArray dst,
int ksize
)
/**
@brief Blurs an image using the median filter.
简介 使用中值滤波器使图像模糊。
The function smoothes an image using the median filter with the ksize*ksize aperture. Each channel of a multi-channel image is processed independently. In-place operation is supported.
该函数使用带有ksize*ksize光圈的中值滤波器平滑图像。多通道图像的每个通道都是独立处理的。支持就地操作。
@note The median filter uses #BORDER_REPLICATE internally to cope with border pixels, see #BorderTypes
注意中值滤波器使用“边界”内部复制来处理边界像素,请参见“边界类型”
@param src input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be
CV_8U, CV_16U, or CV_32F, for larger aperture sizes, it can only be CV_8U.
@param dst destination array of the same size and type as src.
@param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ...
@sa bilateralFilter, blur, boxFilter, GaussianBlur
*/
```
#### 高斯滤波
```C++
void cv::GaussianBlur ( InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
/**
@brief Blurs an image using a Gaussian filter.
简介 使用高斯滤波器使图像模糊。
The function convolves the source image with the specified Gaussian kernel. In-place filtering is supported.
该函数使用指定的高斯核卷积源图像。支持就地筛选。
@param src input image; the image can have any number of channels, which are processed independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive and odd. Or, they can be zero's and then they are computed from sigma.
@param sigmaX Gaussian kernel standard deviation in X direction.
@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height, respectively (see #getGaussianKernel for details); to fully control the result regardless of possible future modifications of all this semantics, it is recommended to specify all of ksize, sigmaX, and sigmaY.
@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported.
@sa sepFilter2D, filter2D, blur, boxFilter, bilateralFilter, medianBlur
*/
```
```C++
Mat cv::getGaussianKernel ( int ksize,
double sigma,
int ktype = CV_64F
)
/**
@brief Returns Gaussian filter coefficients.
简介 返回高斯滤波器系数。
The function computes and returns the ksize*1 matrix of Gaussian filter coefficients:
该函数计算并返回高斯滤波器系数的ksize*1矩阵:
Two of such generated kernels can be passed to sepFilter2D. Those functions automatically recognize smoothing kernels (a symmetrical kernel with sum of weights equal to 1) and handle them accordingly. You may also use the higher-level GaussianBlur.
其中两个生成的内核可以传递给sepFilter2D。这些函数自动识别平滑核(权重和等于1的对称核)并相应地处理它们。您也可以使用更高级别的高斯模糊。
@param ksize Aperture size. It should be odd ( $\texttt{ksize} \mod 2 = 1\f$ ) and positive.
@param sigma Gaussian standard deviation. If it is non-positive, it is computed from ksize as `sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8`.
@param ktype Type of filter coefficients. It can be CV_32F or CV_64F .
@sa sepFilter2D, getDerivKernels, getStructuringElement, GaussianBlur
*/
```
```[tex]
\begin{matrix}
G_i&=& \alpha *e^{-(i-( \texttt{ksize} -1)/2)^2/(2* \texttt{sigma}^{2})}\\
i&=&0..\texttt{ksize}-1\ \\
\sum_i G_i&=&1
\end{matrix}
```
```[tex]
\texttt{G(x,y)} = \frac{1}{2\pi\sigma}e^{-\frac{\delta x^2+\delta y^2}{2\sigma^2}}
```
#### 双边滤波
```C++
void cv::bilateralFilter ( InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT
)
/**
@brief Applies the bilateral filter to an image.
简介 将双边过滤器应用于图像。
The function applies bilateral filtering to the input image, as described in
该函数对输入图像应用双边滤波,如中所述
http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
bilateralFilter can reduce unwanted noise very well while keeping edges fairly sharp. However, it is very slow compared to most filters.
双边滤波器可以很好地减少不必要的噪音,同时保持边缘相当锐利。但是,与大多数过滤器相比,它的速度非常慢。
_Sigma values_: For simplicity, you can set the 2 sigma values to be the same. If they are small (<10), the filter will not have much effect, whereas if they are large (>150), they will have a very strong effect, making the image look "cartoonish".
_西格玛值_:为了简单起见,您可以将2个西格玛值设置为相同。如果它们很小(<10),过滤器将不会有太大的效果,而如果它们很大(>150),它们将有非常强的效果,使图像看起来“卡通化”。
_Filter size_: Large filters (d>5) are very slow, so it is recommended to use d=5 for real-time applications, and perhaps d=9 for offline applications that need heavy noise filtering.
_过滤器大小:大型过滤器(d>5)速度非常慢,因此建议在实时应用程序中使用d=5,在需要大量噪声过滤的脱机应用程序中使用d=9。
This filter does not work inplace.
这个过滤器在原地不工作。
@param src Source 8-bit or floating-point, 1-channel or 3-channel image.
@param dst Destination image of the same size and type as src .
@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed from sigmaSpace.
@param sigmaColor Filter sigma in the color space. A larger value of the parameter means that farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting in larger areas of semi-equal color.
@param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that farther pixels will influence each other as long as their colors are close enough (see sigmaColor). When d\>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is proportional to sigmaSpace.
@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes
*/
```
## 2. 腐蚀膨胀处理
数学形态学提供了一组有用的方法,能够用来调整分割区域的形状以获得比较理想的结果,它最初是从数学中的集合论发展而来并用于处理二值图的,虽然运算很简单,但是往往可以产生很好的效果,后来这些方法推广到普通的灰度级图像处理中。
按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域)与核进行卷积。
核可以是任何的形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点(anchorpoint)。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,其实,我们可以把核视为模板或者掩码。
不理解的话,[参考链接](https://www.cnblogs.com/sdu20112013/p/11644684.html)
### 常用函数
#### 膨胀
```C++
void cv::dilate ( InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
/**
@brief Dilates an image by using a specific structuring element.
简介 通过使用特定的结构元素来扩展图像。
The function dilates the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the maximum is taken:
该函数使用指定的结构元素对源图像进行放大,该结构元素确定取最大值的像素邻域的形状:
*/
```
```[tex]
\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')
```
```C++
/*
The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In case of multi-channel images, each channel is processed independently.
该功能支持就地模式。膨胀可以应用多次(迭代)。在多通道图像的情况下,每个通道独立处理。
@param src input image; the number of channels can be arbitrary, but the depth should be one of
CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular structuring element is used. Kernel can be created using #getStructuringElement
@param anchor position of the anchor within the element; default value (-1, -1) means that the anchor is at the element center.
@param iterations number of times dilation is applied.
@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not suported.
@param borderValue border value in case of a constant border
@sa erode, morphologyEx, getStructuringElement
*/
```
#### 腐蚀
```C++
void cv::erode ( InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
/**
@brief Erodes an image by using a specific structuring element.
简介 通过使用特定的结构元素来腐蚀图像。
The function erodes the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the minimum is taken:
该函数使用指定的结构元素侵蚀源图像,该结构元素确定像素邻域的形状,在该邻域上取最小值:
*/
```
```[tex]
\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')
```
```C++
/*
The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In case of multi-channel images, each channel is processed independently.
该功能支持就地模式。侵蚀可以应用多次(迭代)。在多通道图像的情况下,每个通道独立处理。
@param src input image; the number of channels can be arbitrary, but the depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular structuring element is used. Kernel can be created using #getStructuringElement.
@param anchor position of the anchor within the element; default value (-1, -1) means that the anchor is at the element center.
@param iterations number of times erosion is applied.
@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported.
@param borderValue border value in case of a constant border
@sa dilate, morphologyEx, getStructuringElement
*/
```
#### 形态学操作函数
```C++
void cv::morphologyEx ( InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
/**
@brief Performs advanced morphological transformations.
简介 执行高级形态转换。
The function cv::morphologyEx can perform advanced morphological transformations using an erosion and dilation as basic operations.
函数cv::morphologyEx可以使用侵蚀和扩张来执行高级形态转换基本操作。
Any of the operations can be done in-place. In case of multi-channel images, each channel is processed independently.
任何操作都可以就地完成。对于多通道图像,每个通道都是独立处理。
@param src Source image. The number of channels can be arbitrary. The depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst Destination image of the same size and type as source image.
@param op Type of a morphological operation, see #MorphTypes 下文有表格
@param kernel Structuring element. It can be created using #getStructuringElement.
@param anchor Anchor position with the kernel. Negative values mean that the anchor is at the kernel center.
@param iterations Number of times erosion and dilation are applied.
@param borderType Pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported.
@param borderValue Border value in case of a constant border. The default value has a special meaning.
@sa dilate, erode, getStructuringElement
@note The number of iterations is the number of times erosion or dilatation operation will be applied. For instance, an opening operation (#MORPH_OPEN) with two iterations is equivalent to apply successively: erode -> erode -> dilate -> dilate (and not erode -> dilate -> erode -> dilate).
迭代次数是应用侵蚀或膨胀操作的次数。例如,具有两次迭代的打开操作(#MORPH_OPEN)相当于依次应用:腐蚀->腐蚀->扩张->扩张(而非腐蚀->扩张->腐蚀->扩张)。
*/
```
enum `MorphTypes`
| MorphTypes | 公式 |
| ------------------ | ------------------------------------------------------------ |
| MORPH_ERODE = 0 | |
| MORPH_DILATE = 1 | |
| MORPH_OPEN = 2 | `$ \texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} )) $` |
| MORPH_CLOSE = 3 | `$ \texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} )) $` |
| MORPH_GRADIENT = 4 | `$ \texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} ) $` |
| MORPH_TOPHAT = 5 | `$ \texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} ) $` |
| MORPH_BLACKHAT = 6 | `$ \texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src} $` |
| MORPH_HITMISS = 7 | Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation |
#### 构建内核函数
```C++
Mat cv::getStructuringElement ( int shape,
Size ksize,
Point anchor = Point(-1,-1)
)
/**
@brief Returns a structuring element of the specified size and shape for morphological operations.
简介 为形态学操作返回指定大小和形状的结构元素。
The function constructs and returns the structuring element that can be further passed to #erode, #dilate or #morphologyEx. But you can also construct an arbitrary binary mask yourself and use it as the structuring element.
函数构造并返回可进一步传递给 #腐蚀 、 #扩张 或 #形态学 的结构元素。但是您也可以自己构造任意的二进制掩码,并将其用作结构元素。
@param shape Element shape that could be one of #MorphShapes
@param ksize Size of the structuring element.
@param anchor Anchor position within the element. The default value (-1, -1) means that the anchor is at the center. Note that only the shape of a cross-shaped element depends on the anchor position. In other cases the anchor just regulates how much the result of the morphological operation is shifted.
*/
```
## 3. 霍夫运算
### 常见函数
#### 霍夫圆
```C++
void cv::HoughCircles ( InputArray image,
OutputArray circles,
int method,
double dp,
double minDist,
double param1 = 100,
double param2 = 100,
int minRadius = 0,
int maxRadius = 0
)
/**
@brief Finds circles in a grayscale image using the Hough transform.
简介 使用Hough变换在灰度图像中查找圆。
*/
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img, gray;
if( argc != 2 || !(img=imread(argv[1], 1)).data)
return -1;
cvtColor(img, gray, COLOR_BGR2GRAY);
// smooth it, otherwise a lot of false circles may be detected
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, HOUGH_GRADIENT, 2, gray.rows/4, 200, 100 );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// draw the circle center
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
waitKey(0);
return 0;
}
/*
@note Usually the function detects the centers of circles well. However, it may fail to find correct radii. You can assist to the function by specifying the radius range ( minRadius and maxRadius ) if you know it. Or, in the case of #HOUGH_GRADIENT method you may set maxRadius to a negative number to return centers only without radius search, and find the correct radius using an additional procedure.
注:该功能通常能很好地检测圆的中心。但是,它可能无法找到正确的半径。如果您知道半径范围(minRadius和maxRadius),可以通过指定半径范围来辅助该函数。或者,在#HOUGH_梯度法的情况下,您可以将maxRadius设置为负数,以仅返回中心,而不进行半径搜索,并使用其他步骤找到正确的半径。
It also helps to smooth image a bit unless it's already soft. For example, GaussianBlur() with 7x7 kernel and 1.5x1.5 sigma or similar blurring may help.
它也有助于平滑图像一点,除非它已经平滑。例如,具有7x7内核和1.5x1.5sigma或类似模糊的GaussianBlur()可能会有所帮助。
@param image 8-bit, single-channel, grayscale input image.
@param circles Output vector of found circles. Each vector is encoded as 3 or 4 element floating-point vector (x, y, radius) or (x, y, radius, votes).
@param method Detection method, see #HoughModes. The available methods are #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT.
@param dp Inverse ratio of the accumulator resolution to the image resolution. For example, if dp=1 , the accumulator has the same resolution as the input image. If dp=2 , the accumulator has half as big width and height. For #HOUGH_GRADIENT_ALT the recommended value is dp=1.5, unless some small very circles need to be detected.
@param minDist Minimum distance between the centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed.
@param param1 First method-specific parameter. In case of #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT, it is the higher threshold of the two passed to the Canny edge detector (the lower one is twice smaller). Note that #HOUGH_GRADIENT_ALT uses #Scharr algorithm to compute image derivatives, so the threshold value shough normally be higher, such as 300 or normally exposed and contrasty images.
@param param2 Second method-specific parameter. In case of #HOUGH_GRADIENT, it is the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first. In the case of #HOUGH_GRADIENT_ALT algorithm, this is the circle "perfectness" measure. The closer it to 1, the better shaped circles algorithm selects. In most cases 0.9 should be fine. If you want get better detection of small circles, you may decrease it to 0.85, 0.8 or even less. But then also try to limit the search range [minRadius, maxRadius] to avoid many false circles.
@param minRadius Minimum circle radius.
@param maxRadius Maximum circle radius. If <= 0, uses the maximum image dimension. If < 0, #HOUGH_GRADIENT returns centers without finding the radius. #HOUGH_GRADIENT_ALT always computes circle radiuses.
@sa fitEllipse, minEnclosingCircle
*/
```
#### 霍夫线
```C++
void cv::HoughLines ( InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double srn = 0,
double stn = 0,
double min_theta = 0,
double max_theta = CV_PI
)
/**
@brief Finds lines in a binary image using the standard Hough transform.
使用标准Hough变换查找二值图像中的线条。
The function implements the standard or standard multi-scale Hough transform algorithm for line detection. See <http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm> for a good explanation of Hough transform.
该函数实现用于直线检测的标准或标准多尺度Hough变换算法。看...为了更好地解释霍夫变换。
@param image 8-bit, single-channel binary source image. The image may be modified by the function.
@param lines Output vector of lines. Each line is represented by a 2 or 3 element vector(rho, theta) or (rho, theta, votes) . rho is the distance from the coordinate origin (0,0) (top-left corner of the image). theta is the line rotation angle in radians (0 ~ vertical line, pi/2 ~ horizontal line). votes is the value of accumulator.
@param rho Distance resolution of the accumulator in pixels.
@param theta Angle resolution of the accumulator in radians.
@param threshold Accumulator threshold parameter. Only those lines are returned that get enough votes > threshold.
@param srn For the multi-scale Hough transform, it is a divisor for the distance resolution rho . The coarse accumulator distance resolution is rho and the accurate accumulator resolution is rho/srn . If both srn=0 and stn=0 , the classical Hough transform is used. Otherwise, both these parameters should be positive.
@param stn For the multi-scale Hough transform, it is a divisor for the distance resolution theta.
@param min_theta For standard and multi-scale Hough transform, minimum angle to check for lines. Must fall between 0 and max_theta.
@param max_theta For standard and multi-scale Hough transform, maximum angle to check for lines. Must fall between min_theta and CV_PI.
*/
```