当前位置: 首页 > news >正文

opencv_特征检测和描述

理解特征

寻找独特的特定模式或特定特征,可以轻松跟踪和比较。

拼图:在图像中搜索这些特征,找到它们,在其他图像中查找相同的特征并对齐它们。而已。

基本上,角被认为是图像中的好特征。

在本单元中,我们正在寻找 OpenCV 中的不同算法来查找特征,描述特征,匹配它们等。

Harris 角点检测

OpenCV 中的 Harris 角点检测器

Harris角点检测的结果是一个由角点分数构成的灰度图像。选取适当的阈值对结果图像进行二值化我们就检测到了图像中的角点。

为此,OpenCV具有函数cv.cornerHarris()。它的参数是:

  • img - 输入图像,应该是灰度和float32类型。
  • blockSize - 考虑角点检测的邻域大小
  • ksize - 使用的Sobel衍生物的孔径参数。
  • k - 方程中的Harris检测器自由参数。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg1 = cv.imread('c:/Users/HP/Downloads/chessboard1.png')
img2 = cv.imread('c:/Users/HP/Downloads/chessboard2.png')
img3 = cv.imread('c:/Users/HP/Downloads/chessboard3.png')gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# 阈值选择
img1[dst>0.01*dst.max()]=[0,0,255]gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# 阈值选择
img2[dst>0.01*dst.max()]=[0,0,255]gray = cv.cvtColor(img3,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# 阈值选择
img3[dst>0.01*dst.max()]=[0,0,255]plt.figure()  plt.subplot(2, 2, 1)  # (rows, columns, panel number)  
plt.imshow(img1)  
plt.axis('off')  # 关闭坐标轴  plt.subplot(2, 2, 2)  # (rows, columns, panel number)  
plt.imshow(img2)  
plt.axis('off')  # 关闭坐标轴  plt.subplot(2, 2, 3)  # (rows, columns, panel number)  
plt.imshow(img3)  
plt.axis('off')  # 关闭坐标轴  plt.show()

在这里插入图片描述

具有亚像素级精度的角点

以最高精度找到角点:

OpenCV 带有一个函数 cv.cornerSubPix() ,它进一步细化了角点检测,以达到亚像素级精度:

先找到 Harris 角点,然后将这些角的质心(角点处可能有一堆像素,我们采用它们的质心)传递给该函数来细化它们;

在经过指定次数的迭代或达到一定精度后停止它,以先发生者为准。

Harris 角点以红色像素标记,细化后的角点以绿色像素标记。

import numpy as np
import cv2 as cvimg = img1
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)# find Harris corners
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
dst = cv.dilate(dst,None)
ret, dst = cv.threshold(dst,0.01*dst.max(),255,0)
dst = np.uint8(dst)# 找到质心
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)# 定义refine的标准
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)# Now draw them
res = np.hstack((centroids,corners))
res = np.int0(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]] = [0,255,0]plt.xticks([]), plt.yticks([]) # 隐藏 X 和 Y 轴的刻度值
plt.imshow(img)

在这里插入图片描述

放大

Shi-Tomasi 角点检测和追踪的良好特征

J. Shi 和 C. Tomasi 在他们的论文 Good Features to Track 中做了一个小修改,与 Harris 角点检测相比显示出更好的结果。

Harri 角点检测的评分由下式给出: R = λ 1 λ 2 − k ( λ 1 + λ 2 ) 2 R = \lambda_1 \lambda_2 - k(\lambda_1+\lambda_2)^2 R=λ1λ2k(λ1+λ2)2

不同于此,Shi-Tomasi 提出: R = m i n ( λ 1 , λ 2 ) R = min(\lambda_1, \lambda_2) R=min(λ1,λ2)

cv.goodFeaturesToTrack() 通过 Shi-Tomasi 方法(或 Harris 角点检测,如果你指定它)在图像中找到 N 个最佳的角点:

  • 灰度图像;
  • 指定要查找的角点数量;
  • 然后指定质量等级,该等级是 0-1 之间的值,所有低于这个质量等级的角点都将被忽略;
  • 最后设置检测到的两个角点之间的最小欧氏距离。

通过所有这些信息,该函数可以在图像中找到角点。所有低于质量等级的角点都将被忽略。然后它根据质量按降序对剩余的角点进行排序。该函数选定质量等级最高的角点(即排序后的第一个角点),忽略该角点最小距离范围内的其余角点,以此类推最后返回 N 个最佳的角点。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('c:/Users/HP/Downloads/chessboard3.png')gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray,25,0.01,10)  # 角点数,质量等级,最小欧氏距离
corners = np.int0(corners)
for i in corners:x,y = i.ravel()cv.circle(img,(x,y),3,255,-1)plt.xticks([]), plt.yticks([]) # 隐藏 X 和 Y 轴的刻度值
plt.imshow(img),plt.show()

在这里插入图片描述

SIFT 简介(尺度不变特征变换)

Harris可以应对旋转,那么缩放呢?

–> Scale-Invariant Feature Transform (2004,D.Lowe,不列颠哥伦比亚大学)

  1. 尺度空间极值检测
  • 进行尺度空间滤波。使用不同 σ \sigma σ值的高斯拉普拉斯算子(LoG)对图像进行卷积。具有不同 σ \sigma σ值的 LoG 可以检测不同大小的斑点。简而言之, σ \sigma σ相当于一个尺度变换因子。

  • 例如,在上图中使用具有低 σ \sigma σ的高斯核可以检测出小的角点,而具有高 σ \sigma σ的高斯核则适合于检测大的角点。

  • 因此,我们可以在尺度空间和二维平面中找到局部最大值 ( x , y , σ ) (x, y, \sigma) (x,y,σ),这意味着在 σ \sigma σ尺度中的 ( x , y ) (x, y) (x,y)处有一个潜在的特征点。

  1. 特征点定位
  • 使用尺度空间的泰勒展开来获得潜在特征点更准确的极值位置。
  1. 指定方向
  • 为每个特征点指定方向,以实现图像的旋转不变性。
  1. 特征点描述子
  • 创建特征点描述子。

  • 在关键点周围选取 16x16 的邻域。将它为 16 个 4x4 大小的子块。对于每个子块,创建包含 8 个 bin 的方向直方图。因此总共有 128 个 bin 值可用。由这 128 个形成的向量构成了特征点描述子。

  • 除此之外,还采取了一些措施来实现对光照变化、旋转等的鲁棒性。

  1. 特征点匹配
  • 通过识别两幅图像中距离最近的特征点来进行特征点匹配。
import numpy as np
import cv2 as cv
img = cv.imread('c:/Users/HP/Downloads/house.png')plt.figure()  plt.subplot(1, 2, 1)  # (rows, columns, panel number)  
plt.imshow(img)  
plt.axis('off')  # 关闭坐标轴  gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
sift = cv.SIFT_create()
kp = sift.detect(gray,None)
img_ = cv.drawKeypoints(gray,kp,img)
cv.imwrite('c:/Users/HP/Downloads/house_sift.png',img_)plt.subplot(1, 2, 2)  # (rows, columns, panel number)  
plt.imshow(img_)  
plt.axis('off')  # 关闭坐标轴  plt.show()

在这里插入图片描述

img = cv.imread('c:/Users/HP/Downloads/house.png')
img = cv.drawKeypoints(gray,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 显示特征点的方向plt.imshow(img)  
plt.axis('off')

在这里插入图片描述

现在要计算描述子,OpenCV 提供了两种方法:

  1. 如果你已经找到了特征点,可以调用 sift.compute() 来计算我们找到的特征点的描述子。例如:kp,des = sift.compute(gray,kp)。
  2. 如果你没有找到特征点,请使用函数 sift.detectAndCompute() 在一个单独步骤中直接查找特征点和描述子。
# 第二种sift = cv.SIFT_create()
kp, des = sift.detectAndCompute(gray,None)# 这里 kp 是一个特征点列表,des 是一个 numpy 数组,该数组大小是特征点数目乘 128

SURF 简介(加速鲁棒特性)| BRIEF(Binary Robust Independent Elementary Features)

SURF:Speeded Up Robust Features (2006,Bay,H.,Tuytelaars,T., Van Gool,L) ,顾名思义,它是 SIFT 的加速版本。

实际匹配时可能不需要所有的维度 --> BRIEF 是一种更快计算和匹配特征点描述子的方法,提供较高的识别率,除非存在大的平面内旋转。

// 由于版权保护,新版opencv不支持这个功能,,为此换版本有点太麻烦了,暂且略过;

// https://github.com/opencv/opencv/wiki/ChangeLog#version4100

  • features2d

    • the unified framework for keypoint extraction, computing the descriptors and matching them has been introduced. The previously available and some new detectors and descriptors, like SURF, FAST, StarDetector etc. have been wrapped to be used through the framework. The key advantage of the new framework (besides the uniform API for different detectors and descriptors) is that it also provides high-level tools for image matching and textured object detection. Please, see documentation http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html\ and the C++ samples:
      • descriptor_extractor_matcher.cpp – finding object in a scene using keypoints and their descriptors.
      • generic_descriptor_matcher.cpp – variation of the above sample where the descriptors do not have to be computed explicitly.
      • bagofwords_classification.cpp – example of extending the framework and using it to process data from the VOC databases: http://pascallin.ecs.soton.ac.uk/challenges/VOC/
    • the newest super-fast keypoint descriptor BRIEF by Michael Calonder has been integrated by Ethan Rublee. See the sample opencv/samples/cpp/video_homography.cpp
    • SURF keypoint detector has been parallelized using TBB (the patch is by imahon and yvo2m)
  • 角点检测的 FAST 算法

    之前的方法还不够快

    –> FAST(Features from Accelerated Segment Test): Machine learning for high-speed corner detection (2006/2010,Edward Rosten 和 Tom Drummond)

    • 使用 FAST 进行特征检测

    • 机器学习角点检测器(决策树

    • 非最大值抑制(在相邻位置中检测到多个特征点

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('c:/Users/HP/Downloads/chessboard3.png',0)# Initiate FAST object with default values
    fast = cv.FastFeatureDetector_create()# find and draw the keypoints
    kp = fast.detect(img,None)
    img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))# Print all default params
    print( "Threshold: {}".format(fast.getThreshold()) )
    print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
    print( "neighborhood: {}".format(fast.getType()) )
    print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )# 不使用非最大值抑制
    fast.setNonmaxSuppression(0)
    kp = fast.detect(img,None)
    print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) )
    img3 = cv.drawKeypoints(img, kp, None, color=(255,0,0))plt.figure()  plt.subplot(1, 2, 1)  # (rows, columns, panel number)  
    plt.imshow(img2)  
    plt.title('nonmaxSuppression')  
    plt.axis('off') plt.subplot(1, 2, 2)  
    plt.imshow(img3)  
    plt.title('disable~')  
    plt.axis('off')  plt.show()
    

    在这里插入图片描述

    ORB(Oriented FAST and Rotated BRIEF)

    ORB: An efficient alternative to SIFT or SURF(2011,Ethan Rublee,Vincent Rabaud,Kurt Konolige,Gary R. Bradski)

    一个很好的 SIFT 和 SURF 的替代:SIFT 和 SURF 已获得专利,您应该支付它们的使用费用。但是 ORB 不是!!!

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread('c:/Users/HP/Downloads/chessboard3.png',0)# Initiate ORB detector
    orb = cv.ORB_create()# find the keypoints with ORB
    kp = orb.detect(img,None)# compute the descriptors with ORB
    kp, des = orb.compute(img, kp)# draw only keypoints location,not size and orientation
    img2 = cv.drawKeypoints(img, kp, None, color=(0,255,0), flags=0)
    plt.imshow(img2)
    plt.axis('off') 
    plt.show()

    在这里插入图片描述

    特征匹配

    蛮力匹配的基础知识

    蛮力匹配器很简单。它采用第一组中的一个特征点描述子,并使用一些距离计算与第二组中的所有其他特征点匹配。并返回距离最近的一个特征点。

    • 对于 BF 匹配器,首先我们必须使用 cv.BFMatcher() 创建 BFMatcher 对象。

    • 第二个参数是布尔变量 crossCheck,默认为 false。如果为 True,则 Matcher 仅返回具有值(i,j)的匹配,使得集合 A 中的第 i 个描述子具有集合 B 中的第 j 个描述子作为最佳匹配,反之亦然。

    • 一旦创建,两个重要的方法是 BFMatcher.match() 和 BFMatcher.knnMatch()。第一个返回最佳匹配。第二种方法返回 k 个最佳匹配,其中 k 由用户指定。

    对 ORB 描述子使用蛮力匹配

    有一个 queryImage 和一个 trainImage,尝试使用特征匹配在 trainImage 中查找 queryImage。

    • 使用 ORB 描述符来匹配功能。

    • 接下来,我们使用 cv.NORM_HAMMING (因为我们使用的是 ORB)创建一个 BFMatcher 对象并且启用了 crossCheck 以获得更好的结果。

    • 然后我们使用 Matcher.match()方法在两个图像中获得最佳匹配。

    • 我们按照距离的升序对它们进行排序,以便最佳匹配(距离最小)出现在前面。然后画出前 合适 个匹配。

    import numpy as np
    import cv2 as cv
    import matplotlib.pyplot as plt## 图片下载地址:
    ## https://github.com/opencv/opencv/blob/master/samples/data/box.png
    ## https://github.com/opencv/opencv/blob/master/samples/data/box_in_scene.pngimg1 = cv.imread('c:/Users/HP/Downloads/box.png',0)          # queryImage
    img2 = cv.imread('c:/Users/HP/Downloads/box_in_scene.png',0) # trainImage# Initiate ORB detector
    orb = cv.ORB_create()
    # find the keypoints and descriptors with ORB
    kp1, des1 = orb.detectAndCompute(img1,None)
    kp2, des2 = orb.detectAndCompute(img2,None)# create BFMatcher object
    bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
    # Match descriptors.
    matches = bf.match(des1,des2)
    # Sort them in the order of their distance.
    matches = sorted(matches, key = lambda x:x.distance)# Draw first x matches.
    img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:20], None, flags=2)  # 前20个匹配
    plt.imshow(img3)
    plt.axis('off') 
    plt.show()
    

    在这里插入图片描述

    这个匹配器对象是什么?

    matches = bf.match(des1,des2)的结果是 DMatch 对象的列表。此 DMatch 对象具有以下属性:

    • DMatch.distance - 描述子之间的距离。越低越好。
    • DMatch.trainIdx - 目标图像中描述子的索引
    • DMatch.queryIdx - 查询图像中描述子的索引
    • DMatch.imgIdx - 目标图像的索引。

    对 SIFT 描述符进行蛮力匹配和比率测试

    同样由于版本问题不可用,暂且略过;

    // https://github.com/opencv/opencv/wiki/ChangeLog#version4100

  • SIFT and SURF have been moved to a separate module named nonfree to indicate possible legal issues of using those algorithms in user applications. Also, SIFT performance has been substantially improved (by factor of 3-4x).

  • 基于 FLANN 的匹配器

    FLANN 代表快速最近邻搜索包(Fast Library for Approximate Nearest Neighbors)。

    它包含一系列算法,这些算法针对大型数据集中的快速最近邻搜索和高维特征进行了优化。对于大型数据集,它比 BFMatcher 工作得更快。

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img1 = cv.imread('c:/Users/HP/Downloads/box.png',0)          # queryImage
    img2 = cv.imread('c:/Users/HP/Downloads/box_in_scene.png',0) # trainImage# Initiate ORB detector
    orb = cv.ORB_create()
    # find the keypoints and descriptors with SIFT
    kp1, des1 = orb.detectAndCompute(img1,None)
    kp2, des2 = orb.detectAndCompute(img2,None)# FLANN parameters
    # FLANN_INDEX_KDTREE = 1
    # index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
    FLANN_INDEX_LSH = 6
    index_params= dict(algorithm = FLANN_INDEX_LSH,table_number = 6, # 12key_size = 12, # 20multi_probe_level = 1) #2
    #### 注意这里参数和SIFT不同search_params = dict(checks=50)   # or pass empty dictionary
    flann = cv.FlannBasedMatcher(index_params,search_params)
    matches = flann.knnMatch(des1,des2,k=2)# Need to draw only good matches, so create a mask
    matchesMask = [[0,0] for i in range(len(matches))]
    # ratio test as per Lowe's paper
    for i,(m,n) in enumerate(matches):if m.distance < 0.7*n.distance:matchesMask[i]=[1,0]
    draw_params = dict(matchColor = (0,255,0),singlePointColor = (255,0,0),matchesMask = matchesMask,flags = 0)img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)
    plt.imshow(img3,)
    plt.axis('off') 
    plt.show()

    在这里插入图片描述

    特征匹配+单应性查找对象

    • 使用来自 calib3d 模块的函数,即 cv.findHomography() 。如果将两个图像中的特征点集传递给这个函数,它将找到该对象的透视变换。

    • 然后我们可以使用 cv.perspectiveTransform() 来查找对象。它需要至少四个正确的点来找到这种变换。

    • 使用 RANSAC 或 LEAST_MEDIAN(可以由标志位决定)。因此,提供正确估计的良好匹配称为内点,剩余称为外点。 cv.findHomography() 返回一个指定了内点和外点的掩模。

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt#### 首先,在图像中找到 ORB 特征并应用比率测试来找到最佳匹配。MIN_MATCH_COUNT = 10img1 = cv.imread('c:/Users/HP/Downloads/box.png',0)          # queryImage
    img2 = cv.imread('c:/Users/HP/Downloads/box_in_scene.png',0) # trainImage# Initiate ORB detector
    orb = cv.ORB_create()
    # find the keypoints and descriptors with SIFT
    kp1, des1 = orb.detectAndCompute(img1,None)
    kp2, des2 = orb.detectAndCompute(img2,None)# FLANN parameters
    # FLANN_INDEX_KDTREE = 1
    # index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
    FLANN_INDEX_LSH = 6
    index_params= dict(algorithm = FLANN_INDEX_LSH,table_number = 6, # 12key_size = 12, # 20multi_probe_level = 1) #2
    #### 注意这里参数和SIFT不同search_params = dict(checks = 50)
    flann = cv.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1,des2,k=2)
    # store all the good matches as per Lowe's ratio test.
    good = []
    for m,n in matches:if m.distance < 0.7*n.distance:good.append(m)#### 现在设置至少 10 个匹配(由 MIN_MATCH_COUNT 定义)时才查找目标对象。否则只显示一条消息,说明没有足够的匹配。
    #    如果找到足够的匹配则提取两个图像中匹配的特征点的位置,传入函数中以找到透视变换。
    #    用这个 3x3 变换矩阵将 queryImage 中的角点转换为 trainImage 中的对应点。然后绘制出来。if len(good)>MIN_MATCH_COUNT:src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC,5.0)matchesMask = mask.ravel().tolist()h,w= img1.shapepts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)dst = cv.perspectiveTransform(pts,M)img2 = cv.polylines(img2,[np.int32(dst)],True,255,3, cv.LINE_AA)
    else:print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) )matchesMask = None#### 最后,我们绘制内点(如果成功找到对象)或匹配特征点(如果失败)。draw_params = dict(matchColor = (0,255,0), # draw matches in green colorsinglePointColor = None,matchesMask = matchesMask, # draw only inliersflags = 2)
    img3 = cv.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
    plt.imshow(img3, 'gray')
    plt.axis('off') 
    plt.show()

    在这里插入图片描述

