इमेज प्रोसेसिंग ओपनसीवी

Imeja Prosesinga Opanasivi



हम इस लेख में इमेज-प्रोसेसिंग विधियों का अध्ययन करने जा रहे हैं। हम कंप्यूटर विजन और मशीन लर्निंग में कुछ मौलिक लेकिन महत्वपूर्ण विषयों की जांच करेंगे। ये मौलिक इमेज प्रोसेसिंग तकनीक डेटासेट जैसी जटिल समस्याओं को हल कर सकती हैं। नतीजतन, छवि प्रसंस्करण में छह मूलभूत कदम हैं, जो नीचे सूचीबद्ध हैं:
  1. छवि अनुवाद
  2. छवि रोटेशन
  3. छवि अंकगणित
  4. छवि फ़्लिपिंग
  5. इमेज क्रॉपिंग
  6. छवि का आकार बदलना

अब, हम उपरोक्त सभी इमेज प्रोसेसिंग विषयों के बारे में विस्तार से बताएंगे।

1. छवि अनुवाद

इमेज ट्रांसलेशन एक इमेज प्रोसेसिंग विधि है जो इमेज को x और y-एक्सिस के साथ ले जाने में हमारी मदद करती है। हम छवि को ऊपर, नीचे, दाएँ, बाएँ या किसी भी संयोजन में ले जा सकते हैं।







हम अनुवाद मैट्रिक्स को प्रतीक एम के साथ परिभाषित कर सकते हैं, और हम इसे गणितीय रूप में प्रस्तुत कर सकते हैं, जैसा कि नीचे दिखाया गया है:





इस प्रोग्राम के द्वारा हम ट्रांसलेशन इमेज के कांसेप्ट को समझ सकते हैं।





पायथन कोड: हम निम्न कार्यक्रम का नाम इस प्रकार रखेंगे अनुवाद.py .

# आवश्यक पैकेज आयात करें

आयात Numpy जैसा उदा.

आयात argparse

आयात imutil

आयात cv2

# हम तर्क पार्सर लागू करते हैं

ap_obj = argparse. तर्क पार्सर ( )

ap_obj. add_argument ( '-क' , '--छवि' , आवश्यक = सही ,

मदद करना = 'छवि फ़ाइल का स्थान' )

तर्क = किसका ( ap_obj. parse_args ( ) )

# छवि लोड करें और स्क्रीन पर दिखाएं

छवि = cv2. imread ( तर्क [ 'छवि' ] )

cv2. ishow ( 'मूल छवि' , छवि )

# छवि का अनुवाद एक NumPy मैट्रिक्स है जो नीचे दिया गया है:

# [[1, 0, शिफ्टएक्स], [0, 1, शिफ्टवाई]]

# हम छवियों को स्थानांतरित करने के लिए उपरोक्त NumPy मैट्रिक्स का उपयोग करने जा रहे हैं

# एक्स-अक्ष और वाई-अक्ष दिशाएं। इसके लिए हमें बस पिक्सेल वैल्यू पास करनी होगी।

# इस प्रोग्राम में, हम छवि को 30 पिक्सेल दाईं ओर ले जाएंगे

# और 70 पिक्सेल नीचे की ओर.

translation_mat = उदा. फ्लोट32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

image_translation = cv2. WarpAffine ( छवि , translation_mat ,

( छवि। आकार [ 1 ] , छवि। आकार [ 0 ] ) )

cv2. ishow ( 'इमेज ट्रांसलेशन डाउन एंड राइट' , image_translation )

# अब, हम छवियों को साथ में स्थानांतरित करने के लिए उपरोक्त NumPy मैट्रिक्स का उपयोग करने जा रहे हैं

# एक्स-अक्ष (बाएं) और वाई-अक्ष (ऊपर) दिशाएं।

# यहां, हम छवियों को 50 पिक्सेल बाईं ओर ले जा रहे हैं

# और 90 पिक्सेल ऊपर की ओर.

translation_mat = उदा. फ्लोट32 ( [ [ 1 , 0 , - पचास ] , [ 0 , 1 , - 90 ] ] )

image_translation = cv2. WarpAffine ( छवि , translation_mat ,

( छवि। आकार [ 1 ] , छवि। आकार [ 0 ] ) )

cv2. ishow ( 'इमेज ट्रांसलेशन अप एंड लेफ्ट' , image_translation )

cv2. प्रतीक्षा करें ( 0 )

लाइन 1 से 5: हम इस कार्यक्रम के लिए सभी आवश्यक पैकेजों का आयात कर रहे हैं, जैसे OpenCV, argparser, और NumPy। कृपया ध्यान दें कि एक और पुस्तकालय है जो imutils है। यह OpenCV का पैकेज नहीं है। यह केवल एक पुस्तकालय है जो समान छवि प्रसंस्करण को आसानी से दिखाएगा।



जब हम OpenCV स्थापित करते हैं तो पुस्तकालय imutils स्वचालित रूप से शामिल नहीं होंगे। तो imutils को स्थापित करने के लिए, हमें निम्नलिखित विधि का उपयोग करना होगा:

पिप imutils स्थापित करें

लाइन 8 से 15: हमने अपना एग्रीपार्सर बनाया और अपनी छवि को लोड किया।

लाइन 24 से 25: यह कार्यक्रम अनुभाग वह है जहां अनुवाद होता है। अनुवाद मैट्रिक्स हमें बताता है कि छवि को कितने पिक्सेल ऊपर या नीचे या बाएँ या दाएँ ले जाया जाएगा। क्योंकि OpenCV के लिए आवश्यक है कि मैट्रिक्स मान फ़्लोटिंग पॉइंट ऐरे में हो, अनुवाद मैट्रिक्स फ़्लोटिंग पॉइंट सरणियों में मान लेता है।

अनुवाद मैट्रिक्स की पहली पंक्ति इस तरह दिखती है:

मैट्रिक्स की यह पंक्ति x-अक्ष के लिए है। टी का मूल्य एक्स यह तय करेगा कि छवि को बाईं ओर स्थानांतरित किया जाएगा या दाईं ओर। यदि हम एक ऋणात्मक मान पास करते हैं, तो इसका अर्थ है कि छवि बाईं ओर स्थानांतरित हो जाएगी, और यदि मान सकारात्मक है, तो इसका अर्थ है कि छवि दाईं ओर स्थानांतरित हो जाएगी।

अब हम मैट्रिक्स की दूसरी पंक्ति को इस प्रकार परिभाषित करेंगे:

मैट्रिक्स की यह पंक्ति y-अक्ष के लिए है। टी का मूल्य वाई तय करेगा कि छवि को ऊपर या नीचे स्थानांतरित किया जाएगा या नहीं। यदि हम एक ऋणात्मक मान पास करते हैं, तो इसका अर्थ है कि छवि को उल्टा स्थानांतरित कर दिया जाएगा, और यदि मान सकारात्मक है, तो इसका अर्थ है कि छवि को नीचे की ओर स्थानांतरित कर दिया जाएगा।

पिछले कार्यक्रम में 24 पंक्ति में, हम टी को परिभाषित करते हैं एक्स = 30 और टी वाई = 70. इसलिए हम छवि को 30 पिक्सेल दाईं ओर और 70 पिक्सेल नीचे की ओर ले जा रहे हैं।

लेकिन मुख्य छवि अनुवाद प्रक्रिया 25 पंक्ति में होती है, जहाँ हम अनुवाद मैट्रिक्स को परिभाषित करते हैं cv2.warpAffine . इस फ़ंक्शन में, हम तीन पैरामीटर पास कर रहे हैं: पहला पैरामीटर इमेज है, दूसरा पैरामीटर ट्रांसलेशन मैट्रिक्स है, और तीसरा पैरामीटर इमेज डायमेंशन है।

रेखा 27: लाइन 27 आउटपुट में परिणाम प्रदर्शित करेगी।

अब, हम बाएँ और ऊपर के लिए एक और अनुवाद मैट्रिक्स लागू करेंगे। इसके लिए हमें मूल्यों को ऋणात्मक में परिभाषित करना होगा।

