用Python做曲線擬合

Python功能強大,有很多第三方庫,可以直接在Pycharm解釋器設置裏下載添加,包括處理一些MATLAB可以實現的功能。
在這裏插入圖片描述


曲線擬合的方式有很多種,以多項式擬合爲例:


import matplotlib.pyplot as plt
import numpy as np

x = 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')

運行結果:

需要注意的是,多項式擬合所處理的數據量有一定限制,一般越高階的多項是擬合的數據要更爲準確,然而當數據過多時,可以嘗試多次擬合拼接。


以批量處理多張圖片,擬合其亮度值爲例:


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 avg

def 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)

擬合效果:
在這裏插入圖片描述


數據過多時,嘗試兩次高階多項式擬合拼接:


import matplotlib.pyplot as plt
import numpy as np

list1 = [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)

擬合效果:
在這裏插入圖片描述


多項式打印結果:


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

RankWarning中警告指的就是數據過多,擬合效果可能不是很好;且根據其階數可以看出,到了4.667e-142的冪數據已經幾乎飽和就不再進行擬合了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章