相关文章:

opencv_特征检测和描述

理解特征 寻找独特的特定模式或特定特征&#xff0c;可以轻松跟踪和比较。 拼图&#xff1a;在图像中搜索这些特征&#xff0c;找到它们&#xff0c;在其他图像中查找相同的特征并对齐它们。而已。 基本上&#xff0c;角被认为是图像中的好特征。 在本单元中&#xff0c;我…...

CID引流电商下的3C产品选品策略深度解析

​摘要&#xff1a;随着电商行业的迅猛发展和消费者需求的日益多样化&#xff0c;CID引流电商作为一种新兴的电商模式&#xff0c;逐渐受到了广泛关注。在这一模式下&#xff0c;3C产品作为高客单价、高技术含量的代表品类&#xff0c;其选品策略的制定显得尤为重要。本文将从多…...

DeepSORT(目标跟踪算法)中的状态向量与状态转移矩阵

DeepSORT&#xff08;目标跟踪算法&#xff09;中的状态向量与状态转移矩阵 flyfish 状态转移矩阵&#xff08;State Transition Matrix&#xff09;F的构造 这篇是一定要看的&#xff0c;拖到文章的最后部分&#xff0c;需要理解状态转移矩阵怎么来的&#xff0c;怎么是这个…...

李宏毅深度学习01——基本概念简介

视频链接 基本概念 Regression&#xff08;回归&#xff09;&#xff1a; 类似于填空 Classification&#xff08;分类&#xff09;&#xff1a; 类似于选择 Structure Learning&#xff08;机器学习&#xff09;&#xff1a; &#xff1f;&#xff1f; 机器学习找对应函数…...

TcpClient 服务器、客户端连接

TcpClient 服务器 TcpListener 搭建tcp服务器的类&#xff0c;基于socket套接字通信的 1 创建服务器对象 TcpListener server new TcpListener(IPAddress.Parse("127.0.0.1"), 3000); 2 开启服务器 设置最大连接数 server.Start(1000); 3 接收客户端的链接,只能…...

13大最佳工程项目管理系统软件盘点

国内外主流的13款工程项目管理系统软件&#xff1a;Worktile、中建软件、泛微建筑项目管理软件、LiquidPlanner、Wrike、建文软件、广联达、Microsoft Project、泛普软件、Procore、Buildertrend、Fieldwire、Autodesk Construction Cloud。 在快速变化的工程领域&#xff0c;有…...

SpringMVC:拦截器(Interceptor)

1. 简介 拦截器&#xff08;Interceptor&#xff09;类似于过滤器&#xff08;Filter&#xff09; Spring MVC的拦截器作用是在请求到达控制器之前或之后进行拦截&#xff0c;可以对请求和响应进行一些特定的处理。拦截器可以用于很多场景下&#xff1a; 1. 登录验证&#xf…...

