第16章:霍夫变换

第16章:霍夫变换

    • 一、霍夫直线变换:
      • 1. 霍夫直线变换原理:
      • 2. HoughLines函数:
      • 3. HoughLinesP函数:
    • 2. 霍夫圆环变换:

  • 霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。
  • 霍夫变换采用类似于投票的方式来获取当前图像内的形状集合,该变换由Paul Hough(霍夫)于1962年首次提出。

最初的霍夫变换只能用于检测直线,经过发展后,霍夫变换不仅能够识别直线,还能识别其他简单的图形结构,常见的有圆、椭圆等。实际上,只要是能够用一个参数方程表示的对象,都适合用霍夫变换来检测。

下面主要介绍霍夫直线变换霍夫圆变换

  • 霍夫直线变换用来在图像内寻找直线。在 OpenCV 中,可以用函数 cv2.HoughLines()和函数cv2.HoughLinesP()实现。
  • 霍夫圆变换用来在图像内寻找圆。以用函数cv2.HoughCircles()实现。

一、霍夫直线变换:

OpenCV 提供了函数 cv2.HoughLines()和函数 cv2.HoughLinesP()用来实现霍夫直线变换。下面首先介绍霍夫变换的基本原理,然后分别介绍这两个函数的基本使用方法。

1. 霍夫直线变换原理:

​ 为了方便说明问题,先以我们熟悉的笛卡儿坐标系(即平面直角坐标系,与笛卡儿空间对应)为例来说明霍夫变换的基本原理。与笛卡儿坐标系对应,我们构造一个霍夫坐标系(对应于霍夫空间)。在霍夫坐标系中,横坐标采用笛卡儿坐标系中直线的斜率k,纵坐标使用笛卡儿坐标系中直线的截距b。

​ 首先,我们观察笛卡儿空间中的一条直线在霍夫空间内的映射情况。例如下图中,左图是笛卡儿x-y坐标系(笛卡儿空间),右图是霍夫k-b坐标系(霍夫空间)。在笛卡儿空间中,存在着一条直线y=k0x+b0,该直线的截距k0是已知的常量,截距b0也是已知的常量。将该直线映射到霍夫空间内,找到已知的点(k0,b0),即完成映射。

image-20211208155701791

​ 从上述分析中可知,笛卡儿空间内的一条直线,其斜率为k,截距为b,映射到霍夫空间内成为一个点(k,b)。或者,可以这样理解,霍夫空间内的一个点(k0,b0),映射到笛卡儿空间,就是一条直线y=k0x+b0。

​ 这里,我们用“映射”这个词表达不同的空间(坐标系)之间的对应关系,也可以表述为“确定”。例如,上述关系可以表述为:

  • 笛卡儿空间内的一条直线确定了霍夫空间内的一个点。
  • 霍夫空间内的一个点确定了笛卡儿空间内的一条直线。

​ 接下来,观察笛卡儿空间中的一个点在霍夫空间内的映射情况。如下图所示,在笛卡儿空间内存在一个点(x0,y0),通过该点的直线可以表示为y0=kx0+b。其中,(x0,y0)是已知的常量,(k,b)是变量。

​ 对于表达式y0=kx0+b,通过算术运算的左右移项,可以表示为b=−x0k+y0。将点(x0,y0)映射到霍夫空间时,可以认为对应的直线斜率为−x0,截距为y0,即b=−x0k+y0,如下图中右图的直线所示。

image-20211208155944679

从上述分析可知:

  • 笛卡儿空间内的点(x0,y0)映射到霍夫空间,就是直线b=−x0k+y0。
  • 霍夫空间内的直线b=−x0k+y0映射到笛卡儿空间,就是点(x0,y0)。

下面我们看看笛卡儿空间中的两个点映射到霍夫空间的情况。例如,在下图中,左图的笛卡儿空间中存在着两个点(x0,y0)、(x1,y1),分析这两个点映射到霍夫空间的情况。

image-20211208160054385

