แจก Savitzky-Golay Digital Filter .NET Library
![]() |
การปรับเส้นโค้งให้เรียบโดยใช้ Savitzky-Golay Filter |
หนึ่งในเทคนิคสำคัญในการประมวลผลสัญญาณเชิงดิจิตอลคือ การกรองสัญญาณ (Filtering) ซึ่งเป็นกระบวนการในการแยกสัญญาณหลักออกจากสัญญาณที่ไม่ต้องการ (noise) โดยใช้วิธีการทางคณิตศาสตร์ ซึ่งตัวกรองแบบดิจิตอลนั้นมีอยู่ด้วยกันหลายตัว แต่ในบทความนี้เราจะมาทำความรู้จักกับตัวกรองที่ชื่อว่า Savitzky-Golay
ในปี 1964 Abraham Sabitzky และ Marcel J.E. Golay ได้ตีพิมพ์งานวิจัย "Smoothing and differentiation of Data by Simplified Least Squares Procedures." ลงในวารสาร Analytical Chemistry ซึ่งได้ถูกนำไปอ้างอิงเป็นอย่างมาก ด้วยข้อดีที่ไม่ทำให้ Amplitude ของสัญญาณลดลงรวมถึงไม่มีการ lag ของสัญญาณ
ด้วยเหตุนี้ จึงได้ถูกนำไปประยุกต์ใช้เป็นอย่างมาก ไม่ว่าจะเป็นทางด้าน Science, Medical, Engineering เช่น นำไปกรองสัญญาณข้อมูลที่ได้จาก Absorbtion Spectroscopy หรือการนำไปกรองสัญญาณเครื่องตรวจวัดและบันทึกคลื่นไฟฟ้าของหัวใจ(ECG) แม้กระทั่งกรองสัญญาณที่ได้มาจากเครื่องเร่งอนุภาค
* เนื่องมาจากไม่สะดวกในการนำตัวอย่างที่อยู่ในโปรเจคที่ผมทำไว้มาเปิดเผย บวกกับความขี้เกียจในการสร้างโปรเจคตัวอย่างมาสาธิต ในบทความนี้จึงมีเพียงการอธิบายหลักการอย่างคร่าวๆและแจก Library เพียงเท่านั้น
** จากนี้ไปในบทความจะเรียก Savitzky-Golay Filter ว่า SG Filter
* เนื่องมาจากไม่สะดวกในการนำตัวอย่างที่อยู่ในโปรเจคที่ผมทำไว้มาเปิดเผย บวกกับความขี้เกียจในการสร้างโปรเจคตัวอย่างมาสาธิต ในบทความนี้จึงมีเพียงการอธิบายหลักการอย่างคร่าวๆและแจก Library เพียงเท่านั้น
** จากนี้ไปในบทความจะเรียก Savitzky-Golay Filter ว่า SG Filter
หลักการทำงานของตัวกรองสาวิทซกี-โกเลย์
ตัวกรอง SG Filter นั้นใช้หลักการของการประมาณพหุนามเป็นช่วงๆ และการหาค่าเฉลี่ยโดยการเลื่อน Window แบบกำลังสองน้อยที่สุด (Least Square) โดยค่า output ของตัวกรอง SG สามารถคำนวณได้จากสมการ
\[{{g}_{i}}=\sum\limits_{n=-{{n}_{L}}}^{{{n}_{R}}}{{{c}_{n}}{{f}_{i+n}}}\text{ ; i = }...\text{,-2,-1,0,1,2,}...\] แนวคิดของตัวกรอง SG คือการหาสัมประสิทธิ์ตัวกรอง \({{c}_{n}}\) ที่สามารถปรับค่าได้ตามค่าของข้อมูลที่ได้มาจากการเลื่อนของ Window ถ้าสัมประสิทธิ์ \({{c}_{n}}\) ถูกแทนที่ด้วยพหุนามอันดับ \(M\) ที่อยู่ในรูป \(a={{({{A}^{T}}\cdot A)}^{-1}}\cdot {{A}^{T}}\cdot f\text{ }\) จะแสดงเวกเตอร์สัมประสิทธิ์ a ได้ดังสมการข้างล่าง\[a={{({{A}^{T}}\cdot A)}^{-1}}\cdot {{A}^{T}}\cdot f\text{ }\] f ในสมการสามารถแทนด้วยเวกเตอร์หนึ่งหน่วย (unit vector) \({{e}_{n}}\) ดังนั้นค่าสัมประสิทธิ์ของ SG จะได้จาก\[{{c}_{n}}={{\left\{ {{({{A}^{T}}\cdot A)}^{-1}}\cdot ({{A}^{T}}\cdot {{e}_{n}}) \right\}}_{0}}={{\sum\limits_{m=0}^{M}{\left\{ {{({{A}^{T}}\cdot A)}^{-1}} \right\}}}_{0m}}{{n}^{m}}\] จะเห็นได้ว่าพารามิเตอร์ที่ส่งผลต่อการตอบสนองทางความถี่ของตัวกรองคือ M และ n โดยรูปด้านล่างแสดงผลการทดสอบตัวกรอง SG โดยใช้ความกว้างของหน้าต่างเท่ากับ 33 จุด และ \({{n}_{L}}={{n}_{R}}=16\) โดยภาพบนคือฟังก์ชันคลื่นสัญญาณที่ใช้ทดสอบที่เพิ่มสัญญาณรบกวนเข้าไป (สัญญาณหลักคือเส้นประ) ภาพตรงกลางแสดงถึงผลลัพธ์จากการปรับสัญญาณให้เรียบโดยใช้วิธีการเฉลี่ยแบบเลื่อนหน้าต่าง (moving average) จะเห็นได้ว่าขนาดแอมพลิจูดของสัญญาณถูกลดทอนไปด้วยเป็นอย่างมาก กลับกันที่ภาพล่างเป็นการใช้ตัวกรองแบบสาวิทซกี-โกเลย์ โดยใช้พหุนามอันดับที่ \(M=4\) ซึ่งผลลัพธ์ที่เห็นได้ว่าขนาดแอมพลิจูดของสัญญาณมีความใกล้เคียงกับสัญญาณจริงมาก
![]() |
Source : Numerical Recipes in C : The Art of Scientific Computing |
NBT_SavGol_Beta .NET Library
SG Filter อันนี้ ผมปรับเปลี่ยน code จากหนังสือที่ชื่อว่า Numerical Recipes in C : The Art of Scientific Computing (หนังสือเล่มนี้แนะนำเป็นอย่างยิ่งสำหรับผู้ที่ทำ Numerical) โดยวิธีการใช้ไลบรารี่ NBT_SavGol_Beta นั้นเพียงแค่เรียกใช้ Class savgolFilter และใช้ method sgSmooth
savgolFilter SavGolFilter = new savgolFilter();โดยที่ cArrary คือ ข้อมูลที่ต้องการ smooth , n คือ จำนวนของข้อมูล , nl คือ ขนาดของหน้าต่างทางซ้าย , nr คือ ขนาดของหน้าต่างทางขวา , ld คือ อันดับของอนุพันธ์ที่ต้องการ (0 คือ smoothing) , m คือ อันดับพหุนาม โดยผัลลัพธ์จะถูก return ออกมาในรูปของ array
double[] dbData = SavGolFilter.sgSmooth(double[] cArray, int n, int nl, int nr, int ld, int m)
Download : NBT_SavGol_Beta.dll
Comments
Post a Comment