用Python做曲线拟合

Python功能强大,有很多第三方库,可以直接在Pycharm解释器设置里下载添加,包括处理一些MATLAB可以实现的功能。
用Python做曲线拟合
文章图片

曲线拟合的方式有很多种,以多项式拟合为例:
import matplotlib.pyplot as plt import numpy as npx = np.arange(1, 22, 1) y = np.array([176.55823623919866, 175.82629227599108, 174.6682288122686, 174.1676016833001, 173.18851142144007, 171.50626507572986, 171.30220775004557, 171.36967661238003, 171.28415302420305, 171.28824729828153, 171.57034121168718, 172.33094464950744, 173.23238914855358, 173.55613816498442, 174.3453315452684, 175.8405706931801, 176.55279402689868, 176.61370282973544, 176.81582616485196, 177.02915557477107, 176.8786448208988]) z1 = np.polyfit(x, y, 100) # 用3次多项式拟合 p1 = np.poly1d(z1) print(p1) # 在屏幕上打印拟合多项式 yvals=p1(x) # 也可以使用yvals=np.polyval(z1,x) plot1=plt.plot(x, y, '*',label='original values') plot2=plt.plot(x, yvals, 'r',label='polyfit values') plt.xlabel('x axis') plt.ylabel('y axis') plt.legend(loc=4) # 指定legend的位置,读者可以自己help它的用法 plt.title('polyfitting') plt.show() plt.savefig('p1.png')

运行结果:
用Python做曲线拟合
文章图片
需要注意的是,多项式拟合所处理的数据量有一定限制,一般越高阶的多项是拟合的数据要更为准确,然而当数据过多时,可以尝试多次拟合拼接。
以批量处理多张图片,拟合其亮度值为例:
import os import math from PIL import Image, ImageStat, ImageEnhance import sys import matplotlib.pyplot as plt# 读取图片原有的亮度值 def brightness(path): im = Image.open(path) stat = ImageStat.Stat(im) r,g,b = stat.mean return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068 *(b**2))# 获取文件亮度平均值 def brightness_avg(path): os.chdir(path) # 改变工作目录到指定路径 sum = 0.0 num = 0.0 list = [] list1 = [] img_len = len(os.listdir()) for name_list_image in os.listdir(): if name_list_image.endswith(".jpg"): image_url = os.getcwd()+'/'+name_list_image b = brightness(image_url) sum+=b list.append(b) for i in range(0,len(list)): num += list[i] p = num // len(list) print(len(list)) for i in range(len(list)): list1.append(p) print(list1) print(list) print(len(list)) # 设置坐标轴名称 plt.xlabel('x') plt.ylabel('y') plt.plot( list,'*') plt.plot(list, '') plt.plot( list1 ) plt.show() avg = sum/img_len return avgdef main(path,dir): b_avg = brightness_avg(path)if __name__ == "__main__": # path = r'图片文件路径' path='C:/Users/用户名\Desktop/课件/19-20上学期/Python 图像处理基础 曲线拟合/亮度处理/ROIphoto' for i in range(1, len(sys.argv)): path = sys.argv[i] break main(path,dir)

拟合效果:
用Python做曲线拟合
文章图片