为了方便理解,我们从不同的角度分析笛卡儿空间中这两个点到霍夫空间的映射情况。

  • 角度1:笛卡儿空间的一个点会映射为霍夫空间的一条线。

    在笛卡儿空间内,存在着任意两个点(x0,y0)、(x1,y1)。在霍夫空间中,这两个点对应着两条不同的直线。当然,通过分析可知,一条直线是b=−x0k+y0,另外一条直线是b=−x1k+y1。

  • 角度2:笛卡儿空间的一条线会映射为霍夫空间的一个点

    在笛卡儿空间内,存在着任意两个点(x0,y0)、(x1,y1)。这两个点一定能够用一条直线连接,将连接它们的直线标记为y=k1x+b1,则该直线的截距和斜率是(k1,b1)。也就是说,该直线在霍夫空间内映射为点(k1,b1)。

从上述分析可知:

  • 笛卡儿空间内的两个点会映射为霍夫空间内两条相交于(k1,b1)的直线。
  • 这两个点对应的直线会映射为霍夫空间内的点(k1,b1)。

换句话说,角度1决定了线条的数量,角度2决定了两条线相交的点。

这说明,如果在笛卡儿空间内有两个点A、B,它们能够连成一条直线y=k1x+b1,那么在霍夫空间中的点(k1,b1)上会有两条直线,分别对应着笛卡儿空间内的两个点A、B。

下面我们看看笛卡儿空间中的三个点映射到霍夫空间的情况。在下图中,左图是笛卡儿空间,其中存在(0,1)、(1,2)、(2,3)三个点。

image-20211208161422534

下面从不同的角度分析笛卡儿空间中这三个点映射到霍夫空间的情况。

  • 角度1:笛卡儿空间内的一个点会映射为霍夫空间的一条线。

    例如,笛卡儿空间中的(0,1)、(1,2)、(2,3)三个点映射到霍夫空间时,每个点对应着一条直线,对应关系如表所示。image-20211208161509551

    根据对应关系可知:

    • 笛卡儿空间内的点(0,1),对应着霍夫空间内的直线b=1。
    • 笛卡儿空间内的点(1,2),对应着霍夫空间内的直线b=-k+2。
    • 笛卡儿空间内的点(2,3),对应着霍夫空间内的直线b=-2k+3。

从上述分析可知,笛卡儿空间内的三个点映射为霍夫空间内的三条直线。

  • 角度2:笛卡儿空间内的一条线会映射为霍夫空间的一个点。

    例如,笛卡儿空间中的(0,1)、(1,2)、(2,3)三个点对应着直线y=x+1,斜率k为1,截距b为1。该直线y=x+1 映射到霍夫空间内的点(1,1)。

从上述角度1和角度2的分析可知:

  • 笛卡儿空间中的(0,1)、(1,2)、(2,3)三个点会映射为霍夫空间内相交于点(1,1)的三条直线。
  • 笛卡儿空间中的(0,1)、(1,2)、(2,3)三个点所连成(确定)的直线映射为霍夫空间内的点(1,1)

​ 这说明,如果在笛卡儿空间内有三个点,并且它们能够连成一条y=k1x+b1的直线,那么在霍夫空间中,对应的点(k1,b1)上会有三条直线,分别对应着笛卡儿空间内的三个点。

​ 到此,我们已经发现,如果在笛卡儿空间内,有N个点能够连成一条直线y=k1x+b1,那么在霍夫空间内就会有N条直线穿过对应的点(k1,b1)。或者反过来说,如果在霍夫空间中,有越多的直线穿过点(k1,b1),就说明在笛卡儿空间内有越多的点位于斜率为k1,截距为b1的直线y=k1x+b1上。

​ 现在,我们看一个在笛卡儿空间内更多个点映射到霍夫空间的例子,也验证一下上述观点。在下图中,左图所示的是笛卡儿空间,其中有6个点,下面从不同的角度看下这6个点在右图霍夫空间的映射情况。

image-20211208162137460

  • 角度1:笛卡儿空间的一点会映射为霍夫空间的一条线。

笛卡儿空间中的6个点:(0,1)、(1,2)、(2,3)、(3,4)、(3,2)、(1,4),映射到霍夫空间时,每个点对应着一条直线,对应关系如表所示

image-20211208162418904
根据对应关系可知:

  • 笛卡儿空间内的点(0,1),对应着霍夫空间内的直线b=1。
  • 笛卡儿空间内的点(1,2),对应着霍夫空间内的直线b=-k+2。
  • 笛卡儿空间内的点(2,3),对应着霍夫空间内的直线b=-2*k+3。
  • 笛卡儿空间内的点(3,4),对应着霍夫空间内的直线b=-3*k+4。
  • 笛卡儿空间内的点(3,2),对应着霍夫空间内的直线b=-3*k+2。
  • 笛卡儿空间内的点(1,4),对应着霍夫空间内的直线b=-1*k+4。

