opencv矩形轮廓顶点的具体位置确定

这篇具有很好参考价值的文章主要介绍了opencv矩形轮廓顶点的具体位置确定。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题的引入

opencv在图像处理方面有着非常强大的功能,当我们需要使用opencv进行一些图像的矫正工作时,我们通常需要找到原图的一些关键点,然后计算变换后的图像坐标,最后通过仿射变换或者透视变换获得自己想要的矫正图像,比如将一张拍歪了的纸进行矫正,我们的首要任务就是找到原图的一些关键点,通常的做法就是找纸张的4个顶点。

二、问题的解决方法

第一步我们肯定要找到纸张相应的矩形轮廓,这里可以二值化再找,也可以使用一些算子查找,而本文的重点是解决怎样根据矩形轮廓去确定它具体的4个顶点的位置。

方法一:

使用线性规划的方法,在opencv的坐标系下使用x+y=z1和x-y=z2两条直线去切轮廓,分别当z1取最大时(x,y)是右下点,最小时是左上点;当z2取最大时(x,y)是右上点,最小时是左下点,如下图:
opencv 顶点检测,python,计算机视觉,opencv,计算机视觉,python
这个方法单独从轮廓的角度来说,只要旋转的角度不要刚刚好是45°或者135°,这个方法就没有问题,它得到的就是轮廓相对应的右下点、左上点、右上点、左下点,但不是原目标的相应点,就好像当纸张旋转超过45°时,这个方法得到的对于轮廓来说是正确的,但对于纸张来说就不对了,如下图:
opencv 顶点检测,python,计算机视觉,opencv,计算机视觉,python
这个时候如果按之前的一样进行矫正就会得到一个横放的纸张,这样里面的字都是横的,就不是我们想要的了所以这个方法要用来矫正的话,就需要对图像的旋转角度有一个计算和判断,可以通过下面代码获取角度:

#cnt:输入轮廓,angle:返回角度
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)

方法二

这个方法首先要使用轮廓获得其最小面积矩,然后观察研究矩形的性质可以根据当前的形状给出适合的x,y判断式,观察下图:
opencv 顶点检测,python,计算机视觉,opencv,计算机视觉,python

#找轮廓最小矩 cnt:轮廓  box:4个点无规律
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)

对于这样一个高比宽长的矩形,我们的方法是先将4个点按y从小到大进行排序,再取前两个按x从小到大进行排序,小的那个是左下,大的那个是右下;最后取后两个也按x从小到大进行排序,小的那个是左上,大的那个是右上。假如是一个宽比高长的矩形,我们就可以先按x的大小进行排序。这个从代码角度实现可能更为简洁,适用特定轮廓,对角度要求就更宽泛了些,除非旋转到了像上图右边一样的状况,而这种矫正一般出现的机率非常小。

三、一些实现代码

1、下面是使用方法一实现的顶点定位

import numpy as np
import cv2
def get4points(img: np.ndarray, thed, n):
    """
    :param img  the color image which shape is [height, width, depth]
    :return 4 point locations in list or tuple, for example: [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
    """

    #灰度和二值化
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray,thed,255,cv2.THRESH_BINARY)

    # 搜索轮廓
    contours, hierarchy = cv2.findContours(
        binary,
        cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)

    #按轮廓长度选取需要轮廓
    len_list = []
    for i in range(len(contours)):
        len_list.append(len(contours[i]))

    #选第二长的
    sy = np.argsort(np.array(len_list))[-n]

    #寻找顶点
    sum_list = []
    dif_list = []
    for i in contours[sy]:
        sum = i[0][0]+i[0][1]
        sum_list.append(sum)
        dif_list.append(i[0][0]-i[0][1])

    id_lb = np.argsort(np.array(sum_list))
    id_lb2 = np.argsort(np.array(dif_list))
    lu_id , rd_id = id_lb[0] , id_lb[-1]
    ld_id , ru_id = id_lb2[0] , id_lb2[-1]

    points = np.array([contours[sy][lu_id][0],contours[sy][rd_id][0],contours[sy][ld_id][0],contours[sy][ru_id][0]])

    return points , contours , sy

2、下面是使用方法2实现的顶点定位

def getpoints(binary: np.ndarray  , num: int ):
    # 搜索轮廓
    contours, hierarchy = cv2.findContours(
        binary,
        cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)

    #按轮廓位置最左(x最小)选取
    x_list = []
    for i in contours:
        x_sum = 0
        for kk in i:
            x_sum += kk[0][0]
        x_av = x_sum/len(i)
        x_list.append(x_av)

    sy = np.argsort(np.array(x_list))[num]
    cnt = contours[sy]
    
    #找轮廓最小矩
    rect = cv2.minAreaRect(cnt)
    box = cv2.boxPoints(rect)

    return box , contours , sy

def findpoints(points):
    #区分矩形顶点位置
    point_y=sorted(points,key=lambda t:t[1])
    lu, ru =sorted(point_y[:2],key=lambda t:t[0])
    ld, rd =sorted(point_y[2:],key=lambda t:t[0])

    return [list(lu), list(ld), list(ru),list(rd)]

3、下面是一些展示代码文章来源地址https://www.toymoban.com/news/detail-677261.html