数据过多时,尝试两次高阶多项式拟合拼接:
import matplotlib.pyplot as plt import numpy as nplist1 = [176.55823623919866, 175.82629227599108, 174.6682288122686, 174.1676016833001, 173.18851142144007, 171.50626507572986, 171.30220775004557, 171.36967661238003, 171.28415302420305, 171.28824729828153, 171.57034121168718, 172.33094464950744, 173.23238914855358, 173.55613816498442, 174.3453315452684, 175.8405706931801, 176.55279402689868, 176.61370282973544, 176.81582616485196, 177.02915557477107, 176.8786448208988, 176.81439985226544, 176.71451411266156, 176.66586750119254, 176.30753368473069, 176.19523098955372, 176.07119928600355, 175.72179761793777, 175.43552045631185, 175.06619996031966, 174.53081306978117, 174.18429472985528, 173.8891857051452, 173.64330751640563, 173.1717933351755, 172.75272880991568, 172.73580347692774, 172.71686474342098, 172.69409149798975, 173.08779491052138, 173.34364100632905, 173.59571062466185, 174.12459693708425, 175.3580464862954, 175.45959761884262, 175.96958585972754, 176.25514442769904, 176.64561729822563, 176.9716561653289, 176.91158660669385, 176.8209116100747, 176.76023627503446, 176.75061872853308, 176.358077514346, 176.105301140804, 175.75253205020002, 175.32592030580872, 174.4561198543027, 174.16318576040058, 173.6955522308555, 173.36361683009068, 173.27786291152492, 172.8430468018013, 172.44916449098338, 172.37925152892035, 172.37302861988064, 172.539243589413, 172.6076027962434, 173.30903687629709, 173.6726484459664, 174.38075179088534, 174.35096455596033, 175.88411630813638, 176.37365460037168, 176.5190359013566, 176.7555013354064, 176.8843429579835, 176.9999143606833, 176.9612688170496, 176.96293657390825, 176.78778110739344, 176.45215828729877, 176.06391950355714, 175.456133611344, 175.10238577582405, 174.13589426350123, 173.71856168991667, 172.75506195819366, 172.52619234873043, 172.20232568127273, 172.08540070952418, 172.10597477088277, 172.08271329913669, 172.6095880484391, 172.94377522421826, 173.6300070707046, 175.6046559431482, 175.81133042253938, 176.23806059573772, 176.4665155497212, 176.68100141799786, 177.03103128679953, 176.98421637958953, 177.00073049644882, 177.1587220488691, 177.03429777263233, 176.71990304220589, 176.5086407982305, 176.1615847526818, 175.8794207695718, 175.0735855383626, 174.36140581932358, 173.8720499315276, 173.62378250358805, 173.29302157102185, 173.0649065230465, 172.4622044831749, 172.5280950017399, 172.5286747359581, 172.5466194931676, 173.36197557152252, 174.13684369851603, 174.10727291964182, 175.10324893539504, 175.44506588924463, 175.9011658131806, 176.08419194245582, 176.43925933374413, 176.63149256351699, 176.73270643092494, 176.7927115430335, 176.78706440505482, 176.77445250937208, 176.8142036430795, 176.50057944916426, 176.12232222126266, 176.08393647672386, 175.37657408094051, 175.41663659071116, 174.62594785220216, 174.04457169863505, 173.60811211235833, 173.36957821789835, 172.8836504665457, 172.60100177086554, 172.63361517776903, 172.81888582450216, 172.99742334589592, 173.35580779710824, 174.00521684611465, 174.30966818533145, 175.28536562770532, 175.66609314531235, 175.90367459742978, 176.4527738516087, 176.90924497036588, 176.9817389651164, 177.0012641104389, 177.16628613206575, 177.11344509698452, 177.04358001411137, 176.89912996902325, 176.5341418640653, 176.2978147271377, 175.1242588850196, 175.67265226808763, 174.62241233471624, 174.04836019341488, 172.89651207557196, 172.56515161301024, 172.48394284336726, 172.3725575380836, 172.3607151337593, 172.6939537797305, 173.23320994088365, 173.3725417745558, 173.73128516054635, 174.4379216822258, 175.53190635723456, 176.06270831282416, 176.39342939266135, 176.68157793103921, 177.0099858820125, 177.25187668065863, 177.36100632781813, 177.55343593476798, 177.47722670635673, 177.38131049205398, 177.0301008802558, 176.57932362376525, 176.26150568641026, 175.93049640705155, 174.05658379742297, 173.8494293764074, 173.29399494753386, 173.06571316986881, 172.54102581069657, 172.37061972099286, 172.47303701367443, 172.3893822185587, 172.7330071403166, 172.97039275988143, 173.5848272047908, 174.59132738492374, 174.428044597701, 175.2273312893782, 175.87873553926326, 176.30461280490263, 176.71866140171576, 177.01993002417984, 177.0844410062251, 177.12444366484917, 177.3012076876708, 177.32753216669667, 177.47365825023536, 177.34445972416944, 176.6568052203644, 176.34618723106024, 175.95155021561112, 175.5433400026391, 174.14982598610834, 172.70018498277074, 172.3636772790286, 171.35804046813456, 170.95783150186915, 170.79158718440846, 170.89054877009738, 171.18440150525686, 171.50733374367994, 172.5164540673539, 173.2980006609825, 175.34746104889584, 176.3750613338565, 176.87531317442603]def QXNH(list): lists1 = [[],[]] lists2 = [[],[]] lists1[0] = np.array(list[0:101]) lists1[1] = np.array(list[98:234]) lists2[0] = np.arange(1, len(list[0:101])+1, 1) lists2[1] = np.arange(99, 235 , 1) z = [[],[]] p = [[],[]] for i in range(2): x = lists2[i] y = lists1[i] z[i] = np.polyfit(x, y, 76)# 用高次多项式拟合 p[i] = np.poly1d(z[i]) print(p[i])# 在屏幕上打印拟合多项式 yvals = p[i](x)# 也可以使用yvals=np.polyval(z1,x) plot1 = plt.plot(x, y, '*', label='original values') plot2 = plt.plot(x, yvals, 'r', label='polyfit values') plt.xlabel('x axis') plt.ylabel('y axis') plt.legend(loc=4)# 指定legend的位置,读者可以自己help它的用法 plt.title('polyfitting') plt.show() plt.savefig('p1.png')QXNH(list1)

拟合效果:
用Python做曲线拟合
文章图片