从上述分析可知,笛卡儿空间内的6个点映射为霍夫空间内的6条直线

  • 角度2:笛卡儿空间的一条线会映射为霍夫空间的一个点。

    这里为了观察方便,将笛卡儿空间内连接了较多点的线绘制出来:连接点(0,1)、(1,2)、(2,3)、(3,4)的线LineA,连接点(2,3)、(3,2)、(1,4)的线LineB,连接点(0,1)、(3,2)的线LineC

    image-20211208162843769

需要注意,在笛卡儿空间内,各个点之间存在多条直线。例如在点(1,2)、(3,2)之间,点(3,2)、(3,4)之间,点(1,4)、(3,4)之间都存在着直线,这里做了简化,没有将上述直线都绘制出来。

下面分析笛卡儿空间内的三条直线LineA、LineB、LineC在霍夫空间内的映射情况。

  • 直线LineA经过了4个点,表达式为y=1 * x+1,斜率k为1,截距b为1,在霍夫空间内对应于点A(1,1)。
  • 直线LineB经过了3个点,表达式为y=-1 * x+5,斜率k为-1,截距b为5,在霍夫空间内对应于点B(-1,5)。
  • 直线LineC经过了2个点,表达式为y=-1/3 * x+1,斜率k为-1/3,截距b为1,在霍夫空间内对应于点C(-1/3,1)。

在上图中可以看到,右图所示的霍夫空间内点A有4条直线穿过,点B有3条直线穿过,点C有2条直线穿过。分析上述关系:

  • 霍夫空间内有4条直线穿过点A。点A确定了笛卡儿空间内的一条直线,同时该直线穿过4个点,即霍夫空间内的点A确定了笛卡儿空间内的LineA,该直线上包含(0,1)、(1,2)、(2,3)、(3,4)共4个点。
  • 霍夫空间内有3条直线穿过点B。点B确定了笛卡儿空间内的一条直线,同时该直线穿过3个点,即霍夫空间内的点B确定了笛卡儿空间内的LineB,该直线上包含(2,3)、(3,2)、(1,4)共3个点。
  • 霍夫空间内有2条直线穿过点C。点C确定了笛卡儿空间内的一条直线,同时该直线穿过2个点,即霍夫空间内的点C确定了笛卡儿空间内的LineC,该直线上包含(0,1)、(2,3)共2个点。

​ 综上所述,在霍夫空间内,经过一个点的直线越多,说明其在笛卡儿空间内映射的直线,是由越多的点所构成(穿过)的。我们知道,两个点就能构成一条直线。但是,如果有一个点是因为计算错误而产生的,那么它和另外一个点,也会构成一条直线,此时就会凭空构造出一条实际上并不存在的直线。这种情况是要极力避免的。

​ 因此,在计算中,我们希望用更多的点构造一条直线,以提高直线的可靠性。也就是说,如果一条直线是由越多点所构成的,那么它实际存在的可能性就越大,它的可靠性也就越高。

因此,霍夫变换选择直线的基本思路是:选择有尽可能多直线交汇的点。

上面都是以我们熟悉的笛卡儿空间为例说明的。在笛卡儿空间中,可能存在诸如x=x0的垂线LineA的形式

image-20211208163839539

此时,斜率k为无穷大,截距b无法取值。因此,上图中的垂线LineA无法映射到霍夫空间内。为了解决上述问题,可以考虑将笛卡儿坐标系映射到极坐标系上,如图所示。

image-20211208164004913

在笛卡儿坐标系内使用的是斜率k和截距b,即用(k,b)表示一条直线。在极坐标系内,采用极径r(有时也用ρ表示)和极角θ来表示,即(r,θ)来表示。极坐标系中的直线可以表示为:

  • r=xcosθ+ysinθ

​ 例如,上图中的直线LineA,可以使用极坐标的极径r和极角θ来表示。其中,r是直线LineA与图像原点O之间的距离,参数θ是直线LineA的垂线LineB与x轴的角度。在这种表示方法中,图像中的直线有一个(0~π)的角θ,而r的最大值是图像对角线的长度。用这种表示方法,可以很方便地表示上图中的3个点所构成的直线。