【Python】selenium使用find_element时解决【NoSuchWindowException】问题的方法

NoSuchWindowException 是 Selenium WebDriver 中的一种异常&#xff0c;当尝试切换到一个不存在的窗口时&#xff0c;或者在尝试获取窗口句柄时窗口已经关闭或不存在&#xff0c;就会抛出这个异常。 以下是一些解决 NoSuchWindowException 的常见方法&#xff1a; 检查窗口是…...

PTA:7-188 水仙花数

作者 王秀秀 单位 山东交通学院 任务描述 本关任务&#xff1a;输出100到999之间的所有的“水仙花数”。所谓的“水仙花数”是指一个3位数&#xff0c;其各位数字立方和等于该数本身。 例如&#xff0c;153是一个水仙花数&#xff0c;因为 15313 53 33 提示 关键在于对一…...

HTML静态网页成品作业(HTML+CSS+JS)—— 美食企业曹氏鸭脖介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现 图片轮播切换&#xff0c;共有4个页面。 二、…...

SCI二区|鲸鱼优化算法(WOA)原理及实现【附完整Matlab代码】

目录 1.背景2.算法原理2.1算法思想 3.结果展示4.参考文献5.代码获取 1.背景 2016年&#xff0c;S Mirjalili受到自然界座头鲸社会行为启发&#xff0c;提出了鲸鱼优化算法&#xff08;Whale Optimization Algorithm, WOA&#xff09;。 2.算法原理 WOA模拟了座头鲸的社会行为…...

人脸匹配——OpenCV

人脸匹配 导入所需的库加载dlib的人脸识别模型和面部检测器读取图片并转换为灰度图比较两张人脸选择图片并显示结果比较图片创建GUI界面运行GUI主循环运行显示全部代码 导入所需的库 cv2&#xff1a;OpenCV库&#xff0c;用于图像处理。 dlib&#xff1a;一个机器学习库&#x…...

韩顺平0基础学java——第22天

p441-459 异常exception 选中代码块&#xff0c;快捷键ctraltt6&#xff0c;即trt-catch 如果进行了异常处理&#xff0c;那么即使出现了异常&#xff0c;但是会继续执行 程序过程中发生的异常事件分为两大类&#xff1a; 异常体系图※ 常见的运行异常&#xff1a;类型转换…...

神经网络介绍及教程案例

神经网络介绍及教程&案例 神经网络&#xff08;Neural Networks&#xff09;是机器学习和人工智能中的一种关键技术&#xff0c;模仿了人类大脑的工作方式&#xff0c;能够处理复杂的数据和任务。以下是神经网络的一些基础介绍&#xff1a; 基本概念 神经元&#xff08;N…...

