【OpenCV】56 二值图像分析–直线拟合与极值点寻找

56 二值图像分析–直线拟合与极值点寻找

代码

import cv2 as cv
import numpy as np

def canny_demo(image):
    t = 80
    canny_output = cv.Canny(image, t, t * 2)
    return canny_output

src = cv.imread("../images/twolines.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)

binary = canny_demo(src)
k = np.ones((3, 3), dtype=np.uint8)
binary = cv.morphologyEx(binary, cv.MORPH_DILATE, k)
cv.imshow("binary", binary)

# 轮廓发现
contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

# 直线拟合与极值点寻找
for c in range(len(contours)):
    x, y, w, h = cv.boundingRect(contours[c])
    m = max(w, h)
    if m < 30:
        continue
    vx, vy, x0, y0 = cv.fitLine(contours[c], cv.DIST_L1, 0, 0.01, 0.01)
    k = vy/vx
    b = y0 - k*x0
    maxx = 0
    maxy = 0
    miny = 100000
    minx = 0
    for pt in contours[c]:
        px, py = pt[0]
        if maxy < py:
            maxy = py
        if miny > py:
            miny = py
    maxx = (maxy - b) / k
    minx = (miny - b) / k
    cv.line(src, (np.int32(maxx), np.int32(maxy)),
            (np.int32(minx), np.int32(miny)), (0, 0, 255), 2, 8, 0)

# 显示
cv.imshow("contours_analysis", src)
cv.waitKey(0)
cv.destroyAllWindows()

实验结果

【OpenCV】56 二值图像分析–直线拟合与极值点寻找_第1张图片

解释

对轮廓进行分析,除了可以对轮廓进行椭圆或者圆的拟合之外,还可以对轮廓点集进行直线拟合,直线拟合的算法有很多,最常见的就是最小二乘法,对于多约束线性方程,最小二乘可以找好直线方程的两个参数、实现直线拟合,OpenCV中直线拟合正是基于最小二乘法实现的。OpenCV实现直线拟合的API如下:

line = cv.fitLine(points, distType, param, reps, aeps[, line])
  • points表示待拟合的输入点集合
  • distType表示在拟合时候使用距离计算公式是哪一种,OpenCV支持如下六种方式:
    • DIST_L1 = 1
    • DIST_L2 = 2
    • DIST_L12 = 4
    • DIST_FAIR = 5
    • DIST_WELSCH = 6
    • DIST_HUBER = 7
  • param对模型拟合距离计算公式需要参数C,5~7
  • distType需要参数C
  • repsaeps是指对拟合结果的精度要求
  • line在二维拟合时候输出的是vec4f类型的数据,在三维拟合的时候输出是vec6f的vector

所有内容均来源于贾志刚老师的知识星球——OpenCV研习社,本文为个人整理学习,已获得贾老师授权,有兴趣、有能力的可以加入贾老师的知识星球进行深入学习。
在这里插入图片描述

你可能感兴趣的:(OpenCV)