与笛卡儿空间和霍夫空间的映射关系类似:

  • 极坐标系内的一个点映射为霍夫坐标系(霍夫空间)内的一条线(曲线)。
  • 极坐标系内的一条线映射为霍夫坐标系内的一个点。

一般来说,在极坐标系内的一条直线能够通过在霍夫坐标系内相交于一点的线的数量来评估。在霍夫坐标系内,经过一个点的线越多,说明其映射在极坐标系内的直线,是由越多的点所构成(穿过)的。因此,霍夫变换选择直线的基本思路是:选择由尽可能多条线汇成的点。

​ 通常情况下,设置一个阈值,当霍夫坐标系内交于某点的曲线达到了阈值,就认为在对应的极坐标系内存在(检测到)一条直线。

​ 上述内容是霍夫变换的原理,即使完全不理解上述原理,也不影响我们使用OpenCV提供的霍夫变换函数来进行霍夫变换。OpenCV本身是一个黑盒子,它给我们提供了接口(参数、返回值),我们只需要掌握接口的正确使用方法,就可以正确地处理图像问题,无须掌握其内部工作原理。

​ 在某种情况下,OpenCV库和Photoshop等图像处理软件是类似的,只要掌握了它们的使用方法,就能够得到正确的处理结果。在进行图像处理时,并不需要我们关注其实现原理等技术细节。但是,如果我们进一步了解其工作原理,对我们的工作也是有大有裨益的。

2. HoughLines函数:

OpenCV 提供了函数 cv2.HoughLines()用来实现霍夫直线变换,该函数要求所操作的源图像是一个二值图像,所以在进行霍夫变换之前要先将源图像进行二值化,或者进行 Canny 边缘检测。

函数cv2.HoughLines()的语法格式为:

  • lines=cv2.HoughLines(image,rho,theta,threshold)
    • image:是输入图像,即源图像,必须是8位的单通道二值图像。如果是其他类型的图像,在进行霍夫变换之前,需要将其修改为指定格式。
    • rho:为以像素为单位的距离r的精度。一般情况下,使用的精度是1。
    • theta:为角度θ的精度。一般情况下,使用的精度是π/180,表示要搜索所有可能的角度。
    • threshold:是阈值。该值越小,判定出的直线就越多。通过上一节的分析可知,识别直线时,要判定有多少个点位于该直线上。在判定直线是否存在时,对直线所穿过的点的数量进行评估,如果直线所穿过的点的数量小于阈值,则认为这些点恰好(偶然)在算法上构成直线,但是在源图像中该直线并不存在;如果大于阈值,则认为直线存在。所以,如果阈值较小,就会得到较多的直线;阈值较大,就会得到较少的直线。
    • lines:返回值 ,每个元素都是一对浮点数,表示检测到的直线的参数,即(r,θ),是numpy.ndarray类型。

注意:

​ 使用函数 cv2.HoughLines()检测到的是图像中的直线而不是线段,因此检测到的直线是没有端点的。所以,我们在进行霍夫直线变换时所绘制的直线都是穿过整幅图像的。

​ 绘制直线的方法是,对于垂直方向的直线(不是指垂线,是指垂直方向上的各种角度的直线),计算它与图像水平边界(即图像中的第一行和最后一行)的交叉点,然后在这两个交叉点之间画线。对于水平方向上的直线,采用类似的方式完成,只不过用到的是图像的第一列和最后一列。

​ 在绘制线时,所使用的函数是cv2.line()。该函数方便的地方在于,即使点的坐标超出了图像的范围,它也能正确地画出线来,因此没有必要检查交叉点是否位于图像内部。遍历函数cv2.HoughLines()的返回值lines

import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('./buliding.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_img, 50, 150, apertureSize=3)rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
new_img = rgb_img.copy()
print(lines)
for line in lines:rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 1000 * (-b))y1 = int(y0 + 1000 * (a))x2 = int(x0 - 1000 * (-b))y2 = int(y0 - 1000 * (a))cv2.line(new_img, (x1, y1), (x2, y2), (0, 0, 255), 2)plt.subplot(131)
plt.imshow(rgb_img)
plt.axis('off')plt.subplot(132)
plt.imshow(edges)
plt.axis('off')plt.subplot(133)
plt.imshow(new_img)
plt.axis('off')plt.show()

image-20211208200103945

补充:OpenCV中HoughLines两个点(x1, y1),(x2, y2)是如何求出的。

image-20211209150106449

上图显示怎么放大线段到1000即当r=1000时的计算方法。可以是300也可是500、800。

3. HoughLinesP函数:

概率霍夫变换对基本霍夫变换算法进行了一些修正,是霍夫变换算法的优化。它没有考虑所有的点。相反,它只需要一个足以进行线检测的随机点子集即可。

为了更好地判断直线(线段),概率霍夫变换算法还对选取直线的方法作了两点改进:

  • **所接受直线的最小长度。**如果有超过阈值个数的像素点构成了一条直线,但是这条直线很短,那么就不会接受该直线作为判断结果,而认为这条直线仅仅是图像中的若干个像素点恰好随机构成了一种算法上的直线关系而已,实际上原图中并不存在这条直线。
  • **接受直线时允许的最大像素点间距。**如果有超过阈值个数的像素点构成了一条直线,但是这组像素点之间的距离都很远,就不会接受该直线作为判断结果,而认为这条直线仅仅是图像中的若干个像素点恰好随机构成了一种算法上的直线关系而已,实际上原始图像中并不存在这条直线。

在OpenCV中通过cv2.HoughLinesP()函数实现概率霍夫变换:

  • lines = cv2.HoughLiesP(image, rho, theta, threshold, minLineLength, maxLineGap)
    • image:是输入图像,即原图像,必须为8位的单通道二值图像。对于其他类型的图像,在进行霍夫变换之前,需要将其修改为这个指定的格式。
    • rho:为以像素为单位的距离r的精度。一般情况下,使用的精度是1。
    • theta:是角度θ的精度。一般情况下,使用的精度是np.pi/180,表示要搜索可能的角度。
    • threshold:是阈值。该值越小,判定出的直线越多;值越大,判定出的直线就越少。
    • minLineLength:用来控制“接受直线的最小长度”的值,默认值为0。
    • maxLineGap:用来控制接受共线线段之间的最小间隔,即在一条线中两点的最大间隔。
      如果两点间的间隔超过了参数maxLineGap的值,就认为这两点不在一条线上。默认值为0。
    • lines:返回值。是由numpy.ndarray类型的元素构成的,其中每个元素都是一对浮点数,表示检测到的直线的参数,即(x1, y1)、(x2, y2)。
import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('buliding.jpg')
grey_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
new_img = rgb_img.copy()edges = cv2.Canny(grey_img, 150, 200, apertureSize=3)lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=30)
for line in lines:x1, y1, x2, y2 = line[0]cv2.line(new_img, (x1, y1), (x2, y2), (255, 0, 0), 2)plt.subplot(131)
plt.imshow(rgb_img)
plt.title('img')
plt.axis('off')plt.subplot(132)
plt.imshow(edges)
plt.title('edges')
plt.axis('off')plt.subplot(133)
plt.imshow(new_img)
plt.title('rst')
plt.axis('off')plt.show()

image-20211209141003077

2. 霍夫圆环变换:

​ 霍夫变换除了用来检测直线外,也能用来检测其他几何对象。实际上,只要是能够用一个参数方程表示的对象,都适合用霍夫变换来检测。

​ 用霍夫圆变换来检测图像中的圆,与使用霍夫直线变换检测直线的原理类似。在霍夫圆变换中,需要考虑圆半径和圆心(x坐标、y坐标)共3个参数。在OpenCV中,采用的策略是两轮筛选。第1轮筛选找出可能存在圆的位置(圆心);第2轮再根据第1轮的结果筛选出半径大小。

​ 与用来决定是否接受直线的两个参数“接受直线的最小长度(minLineLength)”和“接受直线时允许的最大像素点间距(MaxLineGap)”类似,霍夫圆变换也有几个用于决定是否接受圆的参数:圆心间的最小距离、圆的最小半径、圆的最大半径。

在OpenCV中,通过函数cv2.HoughCircles()实现霍夫圆变换,**该函数将Canny边缘检测和霍夫变换结合。**其语法格式为:

  • circles = cv2.HoughCircles(image, method, dp, minDist, param1, param2, minRadius, maxradius)
    • image:输入图像,即源图像,类型为8位的单通道灰度图像。
    • method:检测方法。截止到OpenCV 4.0.0-pre版本,HOUGH_GRADIENT是唯一可用的参数值。该参数代表的是霍夫圆检测中两轮检测所使用的方法。
    • dp:累计器分辨率,它是一个分割比率,用来指定图像分辨率与圆心累加器分辨率的比例。例如,如果dp=1,则输入图像和累加器具有相同的分辨率。
    • minDist:圆心间的最小间距。该值被作为阈值使用,如果存在圆心间距离小于该值的多个圆,则仅有一个会被检测出来。因此,如果该值太小,则会有多个临近的圆被检测出来;如果该值太大,则可能会在检测时漏掉一些圆。
    • param1:该参数是缺省的,在缺省时默认值为100。它对应的是Canny边缘检测器的高阈值(低阈值是高阈值的二分之一)。
    • param2:圆心位置必须收到的投票数。只有在第1轮筛选过程中,投票数超过该值的圆,才有资格进入第2轮的筛选。因此,该值越大,检测到的圆越少;该值越小,检测到的圆越多。这个参数是缺省的,在缺省时具有默认值100。
    • minRadius:圆半径的最小值,小于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
    • maxRadius:圆半径的最大值,大于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
    • circles:返回值,由圆心坐标和半径构成的numpy.ndarray。

需要特别注意,在调用函数 cv2.HoughLinesCircles()之前,要对源图像进行平滑操作,以减少图像中的噪声,避免发生误判。

