Md.*_*que 1 python opencv numpy
我有一个如下所示的图像,我想从该图像中找到四个坐标(角)。
我尝试过以下代码:
# dilate thresholded image - merges top/bottom
kernel = np.ones((3,3), np.uint8)
dilated = cv2.dilate(img, kernel, iterations=3)
# Finding contours for the thresholded image
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Run Code Online (Sandbox Code Playgroud)
首先,我扩大了图像,使其填充散点部分,并尝试从那里找出轮廓。但它给了我错误的输出。我可以做什么来找出四个角坐标?
我通过将回归线扔到你的每一边并获取它们的拦截点来找到你的点。
首先,我导入内容并使用 open cv 找到轮廓点。
import numpy as np
import cv2
import matplotlib.pyplot as plt
from scipy.stats import linregress
from sympy import solve, symbols
import itertools
img = cv2.imread('ZrSqG.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshold, binarized_img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(binarized_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = (contours[1].reshape(-1,2)).T
Run Code Online (Sandbox Code Playgroud)
现在我得到了一些最上面、最左边的点,并把它们扔了一条线。然后我计算它们的截获并绘制所有图。
def interpolate_function(x,y):
line = interpolate(x,y)
return lambda x: x*line.slope+line.intercept
def interpolate(x,y):
idx = np.argsort(x)
line = linregress(x[idx], y[idx])
return line
def interception(line1, line2):
x = symbols('x')
x = solve(x*line1.slope+line1.intercept-(x*line2.slope+line2.intercept))[0]
return (x,x*line1[0]+line1[1])
idx_x = np.argsort(contours[0])
idx_y = np.argsort(contours[1])
left = [contours[0][idx_x[:30]], contours[1][idx_x[:30]]]
right = contours[0][idx_x[-10:]], contours[1][idx_x[-10:]]
top = contours[0][idx_y[:10]], contours[1][idx_y[:10]]
bottom = contours[0][idx_y[-30:]], contours[1][idx_y[-30:]]
contour_functions = [interpolate_function(*left), interpolate_function(*right),interpolate_function(*top), interpolate_function(*bottom)]
contour_function_eqs = [[interpolate(*left), interpolate(*right)],
[interpolate(*top), interpolate(*bottom)]]
for f in contour_functions:
t = np.linspace(0, img.shape[1], 10**4)
t = t[(0 < f(t)) & (f(t) < img.shape[0])]
plt.plot(t,f(t))
itersections = np.array([interception(line1, line2)
for line1, line2 in itertools.product(contour_function_eqs[0], contour_function_eqs[1])])
plt.scatter(itersections[:,0], itersections[:,1])
plt.imshow(img, cmap='gray')
Run Code Online (Sandbox Code Playgroud)
或者,如果您更喜欢遵循左下部分,您只需通过替换来减少底部的点
bottom = contours[0][idx_y[-30:]], contours[1][idx_y[-30:]]
Run Code Online (Sandbox Code Playgroud)
和
bottom = contours[0][idx_y[-10:]], contours[1][idx_y[-10:]]
Run Code Online (Sandbox Code Playgroud)