gpt4 book ai didi

python - 使用opencv检测图像中折线的顶点

转载 作者:行者123 更新时间:2023-12-02 17:07:08 38 4
gpt4 key购买 nike

我有一些灰度图像,如下所示:

grayscale chart

它们是具有不同标记样式的灰度线形图(可以是正方形,圆形,星形,点形。等等)。

我想获取标记的坐标。我计划将数据线读取为多段线,并使用角点检测算法检测顶点,但是从我一直以来的 Angular 来看,角点检测更适合3D空间。

我的问题是:是否可以将折线图读取为折线图并提取顶点的坐标?有没有办法使用霍夫变换来使用opencv检测折线?

提前致谢

编辑

原始图像如下:

orignal

最佳答案

这个怎么样?

提取行

import numpy as np
import cv2

img = cv2.imread('origin.png')

## 1. choose HSV
# rough hsv values in this image.
# grid(gray)=(0, 0, 174)
# border(black)=(0, 0, 15)
# back ground(white)=(0, 0, 254)

# hsv value including border and back ground
hsv_min = (0, 0, 0) # Lower end of the HSV range
hsv_max = (10, 10, 255) # Upper end of the HSV range

# Transform image to HSV color space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Threshold based on HSV values
color_thresh = cv2.inRange(hsv, hsv_min, hsv_max)

# Invert the image
invert = cv2.bitwise_not(color_thresh)

## If you need perform skeletonization, use skimage.
#import skimage
#from skimage.morphology import skeletonize
#color_thresh = skeletonize(skimage.img_as_float(color_thresh))
#color_thresh = color_thresh.astype('uint8') * 255

cv2.imwrite("lines.png", invert)

lines.png
enter image description here
## 2. cv2.HoughLinesP
# Actually, parameter tuning will be necessary

minLineLength = 100
maxLineGap = 100
lines = cv2.HoughLinesP(color_thresh, 2, np.pi/180,70,minLineLength,maxLineGap)
# lines = [[[319 321 431 188]], ... ,[[ 83 283 195 399]]]

lines = [x.flatten() for x in lines]
# lines = [[319, 321, 431, 188], ... ,[ 83, 283, 195, 399]]

# sort by first element
lines = sorted(lines, key=lambda x : x[0])

# drow lines
for line in lines:
x1,y1,x2,y2 = line
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)


## 3. Find the intersection of two lines
def cross_point(segment_p1p2, segment_p3p4):
'''
Intersection point of two lines
p1p2:{p1(a,b)、p2(c,d)}
p3p4:{p3(e,f)、p4(g,h)}
'''
a = segment_p1p2[0]
b = segment_p1p2[1]
c = segment_p1p2[2]
d = segment_p1p2[3]
e = segment_p3p4[0]
f = segment_p3p4[1]
g = segment_p3p4[2]
h = segment_p3p4[3]

dev = (d-b)*(g-e)-(c-a)*(h-f)
d1 = f*g-e*h
d2 = b*c-a*d

xp = (d1*(c-a)-d2*(g-e))/dev
yp = (d1*(d-b)-d2*(h-f))/dev
return (xp, yp)

# draw circles
for i in range(len(lines)-1):
x, y = cross_point(lines[i], lines[i+1])
cv2.circle(img,(int(x),int(y)), 5, (255,0,0), 2)

cv2.imwrite("out.png",img)

out.png
enter image description here

[附录]
HoughLinesP可能返回多条重叠的线。
在这种情况下,最好进行以下处理。
# [81, 281, 201, 406] and [81, 279, 198, 400] are overlapping
# [435, 184, 557, 214] and [451, 187, 558, 213] are overlapping
lines = [[81, 281, 201, 406],
[81, 279, 198, 400],
[193, 405, 313, 327],
[312, 329, 437, 180],
[435, 184, 557, 214],
[451, 187, 558, 213]]

import math

def is_close(data1, data2, threshold=10):
'''
e.g. data1=[x, y] , data1=[x, y, z]
`threshold` is euclidean distance.
calculate the distance between two points, and determine if they are in the neighborhood.
'''
return math.sqrt(sum((d1-d2)**2 for d1, d2 in zip(data1, data2))) < threshold

# sort by first element
lines = sorted(lines, key=lambda x : x[0])

chained_lines=[lines[0]]
index=0
for i in range(len(lines)):
if i < index:
continue
end_of_line = lines[i][-2:]
# generator which return the index of the chained elements
y = (i for i, v in enumerate(lines) if is_close(end_of_line, v[:2]))
# get the index of the first element
chained_index = next(y, None)
if chained_index != None and chained_index > index:
index = chained_index
chained_lines.append(lines[index])

print(chained_lines)

链线
[[81,281,201,406],[193,405,313,327],[312,329,437,180],[435,184,557,214]]

提取边界
import numpy as np
import cv2

img = cv2.imread('origin.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, bin_img = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY_INV)

minLineLength = 100
maxLineGap = 100
lines = cv2.HoughLinesP(bin_img, 2, np.pi/180,70,minLineLength,maxLineGap)

lines = [x.flatten() for x in lines]

# drow lines
for line in lines:
x1,y1,x2,y2 = line
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imwrite("out2.png",img)

out2.png
enter image description here

关于python - 使用opencv检测图像中折线的顶点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52017123/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com