如何在python中找到拐点?

如何在python中找到拐点?,python,arrays,opencv,Python,Arrays,Opencv,我有一个RGB图像的直方图,它代表了三个分量R、G和B的三条曲线。我想找到每条曲线的拐点。我用二阶导数来求它们,但我找不到,二阶导数不会抵消它的返回值为空。那么我怎样才能找到拐点呢?有没有其他方法可以找到它们 代码中有两个数字性质的问题: 数据似乎不够连续,无法依赖从两个后续np.diff()应用程序计算的二阶导数 即使是这样,它完全0的可能性也很小 要解决第一个问题,您应该平滑直方图(例如,对直方图本身使用均匀或高斯滤波器) 要解决第二个问题,不要寻找==0,而是寻找从正到负(反之亦然)

我有一个RGB图像的直方图,它代表了三个分量R、G和B的三条曲线。我想找到每条曲线的拐点。我用二阶导数来求它们,但我找不到,二阶导数不会抵消它的返回值为空。那么我怎样才能找到拐点呢?有没有其他方法可以找到它们


代码中有两个数字性质的问题:

  • 数据似乎不够连续,无法依赖从两个后续
    np.diff()
    应用程序计算的二阶导数
  • 即使是这样,它完全
    0
    的可能性也很小
要解决第一个问题,您应该平滑直方图(例如,对直方图本身使用均匀或高斯滤波器)

要解决第二个问题,不要寻找
==0
,而是寻找从正到负(反之亦然)的切换点


为您提供一些可能方法的最小示例:

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter1d


np.random.seed(0)

# generate noisy data
raw = np.cumsum(np.random.normal(5, 100, 1000))
raw /= np.max(raw)

# smooth
smooth = gaussian_filter1d(raw, 100)

# compute second derivative
smooth_d2 = np.gradient(np.gradient(smooth))

# find switching points
infls = np.where(np.diff(np.sign(smooth_d2)))[0]

# plot results
plt.plot(raw, label='Noisy Data')
plt.plot(smooth, label='Smoothed Data')
plt.plot(smooth_d2 / np.max(smooth_d2), label='Second Derivative (scaled)')
for i, infl in enumerate(infls, 1):
    plt.axvline(x=infl, color='k', label=f'Inflection Point {i}')
plt.legend(bbox_to_anchor=(1.55, 1.0))

你是说拐点?你在问数学问题吗?欢迎来到SO,请花点时间阅读和阅读该页面上的其他链接。@wwii问题似乎不是关于数学,而是关于如何将数学转化为代码。@supersew yes拐点
derivative2=np.diff(derivative1,axis=0)。astype(int)
我使用cv2.GaussianBlur在直方图上使用了高斯滤波器,请问我如何找到这个切换点?@khadoudj然后使用更宽的sigma,数据仍然太嘈杂。然后寻找具有非连续索引的`>=0`或其他东西来获得切换点。我使用的高斯滤波器的最大值是(7,7)而且还是太noisy@khadoudj我用一些最小的代码更新了答案,以表明我所描述的方法在充分平滑的数据上应该很好地工作。非常感谢,我有一个问题,为什么在gaussian_filter1d中使用100?
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter1d


np.random.seed(0)

# generate noisy data
raw = np.cumsum(np.random.normal(5, 100, 1000))
raw /= np.max(raw)

# smooth
smooth = gaussian_filter1d(raw, 100)

# compute second derivative
smooth_d2 = np.gradient(np.gradient(smooth))

# find switching points
infls = np.where(np.diff(np.sign(smooth_d2)))[0]

# plot results
plt.plot(raw, label='Noisy Data')
plt.plot(smooth, label='Smoothed Data')
plt.plot(smooth_d2 / np.max(smooth_d2), label='Second Derivative (scaled)')
for i, infl in enumerate(infls, 1):
    plt.axvline(x=infl, color='k', label=f'Inflection Point {i}')
plt.legend(bbox_to_anchor=(1.55, 1.0))