图像轮廓,霍夫变换

  • 图像轮廓
    • 查找轮廓
    • 绘制轮廓
    • 轮廓特征
      • 1.轮廓的矩
      • 2.轮廓面积
      • 3.轮廓的长度
      • 4. 轮廓的近似多边形
      • 5.轮廓的凸包
      • 6.轮廓的直边界矩形
      • 7.轮廓的旋转矩形
      • 8.轮廓的最小外包圆
      • 9.轮廓的拟合椭圆
      • 10.轮廓的拟合直线
      • 11.轮廓的最小外包三角形
  • 霍夫变换
    • 霍夫直线变换
    • 霍夫直线
    • 霍夫圆变换
  • 实验素材

图像轮廓

\qquad图像轮廓是一系列相连的点组成的曲线,代表了物体的基本外形,相对于边缘,轮廓是连续的,边缘并不全部连续。寻找轮廓的操作一般用于二值化图,所以通常会使用阈值分割或Canny边缘检测先得到二值图。

查找轮廓

cv2.findContours()函数用于从二值图像中查找图像轮廓,其基本格式如下:

contours,hierarchy=cv2.findContours(image,mode,method,offset)

其参数说明如下:

参数 说明
contours 为返回的轮廓数组,每个元素都是一个表示轮廓的array对象。
hierarchy 为返回的轮廓的层次结构,是一个numpy.ndarray对象。根据轮廓的嵌套关系,可将轮廓之间的层次关系分为父级和子级,外部的轮廓为父级,内部的轮廓为子级。
image 为原图像。
mode 为轮廓的检索模式,不同检索模式下函数返回的轮廓有所不同。
cv2.RETR_LIST 仅检索所有轮廓,不创建任何父子关系。
cv2.RETR_EXTERNAL 仅检索所有的外部轮廓,不包含子级轮廓。
cv2.RETR_CCOMP 检索所有轮廓并将它们排列为2级层次结构,所有的外部轮廓为1级,所有的子级轮廓为2级。
cv2.RETR_TREE 检索所有轮廓并创建完整的层次列表,如父级、子级、孙子级等。
method 为轮廓的近似方法,决定如何确定轮廓包含的像素点。
cv2.CHAIN_APPROX_NONE 存储所有轮廓点,轮廓的任意两个相邻点是水平、垂直或对角线上的邻居。
cv2.CHAIN_APPROX_SIMPLE 只保存水平、垂直和对角线的端点。
cv2.CHAIN_APPROX_TC89_L1 应用Teh-Chin链逼近算法中的一种确定轮廓点。
offset 为每个轮廓点移动的可选偏移量。
import cv2
import numpy as npimg = cv2.imread('shapes.jpg')        # 读取图像
cv2.imshow('original', img)         # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                        # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)        # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print('轮廓:', c)
print('轮廓类型:', type(c))
print('轮廓个数:', len(c))
print('层次:', h)
print('层次类型:', type(h))
for n in (range(3)):img3 = np.zeros(img.shape, np.uint8)+255           # 按原图大小创建一幅白色图像cv2.polylines(img3, [c[n]], True, (255, 0, 0), 2)    # 绘制轮廓cv2.imshow('%s' % n, img3)                          # 显示轮廓图像
cv2.waitKey(0)                                           # 按任意键结束等待
cv2.destroyAllWindows()                                  # 关闭所有窗口


绘制轮廓

\qquadcv2.drawContours()函数用于绘制轮廓,其基本格式如下:

image=cv2.drawContours(image,contours,contourIdx,color,thickness,lineType,hierarchy,maxLevel,offset)

其参数说明如下:

参数 说明
image 为在其中绘制轮廓的图像。
contours 为要绘制的轮廓。
contourIdx 为要绘制的轮廓的索引,大于或等于0时绘制对应的轮廓,负数(通常为-1)表示绘制所有轮廓。
color 为轮廓颜色,颜色为BGR格式。
thickness 为可选参数,表示绘制轮廓时画笔的粗细。
lineType 为可选参数,表示绘制轮廓时使用的线型。
hierarchy 为可选参数,对应cv2.findContours()函数返回的轮廓层次。
maxLevel 为可选参数,表示可绘制的最大轮廓层次深度。
offset 为可选参数,表示绘制轮廓的偏移位置。
import cv2
import numpy as npimg = cv2.imread('shapes.jpg')        # 读取图像
cv2.imshow('original', img)         # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)   # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img3 = np.zeros(img.shape, np.uint8)+255               # 按原图大小创建一幅白色图像
img3 = cv2.drawContours(img3, c, -1, (0, 0, 255), 2)     # 绘制轮廓
cv2.imshow('Contours', img3)                               # 显示轮廓图像
cv2.waitKey(0)                                           # 按任意键结束等待
cv2.destroyAllWindows()                                  # 关闭所有窗口

轮廓特征

1.轮廓的矩

\qquad轮廓的矩包含了轮廓的各种几何特征,如面积、位置、角度、形状等。cv2.moments()函数用于返回轮廓的矩,其基本格式如下:

ret=cv2.moments(array,binaryImage)

其参数说明如下:

参数 说明
ret 为返回的轮廓矩,是一个字典对象。大多数矩的含义比较抽象,但其中的零阶矩(m00)表示轮廓的面积。
array 为表示轮廓的数组。
binaryImage 值为True时,会将array对象中的所有非0值设置为1
import cv2
import numpy as npimg = cv2.imread('shape2.jpg')        # 读取图像
cv2.imshow('original', img)         # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)   # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img3 = np.zeros(img.shape, np.uint8)+255                     # 按原图大小创建一幅白色图像
img3 = cv2.drawContours(img3, c, -1, (0, 0, 255), 2)           # 绘制轮廓
cv2.imshow('Contours', img3)                                     # 显示轮廓图像
for n in range(len(c)):m = cv2.moments(c[n])print('轮廓%s的矩:' % n, m)                 # 输出轮廓矩print('轮廓%s的面积:' % n, m['m00'])        # 输出轮廓面积
cv2.waitKey(0)                                  # 按任意键结束等待
cv2.destroyAllWindows()                         # 关闭所有窗口


2.轮廓面积

\qquadcv2.contourArea()函数用于返回轮廓面积,其基本格式如下:

ret=cv2.contourArea(contour,oriented)

其参数说明如下:

参数 说明
ret 为返回的面积。
contour 为轮廓。
oriented 为可选参数。其参数值为True时,返回值的正与负表示轮廓是顺时针还是逆时针;参数值为False(默认值)时,函数返回值为绝对值
import cv2
import numpy as npimg = cv2.imread('shape2.jpg')                                # 读取图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                  # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)  # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for n in range(len(c)):m = cv2.contourArea(c[n])               # 计算轮廓面积print('轮廓%s的面积:' % n, m)           # 输出轮廓面积

3.轮廓的长度

\qquadcv2.arcLength()函数用于返回轮廓的长度,其基本格式如下:

ret=cv2.arcLength(contour,closed)

其参数说明如下:

参数 说明
ret 为返回的长度。
contour 为轮廓。
closed 为布尔值,为True时表示轮廓是封闭的。
import cv2
import numpy as npimg = cv2.imread('shape2.jpg')                                # 读取图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                  # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)  # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for n in range(len(c)):m = cv2.arcLength(c[n], True)                  # 计算轮廓长度print('轮廓%s的长度:' % n, m)                  # 输出轮廓长度

4. 轮廓的近似多边形

\qquadcv2.approxPolyDP()函数用于返回轮廓的近似多边形,其基本格式如下:

ret=cv2.approxPolyDP(contour,epsilon,closed)

其参数说明如下:

参数 说明
ret 为返回的近似多边形。
contour 为轮廓。
epsilon 为精度,表示近似多边形接近轮廓的最大距离。
closed 为布尔值,为True时表示轮廓是封闭的。
import cv2
import numpy as npimg = cv2.imread('shape3.jpg')        # 读取图像
cv2.imshow('original', img)         # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                       # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)       # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
ep = [0.1, 0.05, 0.01]
arcl = cv2.arcLength(c[0], True)                        # 计算轮廓长度
print(arcl)
img3 = np.zeros(img.shape, np.uint8)+255              # 按原图大小创建一幅白色图像
img3 = cv2.drawContours(img3, c, -1, (0, 0, 255), 2)    # 绘制轮廓
for n in range(3):eps = ep[n]*arclimg4 = img3.copy()app = cv2.approxPolyDP(c[0], eps, True)                     # 获得近似多边形img4 = cv2.drawContours(img4, [app], -1, (255, 0, 0), 2)    # 绘制近似轮廓cv2.imshow('appro %.2f' % ep[n], img4)                   # 显示轮廓图像
cv2.waitKey(0)                                                  # 按任意键结束等待
cv2.destroyAllWindows()                                         # 关闭所有窗口

5.轮廓的凸包

\qquadcv2.convexHull()函数用于返回轮廓的凸包,其基本格式如下:

hull=cv2.convexHull(contour,clockwise,returnPoints)

其参数说明如下:

参数 说明
hull 为返回的凸包,是一个numpy.ndarray对象,包含了凸包的关键点。
contour 为轮廓。
clockwise 为方向标记,为True时,凸包为顺时针方向;为False(默认值)时,凸包为逆时针方向。
returnPoints 为True(默认值)时,返回的hull中包含的是凸包关键点的坐标;为False时,返回的是凸包关键点在轮廓中的索引。
import cv2
import numpy as npimg = cv2.imread('shape3.jpg')                 # 读取图像
cv2.imshow('original', img)                  # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)           # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255              # 按原图大小创建一幅白色图像
img3 = cv2.drawContours(img3, c, -1, (0, 0, 255), 2)    # 绘制轮廓
hull = cv2.convexHull(c[0])
print('returnPoints=True时返回的凸包:\n', hull)
hull2 = cv2.convexHull(c[0], returnPoints=False)
print('returnPoints=False时返回的凸包:\n', hull2)
cv2.polylines(img3, [hull], True, (255, 0, 0), 2)         # 绘制凸包
cv2.imshow('Convex Hull', img3)                         # 显示轮廓图像
cv2.waitKey(0)                                            # 按任意键结束等待
cv2.destroyAllWindows()                                   # 关闭所有窗口


6.轮廓的直边界矩形

\qquad轮廓的直边界矩形是指可容纳轮廓的矩形,且矩形的两条边必须是水平的。直边界矩形不一定是面积最小的边界矩形。cv2.boundingRect()函数用于返回轮廓的直边界矩形,其基本格式如下:

ret=cv2.boundingRect(contour)

其参数说明如下:

参数 说明
ret 为返回的直边界矩形,它是一个四元组,其格式为(矩形左上角x坐标,矩形左上角y坐标,矩形的宽度,矩形的高度)。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                         # 读取图像
cv2.imshow('original', img)                           # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)               # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)    # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                  # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)               # 绘制轮廓
ret = cv2.boundingRect(c[0])                               # 计算直边矩形
print('直边界矩形:', ret)
pt1 = (ret[0], ret[1])
pt2 = (ret[0]+ret[2], ret[1]+ret[3])
cv2.rectangle(img3, pt1, pt2, (255, 0, 0), 2)           # 绘制直边界矩形
cv2.imshow('Rectangle', img3)                             # 显示结果图像
cv2.waitKey(0)                                          # 按任意键结束等待
cv2.destroyAllWindows()                                 # 关闭所有窗口


7.轮廓的旋转矩形

\qquad轮廓的旋转矩形是指可容纳轮廓的面积最小的矩形。cv2.minAreaRect()函数用于返回轮廓的旋转
矩形,其基本格式如下:

box=cv2.minAreaRect(contour)

其参数说明如下:

参数 说明
box 为返回的旋转矩形,它是一个三元组,其格式为((矩形中心点x坐标,矩形中心点y坐标),(矩形的宽度,矩形的高度),矩形的旋转角度)。
contour 为用于计算矩形的轮廓。