16个不为人知的资源网站,强烈建议收藏!

整理了16个不为人知的资源网站&#xff0c;涵盖了课程学习、办公技能、娱乐休闲、小说音乐等多种资源&#xff0c;强烈建议收藏&#xff01; #学习网站 1、中国大学MOOC icourse163.org/ 这是一个汇集了国内顶尖大学免费课程资源的平台&#xff0c;众多985工程院校如北京大…...

pandas获取某列最大值的所有数据

第一种方法&#xff1a; 按照某列进行由大到小的排序&#xff0c;然后再进去去重&#xff0c;保留第一个值&#xff0c;最终保留的结果就是最大值的数据 # 由大到小排序 data_frame data_frame.sort_values(bycolumn_a, ascendingFalse)# 按照column_b列去重保留第一条&#…...

App UI 风格展现非凡创意

App UI 风格展现非凡创意...

rocketmq-5.1.2的dleger高可用集群部署

1、背景 原先为5.0.0版本&#xff0c;因检查出有漏洞&#xff0c;升级到5.1.2版本。 【Rocketmq是阿里巴巴在2012年开发的分布式消息中间件&#xff0c;专为万亿级超大规模的消息处理而设计&#xff0c;具有高吞吐量、低延迟、海量堆积、顺序收发等特点。在一定条件下&#xf…...

无线网络与物联网技术[1]之近距离无线通信技术

无线网络与物联网技术 近距离无线通信技术WIFIWi-Fi的协议标准Wi-Fi的信道Wi-Fi技术的术语Wi-Fi的组网技术Ad-hoc模式无线接入点-APAP&#xff1a;FAT AP vs FIT AP Wi-Fi的特点与应用Wi-Fi的安全技术 Bluetooth蓝牙技术概论蓝牙的技术协议蓝牙的组网技术微微网piconet(了解)散…...

Codeforces Round 952 (Div. 4)

题解写到博客园了&#xff0c;懒得复制过来了了&#xff0c;放个链接 https://www.cnblogs.com/yxcblogs/p/18243276 推广一下自己记录的算法编程竞赛模板仓库 GitHub - yxc-s/programming-template: This repository contains C programming templates optimized for competi…...

spark MLlib (DataFrame-based) 中的聚类算法Bisecting K-Means、K-Means、Gaussian Mixture

Bisecting K-Means 核心原理&#xff1a; Bisecting K-Means 是一种层次 K-Means 聚类算法&#xff0c;基于 Steinbach、Karypis 和 Kumar 的论文《A comparison of document clustering techniques》&#xff0c;并对 Spark 环境进行了修改和适应。 该算法通过递归地将数据集…...

天降流量于雀巢?元老品牌如何创新营销策略焕新生

大家最近有看到“南京阿姨手冲咖啡”的视频吗&#xff1f;三条雀巢速溶咖啡入杯&#xff0c;当面加水手冲&#xff0c;十元一份售出&#xff0c;如此朴实的售卖方式迅速在网络上走红。而面对这一波天降的热度&#xff0c;雀巢咖啡迅速做出了回应&#xff0c;品牌组特地去到了阿…...

新疆在线测宽仪配套软件实现的9大功能!

在线测宽仪可应用于各种热轧、冷轧板带材的宽度尺寸检测&#xff0c;材质不限&#xff0c;木质、钢制、铁质、金属、纸质、塑料、橡胶等都可以进行无损非接触式的检测&#xff0c;在各式各样的产线应用中&#xff0c;有些厂家&#xff0c;需要更加详尽完备的分析信息&#xff0…...

考研计组chap3存储系统

目录 一、存储器的基本概念 80 1.按照层次结构 2.按照各种分类 &#xff08;41&#xff09;存储介质 &#xff08;2&#xff09;存取方式 &#xff08;3&#xff09;内存是否可更改 &#xff08;4&#xff09;信息的可保存性 &#xff08;5&#xff09;读出之后data是否…...

杨氏矩阵和杨辉三角的空间复杂度较小的解题思路

文章目录 题目1 杨氏矩阵题目2 杨辉三角 题目1 杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 思路: 我们可以通过题目…...

【第六篇】SpringSecurity的权限管理

一、权限管理的实现 服务端的各种资源要被SpringSecurity的权限管理控制可以通过注解和标签两种方式来处理。 放开了相关的注解后在Controller中就可以使用相关的注解来控制了 JSR250注解 /*** JSR250*/ @Controller @RequestMapping("/user") public class UserC…...

未来工作场所:数字化转型的无限可能

探索技术如何重塑我们的工作环境与协作方式 引言 在21世纪的第三个十年&#xff0c;数字化转型已不再仅仅是科技公司的专利&#xff0c;它如同一股不可阻挡的潮流&#xff0c;深刻地渗透到了每一个行业的血脉之中。从灵活的远程办公模式到工作流程的智能化重构&#xff0c;技术…...

Landsat8的质量评估波段的一个应用

Landsat8一直是遥感界的热门话题。这不仅延续了自1972年以来NASA连续对地观测&#xff0c;而且这颗卫星为科学界带来了一些新的东西——质量评估波段&#xff08;the Quality Assessment (QA) Band&#xff09;。根据USGS Landsat Missions webpage&#xff0c;“QA通过标示哪个…...

OpenZeppelin Ownable合约 怎么使用

文章目录 智能合约的访问控制Ownable合约使用方法 智能合约的访问控制 熟悉OpenZeppelin的智能合约库的开发者都知道这个库已经提供了根据访问等级进行访问限制的选项&#xff0c;其中最常见的就是Ownable合约管理的onlyOwner模式&#xff0c;另一个是OpenZeppelin的Roles库&a…...

vue3框架基本使用(基础指令)

一、响应式数据 1.ref ref可以定义 基本类型的响应式数据&#xff0c; 也可以定义对象类型响应式数据 <template><h1>{{ name }}</h1><button click"test">修改姓名</button> </template><script setup lang"ts"…...

建设银行网站 购买外汇/百度seo多久能优化关键词

Python入门简单、功能强大&#xff0c;吸引了很多人的学习加入。无论是自学还是参加培训班&#xff0c;根据人们对知识的接受程度&#xff0c;最开始学习的一定是Python语法&#xff0c;今天千锋郑州老师就给大家分享一下Python基础学习教程中语法的知识点。1、行和缩进Python最…...

wordpress 视频展示/网站关键词如何优化上首页

1.存储结构&#xff1a;数据库database 表table 数据data;2.SQL(Structured Query Language&#xff0c;结构化查询语言)语言&#xff1a;和数据库交互的语言&#xff0c;进行数据库管理的语言。库的操作3.查询所有数据库&#xff1a;show databases;4.创建数据库 create …...

班级网站怎么做ppt/郑州seo优化顾问热狗

本文为大家分享了virtualenv建立多个Python独立虚拟开发环境&#xff0c;供大家参考&#xff0c;具体内容如下1、安装virtualenv&#xff1a;pip install virtualenv2、创建一个python的虚拟环境&#xff1a;virtualenv test_demo用virtualenv创建虚拟环境&#xff0c;是通过复…...

局网站建设方案word/九易建网站的建站流程

如何在项目中引入 framework 源代码 我们需要在项目中以源代码的方式引入 framewwork&#xff0c;是方便我们对框架进行修改。当 framework 构建出来以后&#xff0c;可以通过 Cocoapods 或者 .a 文件的方式引入到我们的项目中。但是如果这个框架需要在项目中进行修改、升级或…...

做网站的公司不给域名/百度搜索引擎

JDBC核心技术一、什么JDBC&#xff1f;(一). JDBC简介二、获取数据库连接(一). Driver接口实现类1.如何安装MySql驱动(二).JDBC URL(三).用户名和密码(四).数据库连接方式举例三、使用PreparedStatement实现CRUD操作(一).PreparedStatement的使用1.PreparedStatement介绍2.Prep…...

自己做企业网站详细流程免费/seo关键词优化排名哪家好

用于指数爆longlong的情况&#xff0c;当然你也可以打高精…… 因为昨天有人提到了慢速乘&#xff0c;感觉挺有用的&#xff0c;就顺便都学了吧&#xff0c;而且省选也用到十进制快速幂了。 #include<iostream> #include<cstring> #include<cstdio> #define …...