#展示顶点
def show_points(img , points):
    point_size = 8
    point_color = (0, 0, 255) # BGR
    thickness = 4 # 可以为 0 、4、8
    points_list = [tuple(i) for i in np.int32(points).reshape(-1,2)]
    for point in points_list:
        cv2.circle(img, point, point_size, point_color, thickness)
    img = cv2.resize(img,(808,808))
    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    # cv2.imwrite('dd.jpg',img)

#展示轮廓
def show_Contour(img , contours , sy):
    cv2.drawContours(img, contours , sy , (25, 254, 0), 4)
    img = cv2.resize(img,(808,808))
    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    # cv2.imwrite('mm.jpg',img)

到了这里,关于opencv矩形轮廓顶点的具体位置确定的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python】OpenCV-图像轮廓检测初学

    在图像处理领域中,轮廓检测是一项重要的任务,用于寻找并标定图像中的物体边缘。本文将介绍如何使用OpenCV库进行图像轮廓检测,并展示一个简单的示例代码。代码中的注释将详细解释每一步的操作。 图像轮廓检测是图像处理中的一项关键技术,可用于检测物体的形状、

    2024年02月21日
    浏览(47)
  • OpenCV(10): 轮廓近似—多边形拟合,边界矩形与边界圆形

    轮廓近似(Contour Approximation)是指对轮廓进行逼近或拟合,得到近似的轮廓。在图像处理中,轮廓表示了图像中物体的边界,因此轮廓近似可以用来描述和识别物体的形状。 多边形拟合(Approximating Polygons)是将轮廓逼近成一个由直线段构成的多边形。常见的有最小包围矩形

    2024年02月10日
    浏览(47)
  • OpenCV(三十四):轮廓外接最大、最小矩形和多边形拟合

    目录 1.轮廓外接最大矩形boundingRect() 2.轮廓外接最小矩形minAreaRect() 3.轮廓外接多边形approxPolyDP() 1.轮廓外接最大矩形boundingRect() Rect cv::boundingRect ( InputArray array ) array:输入的灰度图像或者2D点集,数据类型为vectorPoint或者Mat。 示例代码:  轮廓外接最大矩形的结果: 2.轮廓外接

    2024年02月09日
    浏览(73)
  • 【OpenCV-Python】——边缘和轮廓&Laplacian/Sobel/Canny边缘检测&查找/绘制轮廓及轮廓特征&霍夫直线/圆变换

    目录 前言: 1、边缘检测 1.1 Laplacian边缘检测  1.2 Sobel边缘检测  1.3 Canny边缘检测 2、图像轮廓 2.1 查找轮廓  2.2 绘制轮廓 2.3 轮廓特征 3、霍夫变换 3.1 霍夫直线变换  3.2 霍夫圆变换 总结: 图像的边缘是指图像中灰度值急剧变化的位置,边缘检测的目的是为了绘制边缘线条。

    2024年01月23日
    浏览(48)
  • opencv python 实现Canny检测后不连续不封闭轮廓的闭合

    Canny检测后轮廓的闭合在网上看了一些相关文章后总结出有以下方法: 1、 使用闭运算等形态学操作来对轮廓进行处理,但作为像素点级别 的形态学操作往往不能满足要求,如:两条轮廓线相距仅为一个像素,在进行闭运算操作时会使这两条轮廓粘连在一起。 2、 对于规则的

    2024年04月14日
    浏览(46)
  • opencv-python3 | cv2.findContours()检测图像中物体轮廓

    轮廓可以简单地理解为连接所有连续点(沿物体边界)的曲线,这些点通常具有相同的颜色或强度。 轮廓在图像分析中具有重要意义,是物体形状分析和对象检测和识别的有用工具,是理解图像语义信息的重要依据。 通常,为了提高物体轮廓检测的准确率,首先要将彩色图

    2024年02月05日
    浏览(50)
  • 已知中心点、长宽和旋转角度,求矩形的四个顶点坐标(Python)

    本次实现有几个前提: 已知的信息如下形式:[x_center, y_center, w, h, angle],其中默认 w w w 是矩形最长的边,即 w h w h w h 。 已知的旋转角度 θ theta θ 是矩形的最长边 w w w 相对于 x x x 坐标轴的旋转角度 旋转角度 θ theta θ 的旋转区间在 [ 0 , π ] [0, pi] [ 0 , π ] 可以将情况分为两

    2024年02月05日
    浏览(88)
  • OpenCV快速入门:目标检测——轮廓检测、轮廓的距、点集拟合和二维码检测

    在当今数字化时代,计算机视觉的崛起使得目标检测成为科技领域中的一项关键技术。本文将带您快速入门OpenCV中的目标检测,深入探讨轮廓检测、轮廓的距、点集拟合以及二维码检测等核心概念。 OpenCV,作为一种强大的开源计算机视觉库,为开发者提供了丰富的工具和算法

    2024年01月16日
    浏览(57)
  • 数字图像处理(实践篇)二十九 OpenCV-Python在图像中检测矩形、正方形和三角形的实践

    目录 1 方案 2 实践 1 方案 ①检测矩形和正方形 ⒈检测图像中的所有轮廓。 ⒉循环检查所有检测到的轮廓。 ⒊为每个轮廓找到近似的轮廓。如果近似轮廓中的顶点数为4,则计算 宽高比 用来区分 矩形 和 正方形 。如果宽高比在0.9到1.1之间,则认为为正方形,否则的话,则为

    2024年01月25日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包