cv2.minAreaRect()函数的返回结果不能直接用于绘制旋转矩形,可用cv2.boxPoints()函数将其转
换为矩形的顶点坐标,其基本格式如下:

points=cv2.boxPoints(box)

其参数说明如下:

参数 说明
points 为返回的矩形顶点坐标,坐标数据为浮点数。
box 为cv2.minAreaRect()函数返回的矩形数据。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                             # 读取图像
cv2.imshow('original', img)                               # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)    # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                  # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)               # 绘制轮廓
ret = cv2.minAreaRect(c[0])                                # 计算最小矩形
rect = cv2.boxPoints(ret)                                  # 计算矩形顶点
rect = np.int0(rect)                                       # 转换为整数
cv2.drawContours(img3, [rect], 0, (255, 0, 0), 2)           # 绘制旋转矩形
cv2.imshow('Rectangle', img3)                                 # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

8.轮廓的最小外包圆

\qquadcv2.minEnclosingCircle()函数用于返回可容纳轮廓的最小外包圆,其基本格式如下:

center,radius=cv2.minEnclosingCircle(contour)

其参数说明如下:

参数 说明
center 为圆心。
radius 为半径。
contour 为用于计算最小外包圆的轮廓。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                             # 读取图像
cv2.imshow('original', img)                               # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)    # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                   # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)                # 绘制轮廓
(x, y), radius = cv2.minEnclosingCircle(c[0])                # 计算最小圆信息
center = (int(x), int(y))
radius = int(radius)
cv2.circle(img3, center, radius, (255, 0, 0), 2)            # 绘制最小圆
cv2.imshow('Circle', img3)                                # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

9.轮廓的拟合椭圆

\qquadcv2.fitEllipse()函数用于返回轮廓的拟合椭圆,其基本格式如下:

ellipse=cv2.fitEllipse(contour)

其参数说明如下:

参数 说明
ellipse 为返回的椭圆。
contour 为用于计算拟合椭圆的轮廓。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                             # 读取图像
cv2.imshow('original', img)                               # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                   # 转化为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)    # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                  # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)               # 绘制轮廓
ellipse = cv2.fitEllipse(c[0])                              # 计算拟合椭圆
cv2.ellipse(img3, ellipse, (255, 0, 0), 2)                  # 绘制拟合椭圆
cv2.imshow('ellipse', img3)                               # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

10.轮廓的拟合直线

\qquadcv2.fitLine()函数用于返回轮廓的拟合直线,其基本格式如下:

line=cv2.fitLine(contour,distType,param,reps,aeps)

其参数说明如下:

参数 说明
line 为返回的拟合直线。
contour 为用于计算拟合直线的轮廓。
distType 为距离类型参数,决定如何计算拟合直线,可设置为下列常量。
cv2.DIST_USER 用户自定义距离。
cv2.DIST_L1 用2个点的坐标计算距离,公式为 l x1-x2l +l y1-y2 l。
cv2.DIST_L2 欧氏距离(两点间的直线距离)。
cv2.DIST_C 用2个点的坐标计算距离,公式为max(lx1-x2l,ly1-y2l)。
cv2.DIST_L12 用1个点的坐标计算距离,公式为2(sqrt(1+x*x/2)-1)。
cv2.DIST_FAIR 用 1 个点的坐标计算距离,公式为c^2(lxl/c-log(1+lxl/c)),c=1.3998。
cv2.DIST_WELSCH 用1个点的坐标计算距离,公式为c2/2(1-exp(-(x/c)2)),c=2.9846。
cv2.DIST_HUBER 用 1 个点的坐标计算距离,公式为lxl<c?x^2/2:c(lxl-c/2),c=1.345。
param 为距离参数,与距离类型参数有关;其设置为0时,函数将自动选择最优值。
reps 为计算拟合直线需要的径向精度,通常设置为0.01。
aeps 为计算拟合直线需要的角度精度,通常设置为0.01。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                                 # 读取图像
cv2.imshow('original', img)                                   # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                       # 将其转换为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)           # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                          # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)                       # 绘制轮廓
rows, cols = img.shape[:2]
[vx, vy, x, y] = cv2.fitLine(c[0], cv2.DIST_L2, 0, 0.01, 0.01)     # 计算拟合直线
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(img3, (cols-1, righty), (0, lefty), (255, 0, 0), 2)        # 绘制拟合直线
cv2.imshow('FitLine', img3)                                       # 显示结果图像
cv2.waitKey(0)                                                      # 按任意键结束等待
cv2.destroyAllWindows()                                             # 关闭所有窗口