多项式打印结果: D:\图片转视频\venv\Scripts\python.exe “C:/Users/用户名/Desktop/课件/19-20上学期/Python 图像处理基础 曲线拟合/亮度处理/拟合.py”
76 75 74 73
C:/Users/用户名/Desktop/课件/19-20上学期/Python 图像处理基础 曲线拟合/亮度处理/拟合.py:31: RankWarning: Polyfit may be poorly conditioned
4.667e-142 x - 7.025e-140 x - 4.04e-138 x + 1.669e-136 x
72 71 70 69
  • 4.995e-134 x + 4.899e-132 x + 2.37e-130 x - 9.574e-129 x
    QXNH(list1)
    68 67 66 65
  • 3.624e-126 x - 4.764e-124 x - 4.184e-122 x - 2.255e-120 x
    64 63 62 61
  • 3.093e-119 x + 2.701e-116 x + 4.251e-114 x + 4.57e-112 x
    60 59 58 57
  • 3.624e-110 x + 1.707e-108 x - 6.55e-107 x - 2.837e-104 x
    56 55 54 53
  • 4.277e-102 x - 4.609e-100 x - 3.745e-98 x - 1.9e-96 x
    52 51 50 49
  • 4.607e-95 x + 2.731e-92 x + 4.312e-90 x + 4.768e-88 x
    48 47 46 45
  • 3.943e-86 x + 2.015e-84 x - 5.197e-83 x - 2.968e-80 x
    44 43 42 41
  • 4.617e-78 x - 4.939e-76 x - 3.764e-74 x - 1.373e-72 x
    40 39 38 37
  • 1.54e-70 x + 4.042e-68 x + 5.247e-66 x + 4.632e-64 x
    36 35 34 33
  • 2.284e-62 x - 1.039e-60 x - 4.091e-58 x - 5.579e-56 x
    32 31 30 29
  • 4.703e-54 x - 1.632e-52 x + 2.384e-50 x + 5.413e-48 x
    28 27 26 25
  • 5.715e-46 x + 2.794e-44 x - 1.994e-42 x - 5.816e-40 x
    24 23 22 21
  • 5.909e-38 x - 1.662e-36 x + 4.227e-34 x + 6.964e-32 x
    20 19 18 17
  • 3.464e-30 x - 3.847e-28 x - 7.569e-26 x - 2.42e-24 x
    16 15 14 13
  • 6.517e-22 x + 6.596e-20 x - 4.457e-18 x - 8.266e-16 x
    12 11 10 9 8
  • 5.504e-14 x + 7.12e-12 x - 1.2e-09 x + 8.199e-08 x - 3.364e-06 x
    7 6 5 4 3 2
  • 9.076e-05 x - 0.001652 x + 0.02023 x - 0.164 x + 0.858 x - 2.696 x + 3.416 x + 175.1
    D:\图片转视频\venv\lib\site-packages\numpy\lib\polynomial.py:629: RuntimeWarning: overflow encountered in multiply
    scale = NX.sqrt((lhs*lhs).sum(axis=0))
    D:\图片转视频\venv\lib\site-packages\numpy\core_methods.py:38: RuntimeWarning: overflow encountered in reduce
    return umr_sum(a, axis, dtype, out, keepdims, initial, where)
    C:/Users/用户名/Desktop/课件/19-20上学期/Python 图像处理基础 曲线拟合/亮度处理/拟合.py:31: RankWarning: Polyfit may be poorly conditioned
    QXNH(list1)
    64 63 62 61
    -6.597e-142 x + 3.266e-139 x + 1.152e-137 x - 1.081e-134 x
    60 59 58 57
  • 2.801e-132 x - 2.375e-130 x + 6.36e-128 x + 3.15e-125 x
    56 55 54 53
  • 7.207e-123 x + 8.738e-121 x - 6.173e-119 x - 6.753e-116 x
    52 51 50 49
  • 2.147e-113 x - 4.42e-111 x - 5.247e-109 x + 3.589e-107 x
    48 47 46 45
  • 4.171e-104 x + 1.41e-101 x + 3.203e-99 x + 4.813e-97 x
    44 43 42 41
  • 1.418e-95 x - 2.053e-92 x - 8.767e-90 x - 2.308e-87 x
    40 39 38 37
  • 4.238e-85 x - 3.97e-83 x + 7.614e-81 x + 5.116e-78 x
    36 35 34 33
  • 1.568e-75 x + 3.268e-73 x + 4.032e-71 x - 2.365e-69 x
    32 31 30 29
  • 3.094e-66 x - 1.042e-63 x - 2.235e-61 x - 2.677e-59 x
    28 27 26 25
  • 2.215e-57 x + 2.26e-54 x + 6.976e-52 x + 1.274e-49 x
    24 23 22 21
  • 7.339e-48 x - 4.285e-45 x - 1.851e-42 x - 3.89e-40 x
    20 19 18 17
  • 2.845e-38 x + 1.154e-35 x + 5.051e-33 x + 8.969e-31 x
    16 15 14 13
  • 7.223e-30 x - 4.85e-26 x - 1.205e-23 x - 4.014e-22 x
    12 11 10 9
  • 5.23e-19 x + 1.222e-16 x - 5.526e-15 x - 6.731e-12 x
    8 7 6 5 4
  • 3.731e-10 x + 3.02e-07 x + 1.312e-05 x - 0.01482 x + 2.314 x
    3 2
  • 171.1 x + 6324 x - 8.986e+04 x - 2.362e+05
【用Python做曲线拟合】RankWarning中警告指的就是数据过多,拟合效果可能不是很好;且根据其阶数可以看出,到了4.667e-142的幂数据已经几乎饱和已出现过拟合。

    推荐阅读