लाइन 33 से 34: पिछले प्रोग्राम में लाइन 33 पर, हम टी को परिभाषित करते हैं एक्स = -50 और टी वाई = -90। इसलिए हम छवि को 50 पिक्सेल बाईं ओर और 90 पिक्सेल ऊपर की ओर ले जा रहे हैं। लेकिन मुख्य छवि अनुवाद प्रक्रिया 34 पंक्ति में होती है, जहाँ हम अनुवाद मैट्रिक्स को परिभाषित करते हैं cv2.warpAffine .

रेखा 36 : लाइन 36 परिणाम को आउटपुट में दिखाए अनुसार प्रदर्शित करेगा।

पिछले कोड को चलाने के लिए, हमें नीचे दी गई छवि का पथ देना होगा।

आउटपुट: अजगर translate.py – छवि squirrel.jpg

अब, हम उसी छवि अनुवाद कार्यक्रम का उपयोग करके कार्यान्वित करेंगे imutil पुस्तकालय। इमेज प्रोसेसिंग के लिए इस लाइब्रेरी का उपयोग करना बहुत आसान है। इस पुस्तकालय में, हमें इसके बारे में सोचने की ज़रूरत नहीं है cv2.warpAffine क्योंकि यह पुस्तकालय इसका ख्याल रखेगा। तो आइए imutils लाइब्रेरी का उपयोग करके इस इमेज ट्रांसलेशन प्रोग्राम को लागू करें।

पायथन कोड: हम निम्न कार्यक्रम का नाम इस प्रकार रखेंगे translate_imutils.py .

# आवश्यक पैकेज आयात करें

आयात Numpy जैसा उदा.

आयात argparse

आयात imutil

आयात cv2

# यह फ़ंक्शन छवि अनुवाद को लागू करता है और

# अनुवादित छवि को कॉलिंग फ़ंक्शन पर लौटाता है।

डीईएफ़ अनुवाद करना ( छवि , एक्स , वाई ) :

translation_matrix = उदा. फ्लोट32 ( [ [ 1 , 0 , एक्स ] , [ 0 , 1 , वाई ] ] )

image_translation = cv2. WarpAffine ( छवि , translation_matrix ,

( छवि। आकार [ 1 ] , छवि। आकार [ 0 ] ) )

वापसी image_translation

# तर्क पार्सर का निर्माण करें और तर्कों को पार्स करें

एपी = argparse. तर्क पार्सर ( )

