如何将图像中的曲线转换为 Python 中的直线?
How to convert curves in images to lines in Python?
我是图像处理的新手,正在处理这样的图像:
在这些图片中,会有不止一条曲线,我需要将它们拉直以使它们看起来像一条直线。
这是一个快速解决方案。它可以通过对特征进行样条拟合而不是仅仅拟合抛物线来改进。该算法根据拟合的抛物线分别移动图像中的每一行:
from skimage import io, measure, morphology
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
image = io.imread('curves.png', as_gray=True)
# need a binary mask of features
mask = image == image.min()
# close holes in features
mask = morphology.binary_closing(mask, morphology.square(3))
plt.matshow(mask, cmap='gray')
# need to get the coordinates of each feature
rp = measure.regionprops(measure.label(mask))
# going to fit a parabola to the features
def parabola(x, x0, A, y0):
return A*(x-x0)**2 + y0
# get coords of one of the features
coords = rp[0].coords
# do parabola fit
pop, pcov = curve_fit(parabola, coords[:,0], coords[:,1])
# generate fit
fit = parabola(np.arange(mask.shape[0]), *pop)
# plot fit
plt.plot(fit, np.arange(mask.shape[0])) # invert axes
# generate new image to shift
out = np.empty_like(image)
# shift each row individually and add to out array
for i, row in enumerate(image):
out[i] = np.roll(row, -int(round(fit[i] - pop[-1])))
plt.matshow(out, cmap='gray')
原始面具和拟合抛物线:
结果:
我是图像处理的新手,正在处理这样的图像:
在这些图片中,会有不止一条曲线,我需要将它们拉直以使它们看起来像一条直线。
这是一个快速解决方案。它可以通过对特征进行样条拟合而不是仅仅拟合抛物线来改进。该算法根据拟合的抛物线分别移动图像中的每一行:
from skimage import io, measure, morphology
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
image = io.imread('curves.png', as_gray=True)
# need a binary mask of features
mask = image == image.min()
# close holes in features
mask = morphology.binary_closing(mask, morphology.square(3))
plt.matshow(mask, cmap='gray')
# need to get the coordinates of each feature
rp = measure.regionprops(measure.label(mask))
# going to fit a parabola to the features
def parabola(x, x0, A, y0):
return A*(x-x0)**2 + y0
# get coords of one of the features
coords = rp[0].coords
# do parabola fit
pop, pcov = curve_fit(parabola, coords[:,0], coords[:,1])
# generate fit
fit = parabola(np.arange(mask.shape[0]), *pop)
# plot fit
plt.plot(fit, np.arange(mask.shape[0])) # invert axes
# generate new image to shift
out = np.empty_like(image)
# shift each row individually and add to out array
for i, row in enumerate(image):
out[i] = np.roll(row, -int(round(fit[i] - pop[-1])))
plt.matshow(out, cmap='gray')
原始面具和拟合抛物线:
结果: