आप किनारों की तलाश नहीं कर रहे हैं ((उच्च और निम्न ग्रे मूल्य के विस्तारित क्षेत्रों के बीच की सीमाएं), आप लकीरें देख रहे हैं (उनके पड़ोस की तुलना में पतली रेखाएं या उज्जवल), इसलिए किनारे फ़िल्टर आदर्श नहीं हो सकते हैं: एक किनारे फ़िल्टर होगा आपको दो फ्लैक्स (लाइन के प्रत्येक तरफ एक) और लाइन के बीच में कम प्रतिक्रिया दें:
जोड़ें : अगर एक किनारे डिटेक्टर और एक रिज डिटेक्टर के बीच अंतर को अधिक स्पष्ट रूप से समझाने के लिए कहा गया है। मैं अग्रिम में माफी मांगता हूं अगर यह जवाब बहुत लंबा हो रहा है।
एक किनारे डिटेक्टर (आमतौर पर) एक पहला व्युत्पन्न ऑपरेटर होता है: यदि आप एक 3D परिदृश्य के रूप में इनपुट छवि की कल्पना करते हैं, तो एक किनारे डिटेक्टर उस परिदृश्य के प्रत्येक बिंदु पर ढलान की स्थिरता को मापता है:
यदि आप एक विस्तारित उज्ज्वल या अंधेरे क्षेत्र की सीमा का पता लगाना चाहते हैं, तो यह ठीक है। लेकिन ओपी की छवि में नसों के लिए यह आपको सिर्फ एक ही देगा: प्रत्येक नस के बाएं और दाएं की रूपरेखा:
यह भी कैनी एज डिटेक्टर परिणामों में "डबल लाइन पैटर्न" की व्याख्या करता है:
जीएक्सy
g(x,y)≈12x2∂2g∂x2+xy∂2g∂x∂y+12y2∂2g∂y2+x∂g∂x+y∂g∂y+g(0,0)
या, मैट्रिक्स रूप में:
g(x,y)≈12(xy).⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟.(xy)+(xy).(∂g∂x∂g∂y)+g(0,0)
⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟
λ1x2+λ2y2λ1λ2
इस फंक्शन का किस तरह का शेप हो सकता है? वास्तव में, ऐसा नहीं है:
लकीरों का पता लगाने के लिए, हम छवि में उन क्षेत्रों को ढूंढना चाहते हैं जो ऊपर दिए गए भूखंडों के अंतिम भाग की तरह दिखते हैं, इसलिए हम उन क्षेत्रों की तलाश कर रहे हैं, जहां हेसियन का प्रमुख आइगेनवेल्यू बड़ा है (मामूली आइगेनवेल्यू की तुलना में)। यह पता लगाने का सबसे सरल तरीका है कि प्रत्येक पिक्सेल पर प्रमुख आइजनवेल्यू की गणना करना है - और यही रिज फ़िल्टर नीचे करता है।
एक रिज फिल्टर शायद बेहतर परिणाम देंगे। मैंने मैथमेटिका का निर्माण किया है RidgeFilter
(जो आपकी छवि में प्रत्येक पिक्सेल पर हेसियन मैट्रिक्स के प्रमुख आइजनवेल्यू की गणना करता है)
जैसा कि आप देख सकते हैं, हर पतली अंधेरी रेखा के लिए केवल एक चोटी है। पैदावार को कम करना और कंकाल बनाना:
कंकाल की छंटाई और छवि से छोटे घटकों (शोर) को हटाने के बाद, मुझे यह अंतिम कंकाल मिलता है:
पूर्ण गणित कोड:
ridges = RidgeFilter[ColorNegate@src];
skeleton = SkeletonTransform[Binarize[ridges, 0.007]];
DeleteSmallComponents[Pruning[skeleton, 50], 50]
जोड़ें:
मैं मतलबी विशेषज्ञ नहीं हूं, मुझे नहीं पता कि इसमें रिज फिल्टर है या नहीं, लेकिन मैं आपको दिखा सकता हूं कि इसे "हाथ से" कैसे लागू किया जाए (फिर, मैटेमैटिक का उपयोग करके)। जैसा कि मैंने कहा, रिज फिल्टर हेसियन मैट्रिक्स का प्रमुख प्रतिजन है। मैं गणितीय रूप में उस प्रतिध्वनि की गणना कर सकता हूं:
eigenvalue=Last[Eigenvalues[(HxxHxyHxyHyy)]]
12(Hxx+Hyy+H2xx+4H2xy−2HxxHyy+H2yy−−−−−−−−−−−−−−−−−−−−−−−√)
HxxHxyHyy