在图像上拟合样条
Fit a spline on image
我正在尝试找到一种在图像上拟合样条曲线的方法。我知道在要处理的图像中有一行是:
- 有点水平
- 从左到右边缘
- 不连续
我找不到在那里拟合样条的方法。这可以通过 NI LabView 实现,因此很难相信 OpenCV 也没有办法。
这是我的进展:
import cv2
frame = cv2.imread("./download.png")
edged = cv2.Canny(frame, 50, 200)
cv2.imshow('frame', frame)
cv2.imshow('edge', edged)
cv2.waitKey()
下面的示意图描述了我已经完成的工作以及预期的输出(红色手动绘制的样条曲线)。
你可以试试OpenCV的腐蚀膨胀等形态学操作。通过使用不同的内核形状,缩小垂直边缘并增加水平边缘。这样做几次,然后您将连接水平边缘。最后瘦那个胖的水平边缘。
有关如何使用腐蚀和膨胀的一些示例,请访问:
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html.
事实证明,使用 OpenCV 无法拟合样条曲线,但我在@triiiiista 的帮助下找到了解决方法。供日后参考(为简单起见,使用原图的上半部分):
import numpy as np
import cv2
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
frame = cv2.imread("./download.png")
blur = cv2.blur(frame,(5,5))
edged = cv2.Canny(blur, 50, 200)
# remove vertical parts
kernel_remove_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(3, 1))# remove vertical parts
edged_hor = cv2.erode(edged, kernel_remove_vertical)
cv2.imshow('edge', edged)
cv2.imshow('edge_hor', edged_hor)
cv2.waitKey(1)
# Find coordinates for white pixels
# Hope that there aren't too many outliers :)
pixels = np.argwhere(edged_hor == 255)
x = (pixels[:, 1])
y = (pixels[:, 0])
# Interpolate with scipy
f = interp1d(x, y, kind='cubic')
xnew = np.linspace(10, 630)
plt.figure()
plt.imshow(cv2.cvtColor(edged_hor, cv2.COLOR_BGR2RGB))
plt.plot(xnew, f(xnew))
这导致:
我正在尝试找到一种在图像上拟合样条曲线的方法。我知道在要处理的图像中有一行是:
- 有点水平
- 从左到右边缘
- 不连续
我找不到在那里拟合样条的方法。这可以通过 NI LabView 实现,因此很难相信 OpenCV 也没有办法。
这是我的进展:
import cv2
frame = cv2.imread("./download.png")
edged = cv2.Canny(frame, 50, 200)
cv2.imshow('frame', frame)
cv2.imshow('edge', edged)
cv2.waitKey()
下面的示意图描述了我已经完成的工作以及预期的输出(红色手动绘制的样条曲线)。
你可以试试OpenCV的腐蚀膨胀等形态学操作。通过使用不同的内核形状,缩小垂直边缘并增加水平边缘。这样做几次,然后您将连接水平边缘。最后瘦那个胖的水平边缘。
有关如何使用腐蚀和膨胀的一些示例,请访问: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html.
事实证明,使用 OpenCV 无法拟合样条曲线,但我在@triiiiista 的帮助下找到了解决方法。供日后参考(为简单起见,使用原图的上半部分):
import numpy as np
import cv2
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
frame = cv2.imread("./download.png")
blur = cv2.blur(frame,(5,5))
edged = cv2.Canny(blur, 50, 200)
# remove vertical parts
kernel_remove_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(3, 1))# remove vertical parts
edged_hor = cv2.erode(edged, kernel_remove_vertical)
cv2.imshow('edge', edged)
cv2.imshow('edge_hor', edged_hor)
cv2.waitKey(1)
# Find coordinates for white pixels
# Hope that there aren't too many outliers :)
pixels = np.argwhere(edged_hor == 255)
x = (pixels[:, 1])
y = (pixels[:, 0])
# Interpolate with scipy
f = interp1d(x, y, kind='cubic')
xnew = np.linspace(10, 630)
plt.figure()
plt.imshow(cv2.cvtColor(edged_hor, cv2.COLOR_BGR2RGB))
plt.plot(xnew, f(xnew))
这导致: