我想写一个工具来寻找图像中每个有界对象内的Angular 、曲线和直线的数量.

如图所示,对于每个有界区域,将记录每个形状出现.最好能够设定一个阈值,将曲线的弯曲度视为曲线而非Angular 等,直线和Angular 也是如此.

我曾使用Hough线变换检测其他图像上的直线,它可能与我认为的某些东西结合使用.

我对opencv以外的其他库开放——这正是我的一些经验.

提前谢谢

IMAGE: Occurences of shape in the letters

编辑:

它会产生一个输入"k"的比较复杂的结果,在这里它正确地识别了Angular 周围的一些点,但是"腿"(下对角线部分)上有很多点.我不确定如何将其分割成直线、Angular 和曲线.

代码:

import numpy as np

img = cv2.imread('Helvetica-K.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
edges = cv2.Canny(blurred, 50, 150, apertureSize=3)
ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(img, contours, 0, (0,255,0), 1)

#Coordinates of each contour
for i in range(len(contours[0])):
    print(contours[0][i][0][0])
    print(contours[0][i][0][1])
    cv2.circle(img, (contours[0][i][0][0], contours[0][i][0][1]), 2, (0,0,255), -1)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Img example: K-helvitica

推荐答案

您可以将findContours与选项CHAIN_APPROX_SIMPLE一起使用.

  • Angular 小于某个阈值的点是角点.
  • Angular 大于某个阈值的点位于直线上,应删除.
  • 距离超过某个阈值的两个相邻点是直线的端点.
  • 被识别为角的两个相邻点是直线的端点.
  • 所有其他点都属于曲线细节.

Update:

下面是一些代码,你可以从中开始.它展示了如何平滑直线,如何将多个角点合并为一个,以及如何计算每个点的距离和Angular .为了达到要求的结果,你们还有一些工作要做,但我希望它朝着正确的方向发展.

import numpy as np
import numpy.linalg as la
import cv2


def get_angle(p1, p2, p3):
    v1 = np.subtract(p2, p1)
    v2 = np.subtract(p2, p3)
    cos = np.inner(v1, v2) / la.norm(v1) / la.norm(v2)
    rad = np.arccos(np.clip(cos, -1.0, 1.0))
    return np.rad2deg(rad)


def get_angles(p, d):
    n = len(p)
    return [(p[i], get_angle(p[(i-d) % n], p[i], p[(i+d) % n])) for i in range(n)]


def remove_straight(p):
    angles = get_angles(p, 2)                     # approximate angles at points (two steps in path)
    return [p for (p, a) in angles if a < 170]    # remove points with almost straight angles


def max_corner(p):
    angles = get_angles(p, 1)                     # get angles at points
    j = 0

    while j < len(angles):                        # for each point
        k = (j + 1) % len(angles)                 # and its successor
        (pj, aj) = angles[j]
        (pk, ak) = angles[k]

        if la.norm(np.subtract(pj, pk)) <= 4:     # if points are close
            if aj > ak:                           # remove point with greater angle
                angles.pop(j)
            else:
                angles.pop(k)
        else:
            j += 1

    return [p for (p, a) in angles]


def main():
    img = cv2.imread('abc.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)

    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:                  # for each contour
        pts = [v[0] for v in c]         # get pts from contour
        pts = remove_straight(pts)      # remove almost straight angles
        pts = max_corner(pts)           # remove nearby points with greater angle
        angles = get_angles(pts, 1)     # get angles at points

        # draw result
        for (p, a) in angles:
            if a < 120:
                cv2.circle(img, p, 3, (0, 0, 255), -1)
            else:
                cv2.circle(img, p, 3, (0, 255, 0), -1)

    cv2.imwrite('out.png', img)
    cv2.destroyAllWindows()


main()

enter image description here

Python相关问答推荐

合并其中一个具有重叠范围的两个框架的最佳方法是什么?

CustomTKinter-向表单添加额外的输入字段

两极:如何分割一个大 pyramid 并并行保存每个

覆盖Django rest响应,仅返回PK

Python -Polars库中的滚动索引?

Python plt.text中重叠,包adjust_text不起作用,如何修复?

对某些列的总数进行民意调查,但不单独列出每列

try 在树叶 map 上应用覆盖磁贴

如何根据参数推断对象的返回类型?

如何获取TFIDF Transformer中的值?

如何将Docker内部运行的mariadb与主机上Docker外部运行的Python脚本连接起来

pyscript中的压痕问题

将tdqm与cx.Oracle查询集成

如何使用scipy的curve_fit与约束,其中拟合的曲线总是在观测值之下?

考虑到同一天和前2天的前2个数值,如何估算电力时间序列数据中的缺失值?

Maya Python脚本将纹理应用于所有对象,而不是选定对象

寻找Regex模式返回与我当前函数类似的结果

PYTHON、VLC、RTSP.屏幕截图不起作用

为什么我的sundaram筛这么低效

用两个字符串构建回文