एपी। add_argument ( '-मैं' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि के लिए पथ' )

तर्क = किसका ( एपी। parse_args ( ) )

# छवि लोड करें और स्क्रीन पर प्रदर्शित करें

छवि = cv2. imread ( तर्क [ 'छवि' ] )

cv2. ishow ( 'मूल छवि' , छवि )

image_translation = imutil. अनुवाद करना ( छवि , 10 , 70 )

cv2. ishow ( 'दाईं ओर और नीचे की ओर छवि अनुवाद' ,

image_translation )

cv2. प्रतीक्षा करें ( 0 )

लाइन 9 से 13: कार्यक्रम का यह खंड वह है जहां अनुवाद होता है। अनुवाद मैट्रिक्स हमें सूचित करता है कि छवि को कितने पिक्सेल ऊपर या नीचे या बाएँ या दाएँ ले जाया जाएगा।

इन पंक्तियों को पहले ही समझाया जा चुका है, लेकिन अब हम ट्रांसलेशन () नामक एक फंक्शन बनाने जा रहे हैं और इसमें तीन अलग-अलग पैरामीटर भेजेंगे। छवि ही पहले पैरामीटर के रूप में कार्य करती है। ट्रांसलेशन मैट्रिक्स के x और y मान दूसरे और तीसरे पैरामीटर के अनुरूप हैं।

टिप्पणी : इस ट्रांसलेशन फंक्शन को प्रोग्राम के अंदर परिभाषित करने की कोई आवश्यकता नहीं है क्योंकि यह पहले से ही imutils लाइब्रेरी पैकेज में शामिल है। मैंने सीधे स्पष्टीकरण के लिए कार्यक्रम के भीतर इसका इस्तेमाल किया है। हम इस फ़ंक्शन को सीधे imutils के साथ कॉल कर सकते हैं, जैसा कि पंक्ति 24 में दिखाया गया है।

पंक्ति 24: पिछला कार्यक्रम दिखाएगा कि पंक्ति 24 पर, हम tx = 10 और ty = 70 को परिभाषित करते हैं। इसलिए हम छवि को 10 पिक्सेल दाईं ओर और 70 पिक्सेल नीचे की ओर ले जा रहे हैं।

इस कार्यक्रम में, हम किसी भी cv2.warpAffine कार्यों की परवाह नहीं करते हैं क्योंकि वे पहले से ही imutils लाइब्रेरी पैकेज के अंदर हैं।

पिछले कोड को रन करने के लिए, हमें इमेज का पाथ देना होगा, जैसा कि नीचे दिया गया है:

आउटपुट:

अजगर imutils. पाई --छवि गिलहरी. जेपीजी

2. छवि रोटेशन

हमने पिछले पाठ (या किसी भी संयोजन) में एक छवि को ऊपर, नीचे, बाएँ और दाएँ अनुवाद करने (यानी, शिफ्ट) करने का तरीका जाना। अगला, हम रोटेशन पर चर्चा करेंगे क्योंकि यह इमेज प्रोसेसिंग से संबंधित है।

रोटेशन के रूप में जानी जाने वाली प्रक्रिया में एक चित्र को कोण, थीटा द्वारा घुमाया जाता है। जिस कोण से हम छवि को घुमा रहे हैं वह थीटा द्वारा दर्शाया जाएगा। इसके अतिरिक्त, मैं बाद में घुमाने वाली छवियों को आसान बनाने के लिए रोटेट सुविधा फ़ंक्शन प्रदान करूँगा।

अनुवाद के समान, और शायद आश्चर्यजनक रूप से नहीं, एक कोण से घूर्णन, थीटा निम्नलिखित प्रारूप में एक मैट्रिक्स एम बनाकर निर्धारित किया जाता है:

यह मैट्रिक्स दी गई उत्पत्ति (x, y)-कार्तीय तल के चारों ओर एक वेक्टर थीटा डिग्री (वामावर्त) घुमा सकता है। आमतौर पर, इस परिदृश्य में, मूल चित्र का केंद्र होगा, लेकिन वास्तव में, हम किसी भी यादृच्छिक (x, y) बिंदु को हमारे घूर्णन केंद्र के रूप में निर्दिष्ट कर सकते हैं।

घुमाया गया चित्र R तब मूल छवि I से सीधा मैट्रिक्स गुणन का उपयोग करके बनाया गया है: R = IM

दूसरी ओर, OpenCV अतिरिक्त रूप से (1) स्केल (यानी, आकार बदलें) एक छवि की क्षमता प्रदान करता है और (2) रोटेशन को पूरा करने के लिए एक मनमाना रोटेशन केंद्र प्रदान करता है।

हमारा संशोधित रोटेशन मैट्रिक्स एम नीचे दिखाया गया है:

आइए एक नई फाइल को खोलकर और जनरेट करके शुरू करें Rotate.py :

# आवश्यक पैकेज आयात करना

आयात Numpy जैसा उदा.

आयात argparse

आयात imutil

आयात cv2

# आर्ग्युमेंट पार्सर ऑब्जेक्ट बनाना और तर्क को पार्स करना

apobj = argparse. तर्क पार्सर ( )

apobj. add_argument ( '-क' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि पथ' )

बहस = किसका ( apobj. parse_args ( ) )

छवि = cv2. imread ( बहस [ 'छवि' ] )

cv2. ishow ( 'मूल छवि' , छवि )

# छवि के आयामों का उपयोग करके छवि के केंद्र की गणना करें।

( ऊंचाई , चौड़ाई ) = छवि। आकार [ : 2 ]

( केंद्र एक्स , केंद्र वाई ) = ( चौड़ाई / 2 , ऊंचाई / 2 )

# अब, cv2 का उपयोग करके, हम इमेज को 55 डिग्री तक घुमाएंगे

# रोटेशन मैट्रिक्स निर्धारित करने के लिए getRotationMatrix2D () का उपयोग करें

रोटेशनमैट्रिक्स = cv2. getRotationMatrix2D ( ( केंद्र एक्स , केंद्र वाई ) , 55 , 1.0 )

घुमाई गई छवि = cv2. WarpAffine ( छवि , रोटेशनमैट्रिक्स , ( चौड़ाई , ऊंचाई ) )

cv2. ishow ( 'छवि को 55 डिग्री से घुमाया' , घुमाई गई छवि )

cv2. प्रतीक्षा करें ( 0 )

# छवि अब -85 डिग्री घुमाई जाएगी।

रोटेशनमैट्रिक्स = cv2. getRotationMatrix2D ( ( केंद्र एक्स , केंद्र वाई ) , - 85 , 1.0 )

घुमाई गई छवि = cv2. WarpAffine ( छवि , रोटेशनमैट्रिक्स , ( चौड़ाई , ऊंचाई ) )

cv2. ishow ( 'इमेज को -85 डिग्री से घुमाया गया' , घुमाई गई छवि )

cv2. प्रतीक्षा करें ( 0 )

लाइन 1 से 5: हम इस कार्यक्रम के लिए सभी आवश्यक पैकेजों का आयात कर रहे हैं, जैसे OpenCV, argparser, और NumPy। कृपया ध्यान दें कि एक और पुस्तकालय है जो imutils है। यह OpenCV का पैकेज नहीं है। यह केवल एक लाइब्रेरी है जिसका उपयोग उसी इमेज प्रोसेसिंग को आसानी से दिखाने के लिए किया जाएगा।

जब हम OpenCV स्थापित करते हैं तो पुस्तकालय imutils स्वचालित रूप से शामिल नहीं होंगे। OpenCV imutils को स्थापित करता है। हमें निम्नलिखित विधि का उपयोग करना है:

पिप imutils स्थापित करें

लाइन 8 से 14: हमने अपना एग्रीपार्सर बनाया और अपनी छवि को लोड किया। इस argparser में, हम केवल एक छवि तर्क का उपयोग करते हैं, जो हमें उस छवि का मार्ग बताएगा जिसका उपयोग हम इस कार्यक्रम में रोटेशन को प्रदर्शित करने के लिए करेंगे।

छवि को घुमाते समय, हमें घूर्णन के धुरी बिंदु को परिभाषित करना चाहिए। अधिकांश समय, आप इसके केंद्र के बारे में एक छवि को घुमाना चाहेंगे, लेकिन OpenCV आपको इसके बजाय कोई भी यादृच्छिक बिंदु चुनने की अनुमति देता है। आइए बस छवि को उसके केंद्र के चारों ओर घुमाएं।

लाइन 17 से 18 छवि की चौड़ाई और ऊंचाई क्रमशः लें, और फिर छवि के केंद्र को स्थापित करने के लिए प्रत्येक आयाम को दो से विभाजित करें।

हम एक छवि को घुमाने के लिए एक मैट्रिक्स का निर्माण उसी तरह करते हैं जैसे हमने एक छवि का अनुवाद करने के लिए एक मैट्रिक्स को परिभाषित किया है। हम अभी कॉल करेंगे cv2.getRotationMatrix2D NumPy (जो थोड़ा बोझिल हो सकता है) का उपयोग करके मैन्युअल रूप से मैट्रिक्स बनाने के बजाय लाइन 22 पर कार्य करें।

cv2.getRotationMatrix2D फ़ंक्शन को तीन पैरामीटर की आवश्यकता होती है। पहला इनपुट वांछित घूर्णी कोण है (इस मामले में, छवि का केंद्र)। थीटा का उपयोग यह निर्दिष्ट करने के लिए किया जाता है कि हम छवि को कितनी (वामावर्त) डिग्री घुमाएंगे। यहां, हम इमेज को 45 डिग्री घुमाएंगे। अंतिम विकल्प छवि के आकार से संबंधित है।

इस तथ्य के बावजूद कि हमने अभी तक एक छवि को स्केल करने पर चर्चा नहीं की है, आप यहां 1.0 के साथ एक फ़्लोटिंग-पॉइंट नंबर प्रदान कर सकते हैं जो दर्शाता है कि छवि को उसके मूल अनुपात में उपयोग किया जाना चाहिए। हालाँकि, यदि आपने 2.0 का मान टाइप किया है, तो छवि आकार में दोगुनी हो जाएगी। 0.5 की संख्या उस तरह छवि के आकार को कम कर देती है।

लाइन 22 से 23: से हमारे रोटेशन मैट्रिक्स एम प्राप्त करने के बाद cv2.getRotationMatrix2D फ़ंक्शन, हम अपनी छवि का उपयोग करके घुमाते हैं cv2.warpAffine लाइन 23 पर तकनीक। फ़ंक्शन का पहला इनपुट वह छवि है जिसे हम घुमाना चाहते हैं। हमारी आउटपुट छवि की चौड़ाई और ऊंचाई तब हमारे रोटेशन मैट्रिक्स एम के साथ परिभाषित की जाती है। 23 लाइन पर, छवि को 55 डिग्री से घुमाया जाता है।

आप देख सकते हैं कि हमारी छवि घुमाई गई है।

लाइन 28 से 30 दूसरा चक्कर बनाते हैं। कोड की 22-23 पंक्तियाँ समान हैं, सिवाय इसके कि इस बार हम 55 के विपरीत -85 डिग्री घुमा रहे हैं।

हमने बस इस बिंदु तक इसके केंद्र के चारों ओर एक छवि घुमाई है। क्या होगा अगर हम छवि को एक यादृच्छिक बिंदु के चारों ओर घुमाना चाहते हैं?

आइए एक नई फाइल को खोलकर और जनरेट करके शुरू करें रोटेट.py:

# आवश्यक पैकेज आयात करना

आयात Numpy जैसा उदा.

आयात argparse

आयात imutil

आयात cv2

# आर्ग्युमेंट पार्सर ऑब्जेक्ट बनाना और तर्क को पार्स करना

ap_obj = argparse. तर्क पार्सर ( )

ap_obj. add_argument ( '-क' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि पथ' )

बहस = किसका ( ap_obj. parse_args ( ) )

# छवि लोड करें और स्क्रीन पर प्रदर्शित करें

छवि = cv2. imread ( बहस [ 'छवि' ] )

cv2. ishow ( 'मूल छवि' , छवि )

# छवि के आयामों का उपयोग करके छवि के केंद्र की गणना करें।

( ऊंचाई , चौड़ाई ) = छवि। आकार [ : 2 ]

( केंद्र एक्स , केंद्र वाई ) = ( चौड़ाई / 2 , ऊंचाई / 2 )

# अब, cv2 का उपयोग करके, हम इमेज को 55 डिग्री तक घुमाएंगे

# रोटेशन मैट्रिक्स निर्धारित करने के लिए getRotationMatrix2D () का उपयोग करें

रोटेशनमैट्रिक्स = cv2. getRotationMatrix2D ( ( केंद्र एक्स , केंद्र वाई ) , 55 , 1.0 )

घुमाई गई छवि = cv2. WarpAffine ( छवि , रोटेशनमैट्रिक्स , ( चौड़ाई , ऊंचाई ) )

cv2. ishow ( 'छवि को 55 डिग्री से घुमाया' , घुमाई गई छवि )

cv2. प्रतीक्षा करें ( 0 )

# छवि अब -85 डिग्री घुमाई जाएगी।

रोटेशनमैट्रिक्स = cv2. getRotationMatrix2D ( ( केंद्र एक्स , केंद्र वाई ) , - 85 , 1.0 )

घुमाई गई छवि = cv2. WarpAffine ( छवि , रोटेशनमैट्रिक्स , ( चौड़ाई , ऊंचाई ) )

cv2. ishow ( 'इमेज को -85 डिग्री से घुमाया गया' , घुमाई गई छवि )

cv2. प्रतीक्षा करें ( 0 )

# छवि को किसी मनमाने बिंदु से घुमाएं, केंद्र से नहीं

रोटेशनमैट्रिक्स = cv2. getRotationMatrix2D ( ( सेंटरएक्स - 40 , केंद्र वाई - 40 ) , 55 , 1.0 )

घुमाई गई छवि = cv2. WarpAffine ( छवि , रोटेशनमैट्रिक्स , ( चौड़ाई , ऊंचाई ) )

cv2. ishow ( 'मनमानी बिंदुओं से छवि रोटेशन' , घुमाई गई छवि )

cv2. प्रतीक्षा करें ( 0 )

लाइन 34 से 35: अब, किसी वस्तु को घुमाने के लिए यह कोड बहुत सामान्य प्रतीत होना चाहिए। छवि को एक बिंदु के चारों ओर 40 पिक्सेल बाईं ओर और उसके केंद्र से 40 पिक्सेल ऊपर घुमाने के लिए, हम निर्देश देते हैं cv2.getRotationMatrix2D इसके पहले पैरामीटर पर ध्यान देने के लिए कार्य करें।

जब हम इस घुमाव को लागू करते हैं तो उत्पन्न होने वाली छवि नीचे दिखाई गई है:

हम स्पष्ट रूप से देख सकते हैं कि रोटेशन का केंद्र अब (x, y)-कोऑर्डिनेट है, जो चित्र के परिकलित केंद्र से 40 पिक्सेल बाईं ओर और 40 पिक्सेल ऊपर है।

3. छवि अंकगणित

वास्तव में, छवि अंकगणित डेटा प्रकारों पर कुछ अतिरिक्त प्रतिबंधों के साथ केवल मैट्रिक्स जोड़ है जिसे हम बाद में कवर करेंगे।

आइए रैखिक बीजगणित के कुछ सुंदर मूल सिद्धांतों पर जाने के लिए कुछ समय निकालें।

अगले दो मैट्रिसेस के संयोजन पर विचार करें:

मैट्रिक्स जोड़ का परिणाम क्या होगा? सरल उत्तर मैट्रिक्स प्रविष्टियों का योग है, तत्व द्वारा तत्व:

काफी सरल, है ना?

हम सभी इस समय जोड़ और घटाव के मूलभूत संचालन को समझते हैं। हालाँकि, हमें छवियों के साथ काम करते समय अपने रंग स्थान और डेटा प्रकार द्वारा लगाए गए प्रतिबंधों के प्रति सचेत रहना चाहिए।

उदाहरण के लिए, आरजीबी छवियों में पिक्सेल [0, 255] के बीच आते हैं। क्या होता है यदि हम 250 की तीव्रता वाले पिक्सेल को देखते हुए उसमें 10 जोड़ने का प्रयास करते हैं?

यदि हम मानक अंकगणितीय सिद्धांतों को लागू करते हैं तो हम 260 के मान पर पहुंचेंगे। 260 मान्य मान नहीं है, क्योंकि आरजीबी छवियों को 8-बिट अहस्ताक्षरित पूर्णांक के रूप में दर्शाया गया है।

तो क्या होना चाहिए? क्या हमें यह सुनिश्चित करने के लिए जांच करनी चाहिए कि कोई पिक्सेल [0, 255] की सीमा से परे नहीं है, प्रत्येक पिक्सेल को 0 और 255 के बीच मान रखने के लिए क्लिप करना चाहिए?

या क्या हम 'चारों ओर लपेटते हैं' और एक मॉड्यूलस ऑपरेशन करते हैं? मापांक नियमों के अनुसार, 10 को 255 में जोड़ने पर केवल 9 का मान प्राप्त होगा।

[0, 255] की सीमा से बाहर की छवियों को कैसे जोड़ा और घटाया जाना चाहिए?

सच तो यह है कि कोई सही या गलत तकनीक नहीं होती; यह सब इस बात पर निर्भर करता है कि आप अपने पिक्सेल के साथ कैसे काम कर रहे हैं और आप क्या हासिल करना चाहते हैं।

लेकिन याद रखें कि OpenCV में जोड़ने और NumPy में जोड़ने के बीच अंतर हैं। मॉड्यूलस अंकगणित और 'रैप अराउंड' NumPy द्वारा किया जाएगा। इसके विपरीत, OpenCV क्लिपिंग को निष्पादित करेगा और सुनिश्चित करेगा कि पिक्सेल मान [0, 255] सीमा को कभी न छोड़ें।

आइए नाम की एक नई फाइल बनाकर शुरू करें अंकगणित.py और इसे खोलना:

# अजगर अंकगणित.py --image squirrel.jpg

# आवश्यक पैकेज आयात करना

आयात Numpy जैसा उदा.

आयात argparse

आयात imutil

आयात cv2

# आर्ग्युमेंट पार्सर ऑब्जेक्ट बनाना और तर्क को पार्स करना

apObj = argparse. तर्क पार्सर ( )

apObj. add_argument ( '-क' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि पथ' )

बहस = किसका ( apObj. parse_args ( ) )

छवि = cv2. imread ( बहस [ 'छवि' ] )

cv2. ishow ( 'मूल छवि' , छवि )

'''

हमारे पिक्सेल का मान [0, 255] की सीमा में होगा

चूँकि छवियाँ NumPy सरणियाँ हैं, जिन्हें अहस्ताक्षरित 8-बिट पूर्णांक के रूप में संग्रहीत किया जाता है।

cv2.add और cv2.subtract जैसे कार्यों का उपयोग करते समय, मानों को क्लिप किया जाएगा

इस श्रेणी में भले ही वे इसमें जोड़े या बाहर से घटाए गए हों

[0, 255] सीमा। यहाँ एक उदाहरण है:

'''


प्रिंट ( 'अधिकतम 255: {}' . प्रारूप ( एसटीआर ( cv2. जोड़ना ( उदा. uint8 ( [ 201 ] ) ,

उदा. uint8 ( [ 100 ] ) ) ) ) )

प्रिंट ( 'न्यूनतम 0: {}' . प्रारूप ( एसटीआर ( cv2. घटाना ( उदा. uint8 ( [ 60 ] ) ,

उदा. uint8 ( [ 100 ] ) ) ) ) )

'''

NumPy का उपयोग करके इन सरणियों के साथ अंकगणितीय संचालन करते समय,

मूल्य को क्लिप करने के बजाय चारों ओर लपेटा जाएगा

[0, 255]श्रेणी। छवियों का उपयोग करते समय, इसे रखना आवश्यक है

मन में।

'''


प्रिंट ( 'चारों ओर लपेट दो: {}' . प्रारूप ( एसटीआर ( उदा. uint8 ( [ 201 ] ) + उदा. uint8 ( [ 100 ] ) ) ) )

प्रिंट ( 'चारों ओर लपेट दो: {}' . प्रारूप ( एसटीआर ( उदा. uint8 ( [ 60 ] ) - उदा. uint8 ( [ 100 ] ) ) ) )

'''

आइए अपनी छवि में प्रत्येक पिक्सेल की चमक को 101 से गुणा करें।

ऐसा करने के लिए, हम अपने मैट्रिक्स के समान आकार का एक NumPy सरणी उत्पन्न करते हैं,

एक से भरे, और एक भरी हुई सरणी बनाने के लिए इसे 101 से गुणा करें

101 के साथ। अंत में, हम दो छवियों को मर्ज करते हैं।

आप देखेंगे कि छवि अब 'उज्ज्वल' है।

'''


आव्यूह = उदा. लोगों ( छवि। आकार , dtype = 'uint8' ) * 101

image_added = cv2. जोड़ना ( छवि , आव्यूह )

cv2. ishow ( 'जोड़ा गया छवि परिणाम' , image_added )

#इसी प्रकार हम लेने से अपनी छवि को काला कर सकते हैं

# 60 सभी पिक्सेल से दूर।

आव्यूह = उदा. लोगों ( छवि। आकार , dtype = 'uint8' ) * 60

image_subtracted = cv2. घटाना ( छवि , आव्यूह )

cv2. ishow ( 'घटाया छवि परिणाम' , image_subtracted )

cv2. प्रतीक्षा करें ( 0 )

लाइन 1 से 16 तक हमारी सामान्य प्रक्रिया को पूरा करने के लिए उपयोग किया जाएगा, जिसमें हमारे पैकेजों को आयात करना, हमारे तर्क पार्सर को कॉन्फ़िगर करना और हमारी छवि को लोड करना शामिल है।

याद करें कि मैंने पहले कैसे OpenCV और NumPy जोड़ के बीच के अंतर पर चर्चा की थी? अब जब हमने इसे अच्छी तरह से कवर कर लिया है, आइए इसे समझने के लिए एक विशिष्ट मामले को देखें।

दो 8-बिट अहस्ताक्षरित पूर्णांक NumPy सरणियों को परिभाषित किया गया है रेखा 26 . पहली सरणी में 201 का मान एकमात्र तत्व है। हालाँकि केवल एक सदस्य दूसरी सरणी में है, इसका मान 100 है। मान तब OpenCV के cv2.add फ़ंक्शन का उपयोग करके जोड़े जाते हैं।

आप क्या परिणाम होने का अनुमान लगाते हैं?

पारंपरिक अंकगणितीय सिद्धांतों के अनुसार, उत्तर 301 होना चाहिए। लेकिन याद रखें कि हम 8-बिट अहस्ताक्षरित पूर्णांकों के साथ काम कर रहे हैं, जो केवल [0, 255] की सीमा में हो सकता है। क्योंकि हम cv2.add विधि का उपयोग कर रहे हैं, OpenCV क्लिपिंग को संभालता है और यह सुनिश्चित करता है कि जोड़ केवल 255 का अधिकतम परिणाम देता है।

नीचे दी गई सूची की पहली पंक्ति इस कोड को चलाने का परिणाम दिखाती है:

अंकगणित। पाई

अधिकतम 255 : [ [ 255 ] ]

योग वास्तव में 255 की संख्या का उत्पादन करता है।

अनुकरन करना, रेखा 26 घटाव पूरा करने के लिए cv2.subtract का उपयोग करता है। एक बार फिर, हम प्रत्येक में एक तत्व के साथ दो 8-बिट अहस्ताक्षरित पूर्णांक NumPy सरणियों को परिभाषित करते हैं। पहली सरणी का मान 60 है, जबकि दूसरी सरणी का मान 100 है।

हमारा अंकगणित निर्धारित करता है कि घटाव का परिणाम -40 होना चाहिए, लेकिन OpenCV हमारे लिए एक बार फिर क्लिपिंग को संभालता है। हमें पता चलता है कि मान को 0 तक कम कर दिया गया है। नीचे हमारा परिणाम यह प्रदर्शित करता है:

अंकगणित। पाई

कम से कम 0 : [ [ 0 ] ]

सीवी2 का उपयोग करके, 60 घटाव से 100 घटाएं, मान 0 प्राप्त करें।

लेकिन क्या होता है अगर हम गणना करने के लिए OpenCV के स्थान पर NumPy का उपयोग करते हैं?

लाइन 38 और 39 इस समस्या को हल के।

सबसे पहले, दो 8-बिट अहस्ताक्षरित पूर्णांक NumPy सरणियों को एक तत्व के साथ परिभाषित किया गया है। पहली सरणी का मान 201 है, जबकि दूसरी सरणी का मान 100 है। यदि हम cv2.add फ़ंक्शन का उपयोग करते हैं, तो हमारा योग कम हो जाएगा, और 255 का मान वापस आ जाएगा।

दूसरी ओर, NumPy, 'चारों ओर लपेटता है' और कतरन के बजाय मॉडुलो अंकगणित करता है। 255 के मान तक पहुँचने के बाद NumPy लगभग शून्य हो जाता है और फिर 100 चरणों तक पहुँचने तक गिनना शुरू कर देता है। इसकी पुष्टि आउटपुट की पहली लाइन से होती है, जिसे नीचे दिखाया गया है:

अंकगणित। पाई
चारों ओर लपेट दो: [ चार पाच ]

फिर, दो और NumPy सरणियों को परिभाषित किया गया है, एक 50 के मान के साथ और दूसरा 100 के साथ। यह घटाव cv2.subtract विधि द्वारा 0 के परिणाम को वापस करने के लिए ट्रिम किया जाएगा। लेकिन हम जानते हैं कि क्लिपिंग के बजाय, NumPy निष्पादित करता है सापेक्ष अंकगणित। इसके बजाय, मॉडुलो प्रक्रियाएं चारों ओर लपेटती हैं और घटाव के दौरान 0 तक पहुंचने के बाद 255 से पीछे की ओर गिनना शुरू कर देती हैं। हम इसे निम्न आउटपुट से देख सकते हैं:

अंकगणित। पाई

चारों ओर लपेट दो: [ 207 ]

एक बार फिर, हमारा टर्मिनल आउटपुट क्लिपिंग और रैपिंग के बीच के अंतर को प्रदर्शित करता है:

पूर्णांक अंकगणित करते समय वांछित परिणाम को ध्यान में रखना महत्वपूर्ण है। क्या आप [0, 255] श्रेणी के बाहर के किसी भी मान को क्लिप करना चाहते हैं? उसके बाद OpenCV की अंतर्निहित छवि अंकगणितीय तकनीकों का उपयोग करें।

यदि वे [0, 255] और मॉड्यूलस अंकगणितीय परिचालनों की सीमा के बाहर हैं, तो क्या आप मूल्यों को चारों ओर लपेटना चाहते हैं? फिर NumPy सरणियों को हमेशा की तरह जोड़ा और घटाया जाता है।

रेखा 48 हमारी छवि के समान आयामों के साथ एक आयामी NumPy सरणी को परिभाषित करता है। एक बार और, हम सुनिश्चित करते हैं कि हमारा डेटा प्रकार 8-बिट अहस्ताक्षरित पूर्णांक है। हम अपने एक-अंकीय मानों के मैट्रिक्स को 1 के बजाय 101 के मानों से भरने के लिए 101 से गुणा करते हैं। अंत में, हम मूल छवि में 100s के अपने मैट्रिक्स को जोड़ने के लिए cv2.add फ़ंक्शन का उपयोग करते हैं। यह प्रत्येक पिक्सेल की तीव्रता को 101 तक बढ़ाता है और यह भी सुनिश्चित करता है कि 255 से अधिक होने का प्रयास करने वाले किसी भी मान को सीमा [0, 255] तक सीमित कर दिया जाए।

ध्यान दें कि छवि किस तरह स्पष्ट रूप से उज्जवल है और मूल से अधिक 'धुली हुई' दिखाई देती है। ऐसा इसलिए है क्योंकि हम पिक्सल की तीव्रता को 101 तक बढ़ाकर पिक्सल को चमकीले रंगों की ओर ले जा रहे हैं।

छवि की प्रत्येक पिक्सेल तीव्रता से 60 घटाने के लिए, हम पहले लाइन 54 पर एक दूसरी NumPy सरणी स्थापित करते हैं जो 60 से भरी होती है।

इस घटाव के परिणाम निम्नलिखित छवि में दर्शाए गए हैं:

हमारे आस-पास की वस्तुएँ पहले की तुलना में काफी अधिक गहरी दिखाई देती हैं। ऐसा इसलिए है क्योंकि प्रत्येक पिक्सेल से 60 घटाकर, हम पिक्सेल को RGB कलर स्पेस में गहरे क्षेत्रों में ले जा रहे हैं।

4. इमेज फ़्लिपिंग

रोटेशन के समान, किसी छवि को उसके x या y-अक्ष पर फ़्लिप करना OpenCV द्वारा पेश किया गया एक अन्य विकल्प है। यहां तक ​​​​कि अगर फ़्लिपिंग ऑपरेशंस का अक्सर उपयोग नहीं किया जाता है, तो उन्हें जानना कई कारणों से अविश्वसनीय रूप से फायदेमंद होता है, जिन्हें आप तुरंत नहीं देख सकते हैं।

हम एक छोटी स्टार्टअप कंपनी के लिए एक मशीन लर्निंग क्लासिफायर विकसित कर रहे हैं जो छवियों में चेहरों की पहचान करना चाहती है। हमारे सिस्टम के लिए 'सीखने' के लिए कि चेहरा क्या है, हमें नमूना चेहरों के साथ किसी प्रकार के डेटासेट की आवश्यकता होगी। दुर्भाग्य से, कंपनी ने हमें केवल 40 चेहरों का एक छोटा डाटासेट दिया है, और हम अधिक जानकारी एकत्र करने में असमर्थ हैं।

तो फिर हम क्या करें?

चूँकि एक चेहरा एक चेहरा बना रहता है चाहे वह प्रतिबिंबित हो या न हो, हम चेहरे की प्रत्येक छवि को क्षैतिज रूप से फ़्लिप करने में सक्षम होते हैं और अतिरिक्त प्रशिक्षण डेटा के रूप में प्रतिबिंबित संस्करणों का उपयोग करते हैं।

यह उदाहरण मूर्खतापूर्ण और कृत्रिम लग सकता है, लेकिन ऐसा नहीं है। फ़्लिपिंग एक सुविचारित रणनीति है जिसका उपयोग प्रशिक्षण चरण के दौरान अधिक डेटा उत्पन्न करने के लिए मजबूत डीप-लर्निंग एल्गोरिदम द्वारा किया जाता है।

पिछले से यह स्पष्ट है कि इस मॉड्यूल में आप जो इमेज प्रोसेसिंग तरीके सीखते हैं, वे बड़े कंप्यूटर विजन सिस्टम की नींव के रूप में काम करते हैं।

उद्देश्य:

का उपयोग cv2.flip फ़ंक्शन, आप सीखेंगे कि इस सत्र में क्षैतिज और लंबवत छवि को कैसे फ़्लिप करना है।

फ़्लिपिंग अगली छवि हेरफेर है जिसका हम अध्ययन करेंगे। एक छवि के x और y-अक्षों को फ़्लिप किया जा सकता है या दोनों भी। इससे पहले कि हम कोडिंग में गोता लगाएँ, सबसे पहले एक इमेज फ्लिप के परिणामों को देखना सबसे अच्छा है। एक छवि देखें जो निम्न छवि में क्षैतिज रूप से फ़्लिप की गई है:


ध्यान दें कि बाईं ओर हमारी मूल छवि कैसी है और छवि को दाईं ओर क्षैतिज रूप से कैसे दिखाया गया है।

आइए नाम की एक नई फाइल बनाकर शुरू करें flipping.py .

आपने इमेज फ्लिप का एक उदाहरण देखा है, तो चलिए कोड की जांच करते हैं:

# अजगर Flipping.py --image quirrel.jpg

# आवश्यक पैकेज आयात करना

आयात argparse

आयात cv2

# तर्क पार्सर की वस्तु बनाना और तर्क को पार्स करना

apObj = argparse. तर्क पार्सर ( )

apObj. add_argument ( '-मैं' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि पथ' )

बहस = किसका ( apObj. parse_args ( ) )

छवि = cv2. imread ( बहस [ 'छवि' ] )

cv2. ishow ( 'मौलिक' , छवि )

# छवि को क्षैतिज रूप से पलटें

imagefliped = cv2. पलटना ( छवि , 1 )

cv2. ishow ( 'क्षैतिज रूप से फ़्लिप की गई छवि' , imagefliped )

# छवि को लंबवत रूप से फ़्लिप करें

imagefliped = cv2. पलटना ( छवि , 0 )

cv2. ishow ( 'छवि लंबवत रूप से फ़्लिप की गई' , imagefliped )

# छवि दोनों अक्षों के साथ फ़्लिप करें

imagefliped = cv2. पलटना ( छवि , - 1 )

cv2. ishow ( 'क्षैतिज और लंबवत रूप से फ़्लिप किया गया' , imagefliped )

cv2. प्रतीक्षा करें ( 0 )

अपने पैकेजों को आयात करने, अपने इनपुट्स को पार्स करने और डिस्क से अपनी छवि को लोड करने के लिए हम जो कदम उठाते हैं, उन्हें l में नियंत्रित किया जाता है ines 1 से 12 .

cv2.flip फ़ंक्शन को चालू करके रेखा 15 , छवि को क्षैतिज रूप से फ़्लिप करना सरल है। जिस छवि को हम फ्लिप करना चाहते हैं और एक विशिष्ट कोड या ध्वज जो निर्दिष्ट करता है कि छवि को कैसे फ़्लिप करना है, cv2.flip विधि के लिए आवश्यक दो तर्क हैं।

1 के फ्लिप कोड मान का मतलब है कि हम छवि को क्षैतिज रूप से फ़्लिप करने के लिए y-अक्ष के चारों ओर घुमाएंगे ( रेखा 15 ). यदि हम 0 का एक फ्लिप कोड निर्दिष्ट करते हैं, तो हम छवि को एक्स-अक्ष के बारे में घुमाना चाहते हैं ( रेखा 19 ). एक नकारात्मक फ्लिप कोड ( रेखा 23 ) छवि को दोनों अक्षों पर घुमाता है।

इस विषय में सबसे आसान उदाहरणों में से एक छवि को फ़्लिप करना है, जो बुनियादी है।

इसके बाद, हम छवियों को क्रॉप करने पर चर्चा करेंगे और विशिष्ट छवि भागों को निकालने के लिए NumPy सरणी स्लाइस का उपयोग करेंगे।

5. इमेज क्रॉपिंग

क्रॉपिंग, जैसा कि नाम से पता चलता है, ब्याज के क्षेत्र (या बस आरओआई) को चुनने और हटाने की प्रक्रिया है, जो उस छवि का क्षेत्र है जो हमें रूचि देता है।

चेहरे की पहचान करने वाले एप्लिकेशन के लिए चेहरे को छवि से क्रॉप करना होगा। इसके अतिरिक्त, यदि हम छवियों में कुत्तों को खोजने के लिए एक पायथन स्क्रिप्ट बना रहे थे, तो जब हम कुत्ते को ढूंढते हैं तो हम छवि से बाहर निकलना चाहते हैं।

लक्ष्य: हमारा मुख्य लक्ष्य एक छवि से फसल क्षेत्रों के लिए NumPy सरणी टुकड़ा करने की क्रिया से परिचित होना और आसानी से होना है।

फसल : जब हम किसी छवि को क्रॉप करते हैं, तो हमारा लक्ष्य उन बाहरी तत्वों को हटाना होता है, जिनमें हमारी रुचि नहीं है। हमारे ROI को चुनने की प्रक्रिया को अक्सर हमारे हित के क्षेत्र को चुनने के रूप में संदर्भित किया जाता है।

नामक एक नई फाइल बनाएं क्रॉप.पी , इसे खोलें, और निम्न कोड जोड़ें:

# अजगर फसल

# आवश्यक पैकेज आयात करना

आयात cv2

# छवि लोड और स्क्रीन पर प्रदर्शित करें

छवि = cv2. imread ( 'squirrel.jpg' )

प्रिंट ( छवि। आकार )

cv2. ishow ( 'मौलिक' , छवि )

# NumPy सरणी स्लाइस का उपयोग किसी छवि को जल्दी से ट्रिम करने के लिए किया जाता है

# हम छवि से गिलहरी का चेहरा क्रॉप करने जा रहे हैं

squirrelface = छवि [ 35 : 90 , 35 : 100 ]

cv2. ishow ( 'गिलहरी का चेहरा' , squirrelface )

cv2. प्रतीक्षा करें ( 0 )

# और अब, यहां हम पूरे शरीर को क्रॉप करने जा रहे हैं

# गिलहरी का

squirrelbody = छवि [ 35 : 148 , 23 : 143 ]

cv2. ishow ( 'गिलहरी शरीर' , squirrelbody )

cv2. प्रतीक्षा करें ( 0 )

हम डिस्क से लोड की गई छवि का उपयोग करके पायथन और ओपनसीवी में क्रॉपिंग दिखाएंगे लाइन 5 और 6 .

मूल छवि जिसे हम क्रॉप करने जा रहे हैं

केवल बुनियादी क्रॉपिंग तकनीकों का उपयोग करके, हमारा उद्देश्य आसपास के क्षेत्र से गिलहरी के चेहरे और गिलहरी के शरीर को अलग करना है।

हम छवि के बारे में अपने पूर्व ज्ञान का उपयोग करेंगे और मैन्युअल रूप से शरीर और चेहरे के NumPy सरणी स्लाइस की आपूर्ति करेंगे। सामान्य परिस्थितियों में, हम छवि में चेहरे और शरीर को पहचानने के लिए आम तौर पर मशीन लर्निंग और कंप्यूटर विज़न एल्गोरिदम का उपयोग करते हैं। लेकिन फिलहाल चीजों को सीधा रखें और किसी भी पहचान मॉडल को नियोजित करने से बचें।

हम छवि में चेहरे को कोड की केवल एक पंक्ति से पहचान सकते हैं। रेखा 13 , छवि का एक आयत भाग निकालने के लिए, (35, 35) से शुरू करके, हम NumPy सरणी स्लाइस (90, 100) प्रदान करते हैं। यह भ्रामक लग सकता है कि हम क्रॉप को इंडेक्स के साथ ऊंचाई-पहले और चौड़ाई-दूसरे क्रम में खिलाते हैं, जो हम करते हैं, लेकिन ध्यान रखें कि OpenCV छवियों को NumPy सरणियों के रूप में संग्रहीत करता है। परिणामस्वरूप, हमें x-अक्ष से पहले y-अक्ष के लिए मानों की आपूर्ति करनी चाहिए।

NumPy को हमारी क्रॉपिंग करने के लिए निम्नलिखित चार इंडेक्स की आवश्यकता होती है:

प्रारंभ वाई: शुरुआत में y-निर्देशांक। इस उदाहरण के लिए, हम y=35 से शुरू करते हैं।

अंत वाई: Y अंत में समन्वय करता है। y = 90 होने पर हमारी फसल रुक जाएगी।

प्रारंभ x: स्लाइस की शुरुआत x निर्देशांक। फसल x = 35 पर शुरू होती है।

अंत x: स्लाइस का अंत x-अक्ष समन्वय करता है। x=100 पर, हमारा टुकड़ा समाप्त हो गया है।

इसी तरह, हम मूल छवि से क्षेत्रों (23, 35) और (143, 148) को क्रॉप करते हैं ताकि छवि से पूरा शरीर निकाला जा सके रेखा 19 .

आप देख सकते हैं कि छवि को केवल शरीर और चेहरे को दिखाने के लिए क्रॉप किया गया है।

6. छवि का आकार बदलना

किसी छवि की चौड़ाई और ऊँचाई को बढ़ाने या घटाने की प्रक्रिया को स्केलिंग या केवल आकार बदलने के रूप में जाना जाता है। पक्षानुपात, जो छवि का आकार बदलने के दौरान छवि की चौड़ाई और ऊंचाई का अनुपात है, पर विचार किया जाना चाहिए। पहलू अनुपात की उपेक्षा करने से ऐसी छवियां हो सकती हैं जिन्हें स्केल किया गया है जो संकुचित और विकृत दिखाई देती हैं:

हमारी प्रारंभिक छवि बाईं ओर है। दाईं ओर, आपको दो छवियां दिखाई देंगी जिन्हें पहलू अनुपात को बनाए रखे बिना बढ़ाया गया है, छवि की चौड़ाई के अनुपात को उसकी ऊंचाई तक विकृत कर दिया गया है। अपनी छवियों का आकार बदलते समय, आपको आम तौर पर पहलू अनुपात पर विचार करना चाहिए।

हमारे आकार बदलने वाले एल्गोरिदम द्वारा उपयोग की जाने वाली इंटरपोलेशन तकनीक को छवि के आकार को बढ़ाने या घटाने के लिए पिक्सेल के इन पड़ोसों का उपयोग करने के लिए इंटरपोलेशन फ़ंक्शन के उद्देश्य पर भी विचार करना चाहिए।

सामान्य तौर पर, छवि का आकार छोटा करना कहीं अधिक प्रभावी होता है। ऐसा इसलिए है क्योंकि एक छवि से पिक्सेल हटाना सभी प्रक्षेप कार्यों को करने की आवश्यकता है। दूसरी ओर, प्रक्षेप विधि को उन पिक्सेल के बीच 'अंतराल को भरने' की आवश्यकता होगी जो पहले मौजूद नहीं थे यदि छवि का आकार बढ़ाया जाना था।

बाईं ओर हमारी मूल छवि है। केंद्र में छवि को उसके मूल आकार से आधा कर दिया गया है, लेकिन इसके अलावा, छवि की 'गुणवत्ता' में कोई कमी नहीं आई है। फिर भी, दाईं ओर छवि का आकार काफी बढ़ा दिया गया है। यह अब 'उड़ा हुआ' और 'पिक्सेलेटेड' दिखाई देता है।

जैसा कि मैंने पहले कहा था, आप आम तौर पर छवि के आकार को बढ़ाने के बजाय कम करना चाहेंगे। छवि का आकार कम करके, हम कम पिक्सेल का विश्लेषण करते हैं और कम 'शोर' से निपटना पड़ता है, जो छवि प्रसंस्करण एल्गोरिदम को तेज और अधिक सटीक बनाता है।

अनुवाद और रोटेशन दो छवि परिवर्तन हैं जिन्हें अब तक संबोधित किया गया है। अब हम देखेंगे कि इमेज का आकार कैसे बदलें।

अप्रत्याशित रूप से, हम cv2.resize पद्धति का उपयोग करके अपनी छवियों का आकार बदलेंगे। जैसा कि मैंने पहले संकेत दिया था, इस पद्धति का उपयोग करते समय हमें छवि के पहलू अनुपात पर विचार करना चाहिए। लेकिन इससे पहले कि हम बारीकियों में बहुत गहराई से प्रवेश करें, मुझे आपको एक दृष्टांत देने की अनुमति दें:

# अजगर resize.py --image squirrel.jpg

# आवश्यक पैकेज आयात करना

आयात argparse

आयात cv2

# तर्क पार्सर की वस्तु बनाना और तर्क को पार्स करना

apObj = argparse. तर्क पार्सर ( )

apObj. add_argument ( '-क' , '--छवि' , आवश्यक = सही , मदद करना = 'छवि पथ' )

बहस = किसका ( apObj. parse_args ( ) )

# छवि लोड करें और स्क्रीन पर प्रदर्शित करें

छवि = cv2. imread ( बहस [ 'छवि' ] )

cv2. ishow ( 'मौलिक' , छवि )

# छवि को तिरछा दिखने से रोकने के लिए, पहलू अनुपात

# माना या विकृत होना चाहिए; इसलिए, हम पता लगाते हैं कि क्या है

# नई छवि का वर्तमान छवि से अनुपात।

# चलिए अपनी नई छवि की चौड़ाई 160 पिक्सेल बनाते हैं।

पहलू = 160.0 / छवि। आकार [ 1 ]

आयाम = ( 160 , पूर्णांक ( छवि। आकार [ 0 ] * पहलू ) )

# यह लाइन वास्तविक रीसाइज़िंग ऑपरेशंस दिखाएगी

image = cv2. आकार ( छवि , आयाम , प्रक्षेप = cv2. INTER_AREA )

cv2. ishow ( 'आकार बदली गई छवि चौड़ाई' , image )

# क्या होगा अगर हम छवि की ऊंचाई बदलना चाहते हैं? - का उपयोग

# समान सिद्धांत, हम पहलू अनुपात के आधार पर गणना कर सकते हैं

# चौड़ाई के बजाय ऊंचाई पर। आइए स्केल्ड बनाते हैं

# छवि की ऊंचाई 70 पिक्सेल।

पहलू = 70.0 / छवि। आकार [ 0 ]

आयाम = ( पूर्णांक ( छवि। आकार [ 1 ] * पहलू ) , 70 )

# आकार बदलने का कार्य करें

image = cv2. आकार ( छवि , आयाम , प्रक्षेप = cv2. INTER_AREA )

cv2. ishow ( 'आकार बदली गई छवि ऊंचाई' , image )

cv2. प्रतीक्षा करें ( 0 )

लाइन्स 1-14 , हमारे पैकेज आयात करने और हमारे तर्क पार्सर को कॉन्फ़िगर करने के बाद, हम अपनी छवि को लोड और प्रदर्शित करेंगे।

लाइन्स 20 और 21: प्रासंगिक कोडिंग इन पंक्तियों में शुरू होती है . छवि का आकार बदलते समय इसके पहलू अनुपात को ध्यान में रखा जाना चाहिए। छवि की चौड़ाई और ऊंचाई के बीच के अनुपात को पहलू अनुपात के रूप में जाना जाता है।

लम्बाई चौड़ाई पहलू अनुपात है।

यदि हम पक्षानुपात को ध्यान में नहीं रखते हैं, तो हमारे आकार बदलने के परिणाम विकृत हो जाएंगे।

पर रेखा 20 , आकार बदलने के अनुपात की गणना की जाती है। कोड की इस पंक्ति में हम अपनी नई छवि की चौड़ाई 160 पिक्सेल प्रदान करते हैं। हम अपने अनुपात (पहलू अनुपात) को पुरानी चौड़ाई से विभाजित नई चौड़ाई (160 पिक्सेल) के रूप में परिभाषित करते हैं, जिसे हम नई ऊंचाई से पुरानी ऊंचाई के अनुपात की गणना करने के लिए छवि का उपयोग करके एक्सेस करते हैं। आकार [1]।

छवि के नए आयाम पर रेखा 21 अब गणना की जा सकती है कि हम अपना अनुपात जानते हैं। एक बार और, नई छवि की चौड़ाई 160 पिक्सेल होगी। पुरानी ऊंचाई को हमारे अनुपात से गुणा करने और परिणाम को पूर्णांक में बदलने के बाद, ऊंचाई की गणना की जाती है। हम इस ऑपरेशन को करके छवि के मूल पहलू अनुपात को बनाए रख सकते हैं।

रेखा 24 वह जगह है जहां छवि वास्तव में आकार बदल जाती है। जिस छवि का हम आकार बदलना चाहते हैं वह पहला तर्क है, और दूसरा वह आयाम है जिसे हमने नई छवि के लिए गणना की है। हमारी प्रक्षेप विधि, जो वास्तविक छवि को आकार देने के लिए एल्गोरिथम है, अंतिम पैरामीटर है।

अंत में, पर रेखा 25 , हम अपनी स्केल की गई छवि प्रदर्शित करते हैं।

हम अपने अनुपात (पहलू अनुपात) को फिर से परिभाषित करते हैं रेखा 31 . हमारी नई इमेज की ऊंचाई 70 पिक्सल होगी। नई ऊँचाई से मूल ऊँचाई का अनुपात प्राप्त करने के लिए हम 70 को मूल ऊँचाई से विभाजित करते हैं।

अगला, हम नई छवि के आयाम स्थापित करते हैं। नई छवि की ऊंचाई 70 पिक्सेल होगी, जो पहले से ज्ञात है। नई चौड़ाई उत्पन्न करने के लिए हम पुरानी चौड़ाई को अनुपात से गुणा करके छवि के मूल पहलू अनुपात को एक बार और बनाए रख सकते हैं।

छवि को तब वास्तव में आकार दिया जाता है रेखा 35 , और इसे प्रदर्शित किया जाता है रेखा 36.

यहां, हम देख सकते हैं कि हमने पक्षानुपात बनाए रखते हुए अपनी मूल छवि की चौड़ाई और ऊंचाई कम कर दी है। यदि पहलू अनुपात को बनाए नहीं रखा गया तो हमारी छवि विकृत दिखाई देगी।

निष्कर्ष

इस ब्लॉग में, हमने बुनियादी विभिन्न इमेज प्रोसेसिंग अवधारणाओं का अध्ययन किया है। हमने OpenCV पैकेज की मदद से इमेज ट्रांसलेशन देखा है। हमने छवि को ऊपर, नीचे, दाएँ और बाएँ घुमाने के तरीकों को देखा है। जब हम प्रशिक्षण डेटासेट के रूप में देने के लिए समान छवियों का डेटासेट बनाते हैं, तो ये विधियाँ बहुत उपयोगी होती हैं, इसलिए मशीन अलग-अलग छवियों को देखेगी, भले ही वे समान हों। इस लेख में आपको यह भी सिखाया गया है कि रोटेशन मैट्रिक्स का उपयोग करके कार्टेशियन स्पेस में किसी भी बिंदु के आसपास इमेज को कैसे रोटेट किया जाता है। तब आपने पाया कि OpenCV इस मैट्रिक्स का उपयोग करके छवियों को कैसे घुमाता है और कताई छवियों के कुछ चित्र देखे।

इस खंड में जोड़ और घटाव के दो मौलिक (लेकिन महत्वपूर्ण) छवि अंकगणितीय संचालन की जांच की गई। जैसा कि आप देख सकते हैं, मौलिक मैट्रिसेस को जोड़ना और घटाना सभी छवि अंकगणितीय ऑपरेशन हैं।

इसके अतिरिक्त, हमने छवि अंकगणित की विशिष्टताओं की जांच के लिए OpenCV और NumPy का उपयोग किया। इन प्रतिबंधों को ध्यान में रखा जाना चाहिए, अन्यथा आप अपनी छवियों पर अंकगणितीय संचालन निष्पादित करते समय अप्रत्याशित परिणाम प्राप्त करने का जोखिम उठाते हैं।

यह याद रखना महत्वपूर्ण है कि हालांकि NumPy एक मॉड्यूलस ऑपरेशन करता है और 'चारों ओर लपेटता है', OpenCV जोड़ और घटाव सीमा के अंदर फिट होने के लिए सीमा [0, 255] से परे कटौती करता है। अपने स्वयं के कंप्यूटर दृष्टि अनुप्रयोगों को विकसित करते समय, यह याद रखना आपको मुश्किल बगों को शिकार करने से बचने में सहायता करेगा।

छवि फ़्लिपिंग निस्संदेह उन सरल विचारों में से एक है जिन्हें हम इस पाठ्यक्रम में देखेंगे। अधिक प्रशिक्षण डेटा नमूने उत्पन्न करने के लिए फ़्लिपिंग को अक्सर मशीन लर्निंग में नियोजित किया जाता है, जिसके परिणामस्वरूप अधिक शक्तिशाली और विश्वसनीय छवि क्लासिफायरियर होते हैं।

हमने यह भी सीखा कि किसी छवि का आकार बदलने के लिए OpenCV का उपयोग कैसे किया जाता है। आपके द्वारा नियोजित इंटरपोलेशन विधि और अपनी मूल छवि के पहलू अनुपात दोनों पर विचार करना महत्वपूर्ण है, ताकि परिणाम विकृत न दिखाई दे।

अंत में, यह याद रखना महत्वपूर्ण है कि यदि छवि गुणवत्ता एक समस्या है, तो हमेशा बड़ी से छोटी छवि पर स्विच करना सबसे अच्छा होता है। ज्यादातर मामलों में, एक छवि को बड़ा करने से कलाकृतियां बन जाती हैं और इसकी गुणवत्ता खराब हो जाती है।