import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('xiangqi.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
new_img = rgb_img.copy()circles = cv2.HoughCircles(gray_img, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=50, maxRadius=100)
print(circles)
circles = np.uint16(np.around(circles))
print(circles)
for i in circles[0, :]:cv2.circle(new_img, (i[0], i[1]), i[2], (255, 0, 0), 10)# 圆心cv2.circle(new_img, (i[0], i[1]), 2, (255, 0, 0), 10)plt.subplot(121)
plt.imshow(rgb_img)
plt.title('img')
plt.axis('off')plt.subplot(122)
plt.imshow(new_img)
plt.title('rst')
plt.axis('off')
plt.show()

image-20211209145638841

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个java处理JSON格式数据的通用类(三)

/** *//** * 从json数组中解析出java Integer型对象数组 * param jsonString * return */ public static Double[] getDoubleArray4Json(String jsonString)...{ JSONArray jsonArray JSONArray.fromObject(jsonString); Doubl…

【树莓派学习笔记】九、C语言寄存器操作控制GPIO

目录CPU型号确定寄存器的地址问题GPIO寄存器GPFESLnGPSETnGPCLRn重要函数mmap函数munmap函数点灯程序平台:树莓派3B 版本: 2021-05-07-raspios-buster-armhf CPU型号确定 由 pinout命令可知,所用的板子Soc型号为BCM2837 寄存器的地址问题…

bzoj2527

首先环可以变成链来处理,对于l>r的情况就是修改区间[1,r],[l,mx]然后不难想到整体二分,二分答案k,然后算1~k场流星雨对国家的贡献然后判定将国家划分变成子问题解决,没什么难的终于不是tle,poi良心了一把 1 type wayrecord2 …

第17章:图像分割提取

第17章:图像分割提取一、用分水岭算法实现图像分割提取:1. 算法原理:2. 相关函数介绍:(1) 形态学函数回顾:(2) 距离变换函数distanceTransform:(3) 确定未知区域:(4) 函数connectedComponents对…

[转]可伸缩系统的架构经验

最近,阅读了Will Larson的文章Introduction to Architecting System for Scale,感觉很有价值。作者分享了他在Yahoo!与Digg收获的设计可伸缩系统的架构经验。在我过往的架构经验中,由于主要参与开发企业软件系统,这种面向企业内部…

【Linux技巧】cmake、make命令多线程编译,大大提高编译速度

目录获取最大可用线程数自动以最大线程数编译makecmake效果系统:Debian 获取最大可用线程数 nprocnproc命令可返回当前可用的最大线程数 树莓派3B (BCM2837):4 RK3399 Pro:6 自动以最大线程数编译 make sudo make -j $(nproc)cmake su…

redis学习(九)——数据持久化

一、概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的。所以,我们需要将内存中的数据持久化!典型的需要持久…

【机器视觉学习笔记】生成高斯滤波器掩膜(C++)

目录原理二维高斯分布生成高斯掩膜(小数形式)源码及效果平台:Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文算法摘自高斯滤波(GaussianFilter)原理及C实现 —— 小武~~ 原理 高斯滤波和均值滤波一样,都是利用一个掩膜…

第18章:视频处理

第18章:视频处理一、VideoCapture类:1. VideoCapture类中相关方法介绍:(1) 初始化:(2) 初始化判断方法:(3) 捕获帧:(4) 释放:(5) 属性设置:(6) 捕获多摄像头(视频文件)数据&#xff…

C++的常量折叠(一)

前言 前几天女票问了我一个阿里的面试题,是有关C语言的const常量的,其实她一提出来我就知道考察的点了:肯定是const常量的内存不是分配在read-only的存储区的,const常量的内存分配区是很普通的栈或者全局区域。也就是说const常量只…

【机器视觉学习笔记】二值图像和灰度图像的膨胀、腐蚀、开运算、闭运算算法(C++)

目录二值图像原理腐蚀结构的原点设置在结构内部情况举例结构的原点设置在结构的外部情况举例膨胀结构的原点设置在结构的内部情况举例结构的原点设置在结构的外部情况举例开闭运算完整源码效果原图腐蚀运算膨胀运算开运算闭运算灰度图像原理腐蚀膨胀开闭运算完整源码效果原图腐…

【机器视觉学习笔记】二值图像连通区域提取算法(C++)

目录原理二值图像连通区域(Connected Component)连通区域分析(Connected Component Analysis,Connected Component Labeling)算法:Two-Pass(两遍扫描法)思路:Two-Pass算法的简单步骤…

【机器视觉学习笔记】Harris 角点检测算法(C++)

目录原理算法步骤优缺点源码效果原图输出平台:Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文摘自2、Harris角点检测算法 —— 诺亚方舟369 原理 Harris算子是对Moravec算子的改进,包括: (1)Harris算子用…

剖析ASSERT函数

2019独角兽企业重金招聘Python工程师标准>>>  搜集与总结了assert函数的用法,记于此,以备后续与查找使用: ****身在Windows的世界,但还是深爱着我的它---Linux****I love Linux forever***** …

MSP430G2553 移植 Contiki RTOS 实时操作系统

目录新建工程移植过程关于时间多任务示例main.c内存使用情况效果平台:Code Composer Studio 10.4.0 MSP-EXP430G2 LaunchPad 试验板 MSP430G2553 LaunchPad™ Development Kit (MSP‑EXP430G2ET) contiki下载:contiki-os Github 本文参考自二、Contiki…

Raphael JS 矢量客户端开源框架

之前有基于svg进行矢量绘制,当时是自己写的一些js类库,最近项目中需要,对Raphael做了一些了解,总体不错。 Raphael可以对浏览器的兼容做的不错,基于IE的会自动使用vml进行绘制,其他浏览器基于svg进行绘制&a…

mac os x10.8下如何使用git与github

2019独角兽企业重金招聘Python工程师标准>>> 1、准备工作: 下载安装git客户端 http://code.google.com/p/git-osx-installer/downloads/list?can3(安装了git客户端,命令行中才有git命令) 注册github账号 https://github.com/ -->Pricing …

使用 VS 附加到进程 调试发布的网站

适用场景:调试已发布的网站。 1、把项目 bin 目录下的 pdb 文件复制到服务器上相应网站的 bin 目录下。 2、把VS的调试工具中的 x64 文件夹复制到服务器任意位置。 3、服务器中打开调试工具,并配置端口(注意端口是否可用)。 4、在…

Github git 命令下载加速

目录手动输入法批处理文件系统:Windows 10 20H2 手动输入法 在要下载到的目录按住shift右键 选择在此处打开Powershell窗口 如要下载的仓库地址: 通常的git命令下载: git clone https://github.com/apache/incubator-nuttx.gitCNPMJS.ORG…

MySql 自动更新时间为当前时间

字段类型 : timestamp默认值 : CURRENT_TIMESTAMP如果是创建时间,则下面的“根据当前时间戳更新”不勾选。转载于:https://blog.51cto.com/9625815/1630767