算法部分---角点检测

 

文章目录

  • 摘要
  • 哈尔角点检测
    • 1. 原理
    • 2. 公式推导
    • 3. 存在问题
  • 拟合外接矩形求角点
    • 1. 钝角
    • 2. 直角
    • 3. 锐角
  • 检测的例子
    • 1. 获取轮廓,求外接矩形
    • 2. 角点的排序
  • 总结

 


摘要

角点在三维场景重建运动估计,目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着非常重要的作用。在现实世界中,角点对应于物体的拐角,道路的十字路口、丁字路口等。在近几个项目中,通过获取的角点,多用于透视变换。

一、哈尔角点检测

1. 原理

根据角点的定义,可以分为如下两类:角点可以是两个边缘的角点,邻域内具有两个主方向的特征点。前者很大程度上依赖于图像的分割与边缘提取,具有相当大的难度和计算量。 第二种如Harris角点的检测。如果在各个方向上移动这个widow,

区域内的灰度发生较大的变化,就认为遇到了角点。

2. 公式推导

周围灰度变化的自相关函数如下:

进行泰勒展开如下,其中Ο(u2,v2)近似为0:

矩阵M又称Harris矩阵:

在不同方向的展示如下:

    a. 图像中的直线。一个特征值大,另一个特征值小,λ1>λ2或λ2>λ1。自相关函数值在某一方向上大,在其他方向上小。

    b. 图像中的平面。两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。

    c. 图像中的角点。两个特征值都大,且近似相等,自相关函数在所有方向都增大。

3. 存在问题

实际的烟盒不完全是直角,导致角点检测出现偏离。


 

二、拟合外接矩形求角点

相机拍摄的图像如下所示,在绿框中寻找角点的位置。

1. 钝角

先求出初始的外接矩形,如下所示。

再在该初始的外接矩形进行图像的取反,再次进行外接矩形的拟合,输出对应位置的矩形点。

2. 直角

寻找最小外接矩形,进行角点的排序,从而求得对应位置的角定。

3. 锐角

用findRect在二值化的cornerRoi图像上求外接矩形,再对该矩形的四个点进行排序,烟盒左下方的角点是对应拟合矩形的左下方角点,烟盒右下方的角点是对应拟合矩形的右下方角点。

 

三、检测例子

1. 获取轮廓,求外接矩形。

#近似边缘求角点point
def getSubCornerPoint(binImg, posFlag):
    #寻找近似的轮廓
    resContourFlag, approxContour = findApproxContour(binImg, posFlag)
    if resContourFlag ==False:
        return False, [], []
    #轮廓的外接矩形
    boxPoints = getBoundRect(approxContour)
    #角点排序
    sortBoxPoints = sortPoints(boxReverPoints)
    #获取对应位置的point
    resPoint = getPosSortPoint(sortBoxPoints, posFlag)

#寻找近似的轮廓
def findApproxContour(binImg, posFlag):
    allContours, _ = cv2.findContours(binImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if len(allContours) ==0:
        print("@ error findApproxContour not find the contour pos: ", posFlag)
        return False, []
    #计算轮廓面积,将最大的那组轮廓挑出来
    contour = sorted(allContours, key=cv2.contourArea, reverse=True)[0]
    lengthEps = 0.015  #轮廓边长的近似
    contourMinArea = (binImg.shape[0])*(binImg.shape[1])*fourCornerBinImgRation
    contourArea = cv2.contourArea(contour)
    if (contourArea > contourMinArea):
        epsilon = lengthEps * cv2.arcLength(contour, True)  #精度的近似
        approx = cv2.approxPolyDP(contour, epsilon, True)   #轮廓的近似
        return True, approx
    else:
        print("@ failed findApproxContour not ok area contour pos: ", posFlag)
        return False, []

#轮廓求外接矩形  返回tl, tr, bl, br
def getBoundRect(approxContour):  
    x,y,w,h = cv2.boundingRect(approxContour) #外接矩形
    boxPoints = np.array([[x, y], [x+w, y], [x, y+h], [x+w, y+h]])
    return boxPoints

2. 角点的排序

#位置点的排序 tl, tr, bl, br
def sortPoints(pts):
    xSorted = pts[np.argsort(pts[:, 0]), :]
    leftMost = xSorted[:2,:]
    rightMost = xSorted[2:,:]
    leftMost = leftMost[np.argsort(leftMost[:, 1]),:]  #np.argsort返回坐标的index
    (tl, bl) = leftMost
    rightMost = rightMost[np.argsort(rightMost[:, 1]), :]#y坐标偏上的是top
    (tr, br) = rightMost
    return np.array([tl, tr, bl, br], dtype=int)

 


总结

自带的角点检测方法,稳定行不高。可以采用外接矩形的求对应位置的角点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值