Asosiy qism
Median filtri.
Median filtrni (MF) qo'llashda, ramkaning har bir nuqtasida ketma-ket ishlov berish sodir bo'ladi, natijada hisob-kitoblar ketma-ketligi yuzaga keladi. Mafkuraviy jihatdan, turli nuqtalarda ishlov berish mustaqil (bu MF niqob filtriga o'xshaydi), ammo uni tezlashtirish uchun har qadamda ilgari bajarilgan hisob-kitoblardan foydalanish tavsiya etiladi.
Median filtrlash, odatda markaziy simmetriyaga ega bo'lgan, uning markazi hozirgi filtrlash punktida joylashgan ikki o'lchovli oynani (filtr teshigi) ishlatadi. Shaklda 1.1, xoch va kvadrat shaklida eng ko'p ishlatiladigan oyna variantlarining ikkita misolini ko'rsatadi. Diafragma o'lchovlari algoritm samaradorligini tahlil qilish jarayonida optimallashtirilgan parametrlar qatoriga kiradi. Oynaga tushgan rasm namunalari joriy bosqichning ishchi namunasini hosil qiladi.
Shakl 1.1.
Oynaning ikki o'lchovli tabiati sizga aslida ikki o'lchovli filtrlashni amalga oshirishga imkon beradi, chunki hisob-kitobni shakllantirish uchun hozirgi va satrda, shuningdek, qo'shni bo'lganlardagi ma'lumotlar ishlatiladi. Ishchi tanlovni bir o'lchovli qator sifatida belgilang; uning elementlari soni oynaning o'lchamiga teng va ularning joylashuvi o'zboshimchalik bilan. Odatda, ko'p sonli nuqtalarga ega derazalar qo'llaniladi (bu avtomatik ravishda diafragmaning markaziy simmetriyasi bilan ta'minlanadi va eng markaziy nuqta uning tarkibiga kirganda). Agar siz ketma-ketlikni ko'tarilgan tartibda buyurtma qilsangiz, unda uning medianasi ushbu tartiblangan ketma-ketlikda markaziy o'rinni egallagan namunaning elementi bo'ladi. Olingan raqam - bu ramkaning hozirgi nuqtasi uchun filtrlash mahsuloti. Bunday ishlov berishning natijasi aslida ishchi namunada tasvir elementlari qanday tartibda joylashtirilganiga bog'liq emasligi aniq. Biz tasvirlangan protseduraning rasmiy belgilarini quyidagi shaklda kiritamiz:
x * \u003d med (y 1, y 2, ..., y n) (1.1)
Bir misolni ko'rib chiqaylik. Tasdiqlangan namunaning quyidagi shakli bor deylik: Y \u003d (136,110,99,45,250,55,158,104,75) va uning markazida joylashgan 250 element hozirgi filtrlash punktiga to'g'ri keladi (i 1, i 2) (1.1-rasm). Kadrning ushbu nuqtasida katta yorqinlik pulsli (nuqta) shovqinlarga olib kelishi mumkin. Ko'tarilish tartibida buyurtma qilingan namuna (45.55.75.99.104,110,136,158,250) shaklga ega, shuning uchun (1.1) protseduraga muvofiq biz x * \u003d med (y 1, y 2, ..., y 9) \u003d 104 olamiz. Ko'rmoqdamizki, “qo'shnilar” ning filtrlash natijasiga hozirgi nuqtada ta'siri yorqinlik impulsli emissiyasini "e'tiborsiz qoldirishga" olib keldi, bu filtrlash effekti sifatida ko'rib chiqilishi kerak. Agar impulsli shovqin nuqtaga o'xshamasa, lekin ba'zi bir hududni qamrab olsa, u holda uni bostirish mumkin. Bu mahalliy hududning hajmi MF diafragining yarmidan kam bo'lsa, sodir bo'ladi. Shuning uchun, tasvirning mahalliy joylariga ta'sir qiluvchi impulsli shovqinni bostirish uchun MF diafragma kattaligini oshirish kerak.
(1.1) dan kelib chiqadiki, MFning harakati ijobiy va salbiy tashqi etkazib beruvchilarning kirish namunasining ekstremal qiymatlarini «e'tiborsiz qoldirish» dir. Shovqinni kamaytirishning ushbu printsipi rasmdagi shovqinni kuchaytirish uchun qo'llanilishi mumkin. Shu bilan birga, median filtrlash yordamida shovqinni bostirishni o'rganish ushbu muammoni hal qilishda samaradorligi chiziqli filtrlashdan past ekanligini ko'rsatdi.
MF ishlashini ko'rsatuvchi eksperimental natijalar sek. 1.2. Tajribalarda, yon tomoni 3 ga teng bo'lgan to'rtburchak diafragma bo'lgan MF ishlatilgan, shovqin bilan buzilgan tasvirlar chap qatorda ko'rsatilgan va ularning mediani filtrlash natijalari o'ng qatorda berilgan. Shaklda 1.2 a va fig. 1.2.c impulsli shovqin bilan buzilgan asl tasvirni ko'rsatadi. Tekshirilganda, tasodifiy sonlar sensori yordamida interval bo'ylab taqsimot qonuni formali ishlatilib, ramkaning barcha nuqtalarida mustaqil tasodifiy sonlar hosil qilindi. Shovqin intensivligi har bir nuqtada uning paydo bo'lish ehtimoli p tomonidan o'rnatildi. Agar n i1i2 tasodifiy soni uchun (i 1, i 2) nuqtada hosil bo'lsa, n i1i2
i2 shart
Saralash asosida mediani filtrlash.
Uchdan kattaroq filtr uchun sizga Fil Ekstrom tomonidan 2000 yil noyabr oyida Embedded Systems Programming jurnalining sonida tasvirlangan algoritmdan foydalanishni tavsiya etaman. Ekstrom bog'langan ro'yxatdan foydalanadi. Ushbu yondashuv yaxshi, chunki massiv tartiblanganda, eski qiymatni o'chirib, yangisini qo'shib, massivga biron bir jiddiy tartibsizlik kiritilmaydi. Shuning uchun, bu yondashuv katta filtrlar bilan yaxshi ishlaydi.
Yodingizda bo'lsin, dastlabki nashr qilingan kodda Ekstrom keyinchalik tuzatgan ba'zi xatolar mavjud edi. Embedded.com saytida biror narsa topish qiyinligini hisobga olib, men o'z kodimning bajarilishini nashr etishga qaror qildim. Dastlab, kod Dynamic C-da yozilgan, ammo bu xabar uchun u standart S-ga yuborilgan. Kod ishlamoqda deb taxmin qilinadi, lekin uning to'liq tekshiruvi sizning vijdoningizga bog'liq.
# NULL 0
#define STOPPER 0 / * Har qanday ma'lumotlarga qaraganda kichikroq * /
# aniqlang MEDIAN_FILTER_SIZE 5
uint16_t MedianFilter (uint16_t ma'lumotlar)
{
tuzilish juftligi (
tizim juftligi * nuqta; / * Ro'yxat tuzadigan ko'rsatkichlar tartiblangan tartibda bog'langan * /
uint16_t qiymati; / * Saralash uchun qiymatlar * /
};
/ * To'rtinchi juftlik buferi * /
statik struktur juft juft bufer \u003d (0);
/ * Ma'lumotlarning doiraviy buferiga yo'naltiruvchi * /
statik tuzilish juftligi * datpoint \u003d bufer;
/ * Zanjir to'xtatuvchisi * /
statik struktura juftligi kichik \u003d (NULL, STOPPER);
/ * Bog'langan ro'yxatning boshiga (eng katta) ko'rsatgich. * /
statik struktura juftligi katta \u003d (& kichik, 0);
/ * Almashtirilgan ma'lumotlar elementi vorisiga ko'rsatma * /
tizim juftligi * vorisi;
/ * Saralangan ro'yxatni skanerlashda foydalaniladigan ko'rsatkich * /
tizim juftligi * skanerlash;
/ * Skanerning avvalgi qiymati * /
tizim juftligi * skanerbol;
/ * Median ko'rsatkichi * /
tuzilish juftligi * median;
uint16_t i;
if (ma'lumotlar soni \u003d\u003d STOPPER) (
ma'lumotlar bazasi \u003d STOPPER + 1; / * To'xtashga ruxsat yo'q. * /
}
Agar ((++ ma'lumotlar nuqtasi - bufer)\u003e \u003d MEDIAN_FILTER_SIZE) (
datpoint \u003d bufer; / * Ko'rsatkichlarga ma'lumotlarni ko'paytirish va o'rash. * /
}
Datpoint-\u003e value \u003d ma'lumotlar; / * Yangi ma'lumotlarga nusxalash * /
vorisi \u003d datpoint-\u003e nuqta; / * Ko'rsatkichni eski voris qiymatiga saqlang * /
median \u003d & katta; / * Median dastlab birinchi zanjirda * /
scanold \u003d NULL; / * Dastlab Scanold nolga teng. * /
ko'rish \u003d & katta; / * Zanjirdagi birinchi (eng katta) ma'lumotlarga yo'naltiruvchi ko'rsatkichlar * /
/ * Zanjirdagi birinchi elementni zanjir bilan ajratish alohida holat sifatida * /
if (scan-\u003e point \u003d\u003d datpoint) (agar
scan-\u003e nuqta \u003d voris;
}
scan \u003d scan-\u003e nuqta; / * pastga zanjir * /
/ * Zanjir bo'ylab aylanish, tanaffus orqali oddiy pastadir chiqish. * /
uchun (i \u003d 0; i< MEDIAN_FILTER_SIZE; ++i){
/ * Zanjirdagi toq sonli elementlarni ishlating * /
if (scan-\u003e point \u003d\u003d datpoint) (agar
scan-\u003e nuqta \u003d voris; / * Eski ma'lumotlarni o'chiring. * /
}
If (scan-\u003e value< datum){ /* If datum is larger than scanned value,*/
datpoint-\u003e point \u003d scanold-\u003e nuqta; / * Bu erga zanjir soling. * /
scanold-\u003e point \u003d datpoint; / * Uni zanjir bilan bog'lang. * /
ma'lumotlar bazasi \u003d STOPPER;
};
/ * To'q sonli elementni bajargandan so'ng, median ko'rsatkichni pastga zanjirga o'tkazish * /
median \u003d median-\u003e nuqta; / * Bosqichli o'rtacha ko'rsatkich. * /
agar (skanerlash \u003d\u003d & kichik) (
sindirish; / * Zanjir oxiridagi tanaffus * /
}
scanold \u003d skanerlash; / * Ushbu ko'rsatgichni saqlang va * /
scan \u003d scan-\u003e nuqta; / * pastga zanjir * /
/ * Zanjirda teng raqamlangan buyumlarga ishlov bering. * /
if (scan-\u003e point \u003d\u003d datpoint) (agar
scan-\u003e nuqta \u003d voris;
}
If (scan-\u003e value< datum){
datpoint-\u003e point \u003d scanold-\u003e nuqta;
scanold-\u003e point \u003d datpoint;
ma'lumotlar bazasi \u003d STOPPER;
}
Agar (skanerlash \u003d\u003d & kichik) bo'lsa (
sindirish;
}
Scanold \u003d skanerlash;
scan \u003d scan-\u003e nuqta;
}
return median-\u003e value;
}
Ushbu filtrdan foydalanish uchun har safar yangi kirish qiymatini olganingizda shunchaki funktsiyani chaqiring. Funktsiya oxirgi qabul qilingan o'rtacha qiymatlarni qaytaradi, ularning soni doimiy MEDIAN_FILTER_SIZE tomonidan belgilanadi.
Ushbu algoritm etarli miqdordagi tezkor xotirani ishlatishi mumkin (albatta, bu filtr hajmiga bog'liq), chunki u kirish qiymatlari va ko'rsatkichlarni strukturalarga saqlaydi. Ammo, agar bu muammo bo'lmasa, unda algoritmdan foydalanish juda yaxshi, chunki u tartibli algoritmlarga qaraganda tezroq ishlaydi.
Agar siz ulardan foydalanmoqchi bo'lsangiz, sizga asosiy kodni taqdim etaman:
agar (ADC_Buffer_Full) (Uint_fast16_t adc_copy;
uint_fast16_t filtrlangan_cnts;
/ * Ma'lumotlarni nusxalash * /
memcpy (adc_copy, ADC_Counts, sizeof (adc_copy));
/ * Saralash * /
shell_sort (adc_copy, MEDIAN_FILTER_SIZE);
/ * O'rta qiymatni oling * /
filtered_cnts \u003d adc_copy [(MEDIAN_FILTER_SIZE - 1U) / 2U];
/ * Muhandislik bo'linmalariga aylantirish * /
…
Do'stlaringiz bilan baham: |