Thực hiện
Giả sử bạn đã có thói quen vẽ đường thẳng, bạn chỉ cần bổ sung điều đó bằng một số loại nội suy. Các đường cong được tạo ra bằng cách vẽ đủ các đường ngắn nội suy để làm cho kết quả trông mượt mà. Một điểm khởi đầu tốt sẽ là sử dụng một thói quen nội suy hiện có, giống như thói quen được đưa ra bởi Paul Bourke ở đây .
Tôi sẽ minh họa điều này bằng cách sử dụng các thói quen hình khối mà anh ấy cung cấp, vì đó là những cách đơn giản nhất vẫn sẽ cho kết quả hợp lý. Đây là cái đầu tiên (được dịch sang python) để tham khảo:
def cubic(mu,y0,y1,y2,y3):
mu2 = mu*mu
a0 = y3 - y2 - y0 + y1
a1 = y0 - y1 - a0
a2 = y2 - y0
a3 = y1
return a0*mu*mu2 + a1*mu2 + a2*mu + a3
Mỗi thường trình có một tham số mu
đại diện cho phần phân số của chỉ mục bạn muốn nội suy. Tùy thuộc vào thói quen, các tham số khác sẽ là một số mẫu xung quanh chỉ số được đề cập. Trong trường hợp khối, bạn sẽ cần bốn mẫu. Ví dụ, nếu dữ liệu của bạn y[n]
, và bạn muốn giá trị tại 10.3
, mu
sẽ là .3
, và bạn muốn vượt qua trong y[9]
, y[10]
, y[11]
, và y[12]
.
Sau đó, thay vì vẽ một dòng duy nhất với các điểm cuối, hãy nói, ( 10 ,y10) → ( 11 ,y11), bạn sẽ vẽ một loạt các cái ngắn hơn bằng cách sử dụng các giá trị được nội suy (ví dụ: ( 10 ,y10) → ( 10.1 , khối ( .1 ,y9,y10,y11,y12) ) ...). Rõ ràng những điểm đó sẽ cần phải được thu nhỏ lạix và y kích thước của hình ảnh được hiển thị.
Học thuyết
Bây giờ, vì trang / thói quen mà tôi tham chiếu không trích dẫn bất kỳ nguồn nào, nên đáng để giải thích những thói quen hình khối đó đến từ đâu (và cách chúng hoạt động). Cả cái tôi đã sao chép ở trên và spline Catmull-Rom rất giống nhau mà anh ấy đề cập ngay bên dưới nó, là hai trường hợp cụ thể của việc sử dụng hạt nhân chập khối sau đây:
ψ ( x ) =⎧⎩⎨⎪⎪( α + 2 ) | x|3- ( α + 3 ) | x|2+ 1 ,alpha | x|3- 5 α | x|2+ 8 α | x | - 4 α ,0 , nếu 0 ≤ | x | < 1 nếu 1 ≤ | x | < 2 nếu 2 ≤ | x |
Các thói quen được liệt kê ở trên tương ứng với một giá trị của α = - 1và spline Catmull-Rom tương ứng với α = - 1 / 2. Tôi sẽ không đi sâu vào chi tiết về cách thức hình thức chung của kernel, nhưng nó liên quan đến các ràng buộc khác nhau như đảm bảo rằngψ ( x ) là một ở 0 và 0 ở tất cả các số nguyên khác.
Đây là những gì nó trông giống như:
Hai lựa chọn cho giá trị của αđến từ những nỗ lực để phù hợp với các khía cạnh khác nhau của chức năng chân thành , hạt nhân tái thiết lý tưởng. Cài đặtα = - 1 làm cho đạo hàm của ψ phù hợp với đạo hàm của hàm chân tại x = 1và làm cho nó bằng - 1 / 2thay vào đó cung cấp xấp xỉ tần số thấp tốt nhất. Bởi tất cả các tài khoản, giá trị củaα = - 1 / 2có tính chất tốt hơn nhiều về tổng thể, vì vậy nó có thể là giá trị tốt nhất để sử dụng trong thực tế. Một cuộc thảo luận rộng rãi hơn có thể được tìm thấy trong bài báo sau, bắt đầu từ trang 328:
Meijering, Erik. Lịch sử thời gian của nội suy: Từ thiên văn học cổ đại đến xử lý tín hiệu và hình ảnh hiện đại. Thủ tục tố tụng của IEEE. tập. 90, không. 3, trang 319-42. Tháng 3/2002.
Cái nhìn sâu sắc
Bây giờ, chỉ cần nhìn vào hạt nhân đó liên quan đến việc triển khai thực tế mã nội suy, có thể không rõ ràng hai cái này có liên quan như thế nào. Về cơ bản, quá trình nội suy có thể được coi là thêm các bản sao đã dịch chuyển của nhân, được chia tỷ lệ theo các mẫu của dữ liệu, như vậy:
Trong thực tế, nếu bạn có một triển khai kernel, bạn có thể sử dụng nó trực tiếp để thực hiện phép nội suy, như sau:
def kernel(x, a=-1.0):
x = abs(x)
if x >= 0.0 and x < 1.0:
return (a + 2.0)*x**3.0 - (a + 3.0)*x**2.0 + 1
elif x >= 1.0 and x < 2.0:
return a*x**3.0 - 5.0*a*x**2.0 + 8.0*a*x - 4.0*a
else:
return 0.0
def cubic(mu,y0,y1,y2,y3):
a = -1.0
result = y0 * kernel(mu + 1, a)
result += y1 * kernel(mu, a)
result += y2 * kernel(mu - 1, a)
result += y3 * kernel(mu - 2, a)
return result
Tuy nhiên, nó ít hiệu quả hơn về mặt tính toán để làm theo cách đó. Là cầu nối từ cách tiếp cận hạt nhân trực tiếp đến cách tiếp cận hợp lý hơn ở trên, hãy xem xét rằng với một chút thao tác đại số, việc thực hiện đầu tiên có thể được đưa ra dưới dạng sau:
def cubic(mu,y0,y1,y2,y3):
mu2 = mu*mu
mu3 = mu*mu2
c0 = -mu3 + 2*mu2 - mu
c1 = mu3 - 2*mu2 + 1
c2 = -mu3 + mu2 + mu
c3 = mu3 - mu2
return c0*y0 + c1*y1 + c2*y2 + c3*y3
Trong công thức này, các c0...c3
giá trị có thể được coi là hệ số của bộ lọc FIR được áp dụng cho các giá trị mẫu. Bây giờ dễ dàng hơn nhiều để xem làm thế nào để lấy được thói quen từ kernel. Hãy xem xét kernel vớiα = - 1, như vậy:
ψ ( x ) =⎧⎩⎨⎪⎪| x|3- 2 | x|2+ 1 ,- | x|3+ 5 | x|2- 8 | x | + 4 ,0 , nếu 0 ≤ | x | < 1 nếu 1 ≤ | x | < 2 nếu 2 ≤ | x |
Bây giờ hãy đánh giá hạt nhân đó một cách tượng trưng ở các độ lệch khác nhau, hãy nhớ rằng mu
(μ) phạm vi từ 0
đến 1
:
ψ ( μ + 1 )ψ ( μ )ψ ( μ - 1 )ψ ( μ - 2 )= == == == =- ( μ + 1)3+ 5 ( μ + 1)2- 8 ( μ + 1 ) + 4μ3- 2μ2+ 1( 1 - μ)3- 2 ( 1 - μ)2+ 1- ( 2 - μ)3+ 5 ( 2 - μ)2- 8 ( 2 - μ ) + 4= == == == =-μ3+ 2μ2- μμ3- 2μ2+ 1-μ3+μ2+ μμ3-μ2(c0)(c1)(c2)(c3)
Lưu ý rằng μ - 1 , μ - 2 bị "lật" 1 - μ , 2 - μ tương ứng vì giá trị tuyệt đối trên xtrong định nghĩa hạt nhân. Bây giờ chúng ta có các đa thức chính xác được sử dụng trong "phiên bản FIR" của thói quen nội suy. Việc đánh giá các đa thức đó sau đó có thể được thực hiện hiệu quả hơn thông qua các kỹ thuật tiêu chuẩn (ví dụ: phương pháp của Horner ). Những điều tương tự có thể được thực hiện với các hạt nhân khác và cũng có những cách khác để xây dựng các triển khai hiệu quả (xem Trang chủ Lấy mẫu Âm thanh Kỹ thuật số ).