11.轮廓的最小外包三角形

\qquadcv2.minEnclosingTriangle()函数用于返回可容纳轮廓的最小外包三角形,其基本格式如下:

retval,triangle=cv2.minEnclosingTriangle(contour)

其参数说明如下:

参数 说明
retval 为最小外包三角形的面积。
triangle 为最小外包三角形。
contour 为用于计算最小外包三角形的轮廓。
import cv2
import numpy as npimg = cv2.imread('shape4.jpg')                                 # 读取图像
cv2.imshow('original', img)                                   # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                       # 将其转换为灰度图像
ret, img2 = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)           # 二值化阈值处理
c, h = cv2.findContours(img2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)   # 计算轮廓
img3 = np.zeros(img.shape, np.uint8)+255                          # 按原图大小创建一幅白色图像
cv2.drawContours(img3, c, -1, (0, 0, 255), 2)                       # 绘制轮廓
retval, triangle = cv2.minEnclosingTriangle(c[0])                  # 计算最小外包三角形
triangle = np.int0(triangle)
cv2.polylines(img3, [triangle], True, (255, 0, 0), 2)               # 绘制最小外包三角形
cv2.imshow('Triangle', img3)                                          # 显示结果图像
cv2.waitKey(0)                                                      # 按任意键结束等待
cv2.destroyAllWindows()                                             # 关闭所有窗口

霍夫变换

\qquad霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。霍夫变换运用两个坐标空间之间的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。
\qquad霍夫变换变换是一种利用表决原理的参数估计技术。其基本原理在于利用图像空间和霍夫变换参数空间的点与线的对偶性,把图像空间中的检测问题转换到参数空间。通过在参数空间里进行简单的累加统计,然后在 Hough 参数空间寻找累加器峰值的方法检测直线。Hough 变换的实质是将图像空间内具有一定关系的像元进行聚类,寻找能把这些像元用某一解析形势联系起来的参数空间累计对应点。在参数空间不超过二维的情况下,这种变换效果理想。将原始图像空间的给定的曲线表达形式变为参数空间的一个点,这样就把原始图像中给定曲线的检测问题转化为寻找参数空间的峰值问题,也就是把检测整体特性转化为检测局部特性,例如直线、椭圆、圆、弧线等。简而言之,Hough变换思想是:在原始图像坐标系下的一个点对应了参数坐标系中的一条直线,同样参数坐标系的一条直线对应了原始坐标系下的一个点,然后,原始坐标系下呈现直线的所有点,它们的斜率和截距是相同的,所以它们在参数坐标系下对应于同一个点。这样在原始坐标系下的各个点的投影到参数坐标系下之后,看参数坐标系下没有聚集点,这样的聚集点就对应了原始坐标系下的直线。

霍夫直线变换

cv2.HoughLines()函数利用霍夫变换算法检测图像中的直线,其基本格式如下:

lines=cv2.HoughLines(image,rho,theta,threshold)

其参数说明如下:

参数 说明
lines 为返回的直线。
image 为原图像,必须是8位的单通道二值图像,通常会在霍夫变换之前,对图像执行阈值处理或Canny边缘检测。
rho 为距离的精度(以像素为单位),通常为1。
theta 为角度的精度,通常使用π/180°,表示搜索所有可能的角度。
threshold 为阈值,值越小,检测出的直线越多。
import cv2
import numpy as npimg = cv2.imread('shape6.jpg')                          # 读取图像
cv2.imshow('original', img)                            # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                # 转化为灰度图像
edges = cv2.Canny(gray, 50, 150, apertureSize=3)         # 执行边缘检测
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)         # 霍夫线变换
img3 = img.copy()
for line in lines:                                       # 逐条绘制直线rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0, y0 = a*rho, b*rhopt1 = (int(x0+1000*(-b)), int(y0+1000 * (a)))           # 计算直线端点pt2 = (int(x0-1000*(-b)), int(y0-1000 * (a)))           # 计算直线端点cv2.line(img3, pt1, pt2, (0, 0, 255), 2)                # 绘制直线
cv2.imshow('HoughLines', img3)                            # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

霍夫直线

cv2.HoughLinesP()函数利用概率霍夫变换算法来检测图像中的直线,其基本格式如下:

lines=cv2.HoughLinesP(image,rho,theta,threshold,minLineLength,maxLineGap)

其参数说明如下:

参数 说明
lines 为返回的直线。
image 为原图像,必须是8位的单通道二值图像,通常会在霍夫变换之前,对图像执行阈值处理或Canny边缘检测。
rho 为距离的精度(以像素为单位),通常为1。
theta 为角度的精度,通常使用π/180°,表示搜索所有可能的角度。
threshold 为阈值,值越小,检测出的直线越多。
minLineLength 为可接受的直线的最小长度,默认值为0。
maxLineGap 为共线线段之间的最大间隔,默认值为0
import cv2
import numpy as npimg = cv2.imread('shape6.jpg')                         # 读取图像
cv2.imshow('original', img)                           # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)               # 转化为灰度图像
edges = cv2.Canny(gray, 50, 150, apertureSize=3)        # 执行边缘检测
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 1,minLineLength=100, maxLineGap=10)   # 概率霍夫线变换
img3 = img.copy()
for line in lines:                                          # 逐条绘制直线x1, y1, x2, y2 = line[0]    cv2.line(img3, (x1, y1), (x2, y2), (0, 0, 255), 2)      # 绘制直线
cv2.imshow('HoughLines', img3)                            # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

霍夫圆变换

cv2.HoughCircles()函数利用霍夫变换查找图像中的圆,其基本格式如下:

circles=cv2.HoughCircles(image,method,dp,minDist,param1,param2,minRadius,maxRadius)

其参数说明如下:

参数 说明
circles 为返回的圆。
image 为原图像,必须是8位的单通道二值图像。
method 为查找方法,可设置为cv2.HOUGH_GRADIENT和cv2.HOUGH_GRADIENT _ALT。
dp 为累加器分辨率,它与图像分辨率成反比。例如,如果dp=1,则累加器与输入图像的分辨率相同;如果dp =2,则累加器的宽度和高度是输入图像的一半。
minDist 为圆心间的最小距离。
param1 为对应Canny边缘检测的高阈值(低阈值是高阈值的一半),默认值为100。
param2 为圆心位置必须达到的投票数,值越大,检测出的圆越少,默认值为100。
minRadius 为最小圆半径,半径小于该值的圆不会被检测出来。其默认值为0,不起作用。
maxRadius 为最大圆半径,半径大于该值的圆不会被检测出来。其默认值为0,不起作用。
import cv2
import numpy as npimg = cv2.imread('shape6.jpg')                         # 读取图像
cv2.imshow('original', img)                           # 显示原图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)               # 转化为灰度图像
edges = cv2.Canny(gray, 50, 150, apertureSize=3)        # 执行边缘检测
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 50,param2=30,minRadius=10, maxRadius=40)  # 检测圆
circles = np.uint16(np.around(circles))
img2 = img.copy()
for i in circles[0, :]:cv2.circle(img2, (i[0], i[1]), i[2], (255, 0, 0), 2)    # 画圆cv2.circle(img2, (i[0], i[1]), 2, (0, 0, 255), 3)       # 画圆心
cv2.imshow('circles', img2)                               # 显示结果图像
cv2.waitKey(0)                                              # 按任意键结束等待
cv2.destroyAllWindows()                                     # 关闭所有窗口

实验素材





8.opencv——图像轮廓,霍夫变换相关推荐

  1. 发现你的身形——OpenCV图像轮廓

    文章目录 写在最前 轮廓发现算法 边缘检测 写在最后 写在最前 我的意思不是说你长得很胖,emmmm,而是你的轮廓很大. --五星上将詹姆斯下士如是说 果然有图没图,理解是不一样的,这就体现了计算机视 ...

  2. 《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  3. 《OpenCv视觉之眼》Python图像处理十四 :Opencv图像轮廓提取之Scharr算法和Canny算法

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  4. OpenCV 图像轮廓检测

    本文是OpenCV图像视觉入门之路的第15篇文章,本文详细的介绍了图像轮廓检测的各种操作,例如:轮廓检索模式.轮廓逼近算子等操作. 图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检 ...

  5. OPENCV图像轮廓检测

    前面在图像转换的时候学到canny算子,可以检测出图像的轮廓信息,但是,该算子检测到的轮廓信息还需要我们手动的用眼睛去识别,而实际工程应用中,我们需要得到轮廓的具体数学信息,这就涉及到今天的主题,图像 ...

  6. opencv图像轮廓

    1.1什么是轮廓   cv2.findContours() 轮廓可以简单认为成连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度.轮廓在形状分析和物体的检测和识别中很有用.为了准确,要使用二值 ...

  7. 【笔记】opencv图像轮廓 获得平均灰度值在原图上画轮廓 观察灰度图的分解

    调整大小: image = cv2.resize(image,dst=None,fx=0.5,fy = 0.5,dsize=None) img = cv2.resize(img,dst=None,fx ...

  8. 图像轮廓提取算法(Opencv基于C++实现)

    Opencv图像轮廓提取 0. 实现结果如下: 1. 打开图像代码 2. 轮廓提取函数 3. 代码实现 本文主要实现了图像的轮廓提取,首先先给出直观的轮廓实现结果: 0. 实现结果如下: 1. 打开图 ...

  9. OpenCV:07图像轮廓

    图像轮廓 什么是图形轮廓 查找轮廓 绘制轮廓 计算轮廓的面积和周长 轮廓面积 轮廓周长 多边形逼近 凸包 轮廓拟合 外接矩形 最小外接矩形 最大外接矩形 外接圆 边缘检测`Canny` 霍夫变换 直线 ...

最新文章

  1. 教你两种python selenium保存图片的方法
  2. oracle加undo+resize,How To resize undo tablespace in Oracle
  3. 关注Cortex-M处理器,M0、M3、M4简单对比
  4. linux7 security,SECURITY-centos7下NFS使用与配置
  5. mac 完全卸载android studio
  6. 如何解决JavaScript中0.1+0.2不等于0.3
  7. MyEclipse Tomcat jar包问题
  8. xxx.jar 中没有主清单属性
  9. 辅助类BinaryTreeNode(二叉树节点)
  10. 多线程队列的算法优化
  11. 第七届山东省Acm程序设计竞赛赛后总结
  12. 潜伏研发群一个月,我发现了程序员不为人知的秘密!这也太可爱了吧
  13. 【人脸识别】VGGFace2数据集介绍
  14. 洛谷-神奇的幻方-NOIP2015提高组复赛
  15. gitignore文件的几种写法,Git忽略文件规则的配置方法
  16. cmake 交叉编译_如何使用CMake编译RTT微内核
  17. 获取最顶层的ViewController top ViewController swift
  18. linux 内核移植和根文件系统的制作
  19. maven中使用assembly打包
  20. 使用Comparator.comparing根据类的属性对list进行排序

热门文章

  1. java keystore 私钥,从Java Keystore文件中提取私钥、证书
  2. 跨年倒计时软件app哪个好 2022年跨年倒计时软件推荐云便签
  3. 网约车市场再起风云,T3、高德谁能“狙击”美团?
  4. 安卓 自定义相机,身份证拍照
  5. Ubuntu16.04 x64服务器配置最新tcp拥塞控制算法bbr
  6. MFC中通过Tooltip类来实现悬浮鼠标显示提示信息
  7. 计算机b级excel函数,大学计算机一级excel函数归类 2
  8. python机器学习数理基础
  9. 史上最强c++代码——“boost::asio”
  10. 金仓数据库KingbaseES安全指南--5.2. 数据完整性保护