OpenCV لمعالجة الصور

Opencv Lm Aljt Alswr



سنقوم بدراسة طرق معالجة الصور في هذه المقالة. سوف ندرس بعض الموضوعات الأساسية والحاسمة في رؤية الكمبيوتر والتعلم الآلي. يمكن لتقنيات معالجة الصور الأساسية هذه حل المشكلات المعقدة ، مثل مجموعات البيانات. نتيجة لذلك ، هناك ست خطوات أساسية في معالجة الصور ، وهي مدرجة أدناه:
  1. ترجمة الصور
  2. تدوير الصورة
  3. حساب الصورة
  4. تقليب الصورة
  5. اقتصاص الصورة
  6. تغيير حجم الصورة

الآن ، سنشرح بالتفصيل جميع موضوعات معالجة الصور المذكورة أعلاه.

1. ترجمة الصور

ترجمة الصور هي طريقة لمعالجة الصور تساعدنا على تحريك الصورة على محوري x و y. يمكننا تحريك الصورة لأعلى أو لأسفل أو لليمين أو لليسار أو بأي مجموعة.







يمكننا تعريف مصفوفة الترجمة بالرمز M ، ويمكننا تمثيلها بشكل رياضي ، كما هو موضح أدناه:





يمكننا فهم مفهوم ترجمة الصورة من خلال هذا البرنامج.





كود بايثون: سنحتفظ باسم البرنامج التالي كـ translate.py .

# استيراد الحزم المطلوبة

يستورد حبيبي مثل على سبيل المثال

يستورد جدل

يستورد إموتيل

يستورد cv2

# نقوم بتنفيذ المحلل اللغوي

ap_obj = جدل. حجة محلل ( )

ap_obj. add_argument ( '-ك' و '--صورة' و مطلوب = حقيقي و

يساعد = 'موقع ملف الصورة' )

أرجس = ملك من ( ap_obj. parse_args ( ) )

# قم بتحميل الصورة واعرضها على الشاشة

صورة = cv2. أنا أقرأ ( أرجس [ 'صورة' ] )

cv2. imshow ( 'الصورة_الأصلية' و صورة )

# ترجمة الصورة عبارة عن مصفوفة NumPy والتي ترد أدناه:

# [[1، 0، shiftX]، [0، 1، shiftY]]

# سنستخدم مصفوفة NumPy أعلاه لتحويل الصور على طول ملف

# اتجاهات المحور السيني والمحور ص. لهذا ، علينا ببساطة تمرير قيم البكسل.

# في هذا البرنامج سنقوم بتحريك الصورة 30 بكسل الى اليمين

# و 70 بكسل نحو الأسفل.

ترجمة_سمات = على سبيل المثال تعويم 32 ( [ [ 1 و 0 و 30 ] و [ 0 و 1 و 70 ] ] )

ترجمة الصورة = cv2. الاعوجاج ( صورة و ترجمة_سمات و

( صورة. شكل [ 1 ] و صورة. شكل [ 0 ] ) )

cv2. imshow ( 'ترجمة الصورة لأسفل ولليمين' و ترجمة الصورة )

# الآن ، سنستخدم مصفوفة NumPy أعلاه لتحويل الصور على طول ملف

# اتجاهات المحور س (يسار) والمحور ص (أعلى).

# هنا ، سنقوم بنقل الصور 50 بكسل إلى اليسار

# و 90 بكسل نحو الأعلى.

ترجمة_سمات = على سبيل المثال تعويم 32 ( [ [ 1 و 0 و - خمسون ] و [ 0 و 1 و - 90 ] ] )

ترجمة الصورة = cv2. الاعوجاج ( صورة و ترجمة_سمات و

( صورة. شكل [ 1 ] و صورة. شكل [ 0 ] ) )

cv2. imshow ( 'ترجمة الصورة لأعلى ولليسار' و ترجمة الصورة )

cv2. انتظر ( 0 )

الأسطر من 1 إلى 5: نقوم باستيراد جميع الحزم المطلوبة لهذا البرنامج ، مثل OpenCV و argparser و NumPy. يرجى ملاحظة أن هناك مكتبة أخرى وهي imutils. هذه ليست حزمة من OpenCV. هذه مجرد مكتبة تعرض بسهولة معالجة الصور نفسها.



لن يتم تضمين imutils المكتبة تلقائيًا عند تثبيت OpenCV. حتى يتم تثبيت imutils ، علينا استخدام الطريقة التالية:

نقطة تثبيت imutils

الأسطر 8 إلى 15: أنشأنا agrparser وقمنا بتحميل صورتنا.

السطور من 24 إلى 25: قسم البرنامج هذا هو المكان الذي تحدث فيه الترجمة. تخبرنا مصفوفة الترجمة عن عدد وحدات البكسل التي سيتم تحريكها لأعلى أو لأسفل أو لليسار أو لليمين. نظرًا لأن OpenCV يتطلب أن تكون قيمة المصفوفة في مصفوفة ذات فاصلة عائمة ، فإن مصفوفة الترجمة تأخذ قيمًا في مصفوفات الفاصلة العائمة.

يبدو الصف الأول من مصفوفة الترجمة كما يلي:

هذا الصف من المصفوفة لمحور x. قيمة t x سيقرر ما إذا كان سيتم نقل الصورة إلى الجانب الأيسر أو الأيمن. إذا مررنا قيمة سالبة ، فهذا يعني أنه سيتم إزاحة الصورة إلى الجانب الأيسر ، وإذا كانت القيمة موجبة ، فهذا يعني أن الصورة ستنتقل إلى الجانب الأيمن.

سنقوم الآن بتعريف الصف الثاني من المصفوفة على النحو التالي:

هذا الصف من المصفوفة لمحور ص. قيمة t ص سيقرر ما إذا كان سيتم نقل الصورة إلى أعلى أو أسفل. إذا مررنا قيمة سالبة ، فهذا يعني أن الصورة ستتحول إلى الجانب العلوي ، وإذا كانت القيمة موجبة ، فهذا يعني أن الصورة ستنتقل إلى الجانب السفلي.

في البرنامج السابق في السطر 24 ، نحدد حرف t x = 30 ور ص = 70. لذلك نقوم بتحريك الصورة 30 بكسل نحو الجانب الأيمن و 70 بكسل للأسفل.

لكن عملية ترجمة الصور الرئيسية تتم في السطر 25 ، حيث نحدد مصفوفة الترجمة الملف الشخصي . في هذه الوظيفة ، نقوم بتمرير ثلاث معاملات: المعلمة الأولى هي الصورة ، والمعامل الثاني هو مصفوفة الترجمة ، والمعامل الثالث هو بُعد الصورة.

السطر 27: سيعرض السطر 27 النتيجة في الإخراج.

الآن ، سنقوم بتنفيذ مصفوفة ترجمة أخرى للجانب الأيسر والصاعد. لهذا ، علينا تحديد القيم السلبية.

السطر 33 إلى 34: في البرنامج السابق في السطر 33 ، نحدد حرف t x = -50 ور ص = -90. لذلك نقوم بتحريك الصورة 50 بكسل نحو الجانب الأيسر و 90 بكسل للأعلى. لكن عملية ترجمة الصور الرئيسية تتم في السطر 34 ، حيث نحدد مصفوفة الترجمة الملف الشخصي .

السطر 36 : سيعرض السطر 36 النتيجة كما هو موضح في الإخراج.

لتشغيل الكود السابق ، يتعين علينا إعطاء مسار الصورة كما هو موضح أدناه.

انتاج: python translate.py –image squirrel.jpg

الآن ، سنقوم بتنفيذ نفس برنامج ترجمة الصور باستخدام امتداد إموتيل مكتبة. هذه المكتبة سهلة الاستخدام للغاية لمعالجة الصور. في هذه المكتبة ، لا يتعين علينا التفكير في الملف الشخصي لأن هذه المكتبة ستهتم بهذا. لذلك دعونا ننفذ برنامج ترجمة الصور هذا باستخدام مكتبة imutils.

كود بايثون: سنحتفظ باسم البرنامج التالي كـ translate_imutils.py .

# استيراد الحزم الضرورية

يستورد حبيبي مثل على سبيل المثال

يستورد جدل

يستورد إموتيل

يستورد cv2

# تنفذ هذه الوظيفة ترجمة الصور وملفات

# يعيد الصورة المترجمة إلى وظيفة الاستدعاء.

def ترجمة ( صورة و x و ص ) :

ترجمة_مصفوفة = على سبيل المثال تعويم 32 ( [ [ 1 و 0 و x ] و [ 0 و 1 و ص ] ] )

ترجمة الصورة = cv2. الاعوجاج ( صورة و ترجمة_مصفوفة و

( صورة. شكل [ 1 ] و صورة. شكل [ 0 ] ) )

إرجاع ترجمة الصورة

# بناء المحلل اللغوي للحجة وتحليل الحجج

ا ف ب = جدل. حجة محلل ( )

ا ف ب. add_argument ( '-أنا' و '--صورة' و مطلوب = حقيقي و يساعد = 'الطريق إلى الصورة' )

أرجس = ملك من ( ا ف ب. parse_args ( ) )

# قم بتحميل الصورة وعرضها على الشاشة

صورة = cv2. أنا أقرأ ( أرجس [ 'صورة' ] )

cv2. imshow ( 'الصورة_الأصلية' و صورة )

ترجمة الصورة = إموتيل. ترجمة ( صورة و 10 و 70 )

cv2. imshow ( 'ترجمة الصور إلى اليمين والجانب السلبي' و

ترجمة الصورة )

cv2. انتظر ( 0 )

السطور من 9 إلى 13: هذا القسم من البرنامج هو المكان الذي تحدث فيه الترجمة. تُعلمنا مصفوفة الترجمة بعدد وحدات البكسل التي سيتم تحريكها لأعلى أو لأسفل أو إلى اليسار أو اليمين.

تم شرح هذه الأسطر بالفعل ، لكننا الآن بصدد إنشاء وظيفة تسمى translate () وإرسال ثلاث معلمات مميزة إليها. الصورة نفسها بمثابة المعلمة الأولى. تتوافق قيم x و y لمصفوفة الترجمة مع المعلمات الثانية والثالثة.

ملحوظة : ليست هناك حاجة لتعريف وظيفة الترجمة هذه داخل البرنامج لأنها مدرجة بالفعل في حزمة مكتبة imutils. لقد استخدمته داخل البرنامج من أجل شرح مباشر. يمكننا استدعاء هذه الدالة مباشرة مع imutils ، كما هو موضح في السطر 24.

السطر 24: سيوضح البرنامج السابق أنه في السطر 24 ، نحدد tx = 10 و ty = 70. لذلك نقوم بتحريك الصورة بمقدار 10 بكسل نحو الجانب الأيمن و 70 بكسل للأسفل.

في هذا البرنامج ، لا نهتم بأي من وظائف cv2.warpAffine لأنها موجودة بالفعل داخل حزمة مكتبة imutils.

لتشغيل الكود السابق ، يتعين علينا إعطاء مسار الصورة ، كما هو موضح أدناه:

انتاج:

الثعبان imutils. السنة التحضيرية - صورة السنجاب. jpg

2. دوران الصورة

لقد راجعنا كيفية ترجمة (أي إزاحة) صورة لأعلى ولأسفل ولليسار ولليمين في الدرس السابق (أو أي مجموعة). بعد ذلك ، سنناقش التدوير من حيث صلته بمعالجة الصور.

يتم تدوير الصورة بزاوية ثيتا في عملية تعرف باسم الدوران. ستمثل ثيتا الزاوية التي نقوم بتدوير الصورة بها. بالإضافة إلى ذلك ، سأقدم لاحقًا وظيفة ملاءمة التدوير لجعل تدوير الصور أكثر بساطة.

على غرار الترجمة ، وربما ليس من المستغرب ، الدوران بزاوية ، يتم تحديد ثيتا من خلال بناء مصفوفة M بالتنسيق التالي:

قد تقوم هذه المصفوفة بتدوير متجه ثيتا درجات (عكس اتجاه عقارب الساعة) حول الأصل المعطى (س ، ص) - المستوى الكارتوني. عادةً ، في هذا السيناريو ، يكون الأصل هو مركز الصورة ، ولكن في الواقع ، قد نعيّن أي نقطة عشوائية (x ، y) كمركز دوران خاص بنا.

ثم يتم إنشاء الصورة التي تم تدويرها R من الصورة الأصلية I باستخدام عملية ضرب المصفوفة المباشرة: R = IM

من ناحية أخرى ، يوفر OpenCV أيضًا القدرة على (1) قياس (أي تغيير حجم) صورة و (2) توفير مركز دوران تعسفي لإجراء الدوران حولها.

مصفوفة الدوران المعدلة الخاصة بنا موضحة أدناه:

لنبدأ بفتح وإنشاء ملف جديد يسمى rotate.py :

# استيراد الحزم المطلوبة

يستورد حبيبي مثل على سبيل المثال

يستورد جدل

يستورد إموتيل

يستورد cv2

# إنشاء الكائن المحلل اللغوي وتحليل الوسيطة

apobj = جدل. حجة محلل ( )

apobj. add_argument ( '-ك' و '--صورة' و مطلوب = حقيقي و يساعد = 'مسار الصورة' )

الحجج = ملك من ( apobj. parse_args ( ) )

صورة = cv2. أنا أقرأ ( الحجج [ 'صورة' ] )

cv2. imshow ( 'الصورة_الأصلية' و صورة )

# احسب مركز الصورة باستخدام أبعاد الصورة.

( ارتفاع و العرض ) = صورة. شكل [ : 2 ]

( المركز X و المركز ص ) = ( العرض / 2 و ارتفاع / 2 )

# الآن ، باستخدام cv2 ، سنقوم بتدوير الصورة بمقدار 55 درجة إلى

# تحديد مصفوفة الدوران باستخدام getRotationMatrix2D ()

التناوب = cv2. getRotationMatrix2D ( ( المركز X و المركز ص ) و 55 و 1.0 )

استدارة الصورة = cv2. الاعوجاج ( صورة و التناوب و ( العرض و ارتفاع ) )

cv2. imshow ( 'تم تدوير الصورة بمقدار 55 درجة' و استدارة الصورة )

cv2. انتظر ( 0 )

# سيتم الآن تدوير الصورة بمقدار -85 درجة.

التناوب = cv2. getRotationMatrix2D ( ( المركز X و المركز ص ) و - 85 و 1.0 )

استدارة الصورة = cv2. الاعوجاج ( صورة و التناوب و ( العرض و ارتفاع ) )

cv2. imshow ( 'تم تدوير الصورة بـ -85 درجة' و استدارة الصورة )

cv2. انتظر ( 0 )

الأسطر من 1 إلى 5: نقوم باستيراد جميع الحزم المطلوبة لهذا البرنامج ، مثل OpenCV و argparser و NumPy. يرجى ملاحظة أن هناك مكتبة أخرى وهي imutils. هذه ليست حزمة من OpenCV. هذه مجرد مكتبة سيتم استخدامها لإظهار نفس معالجة الصور بسهولة.

لن يتم تضمين imutils المكتبة تلقائيًا عند تثبيت OpenCV. OpenCV يقوم بتثبيت imutils. علينا استخدام الطريقة التالية:

نقطة تثبيت imutils

الأسطر 8 إلى 14: أنشأنا agrparser وقمنا بتحميل صورتنا. في هذا المحلل ، نستخدم حجة صورة واحدة فقط ، والتي ستخبرنا بمسار الصورة التي سنستخدمها في هذا البرنامج لتوضيح الدوران.

عند تدوير صورة ، يجب أن نحدد النقطة المحورية للدوران. في معظم الأوقات ، سترغب في تدوير صورة حول مركزها ، لكن OpenCV يسمح لك باختيار أي نقطة عشوائية بدلاً من ذلك. دعونا ببساطة ندير الصورة حول مركزها.

الخطوط 17 إلى 18 خذ عرض الصورة وارتفاعها ، على التوالي ، ثم قسّم كل بُعد على اثنين لإنشاء مركز الصورة.

نقوم ببناء مصفوفة لتدوير الصورة بنفس الطريقة التي حددنا بها مصفوفة لترجمة الصورة. سنتصل فقط بـ cv2.getRotationMatrix2D تعمل على السطر 22 بدلاً من إنشاء المصفوفة يدويًا باستخدام NumPy (والذي قد يكون مرهقًا بعض الشيء).

ال cv2.getRotationMatrix2D تتطلب الوظيفة ثلاث معلمات. المدخل الأول هو زاوية الدوران المطلوبة (في هذه الحالة ، مركز الصورة). ثم يتم استخدام ثيتا لتحديد عدد درجات (عكس اتجاه عقارب الساعة) التي سنقوم بتدوير الصورة. هنا ، سندير الصورة 45 درجة. يرتبط الخيار الأخير بحجم الصورة.

بصرف النظر عن حقيقة أننا لم نناقش بعد تحجيم الصورة ، يمكنك تقديم رقم فاصلة عائمة هنا مع 1.0 للإشارة إلى أنه يجب استخدام الصورة بنسبها الأصلية. ومع ذلك ، إذا قمت بكتابة قيمة 2.0 ، فسوف يتضاعف حجم الصورة. عدد 0.5 يقلل من حجم الصورة من هذا القبيل.

السطر 22 إلى 23: بعد استلام مصفوفة الدوران الخاصة بنا M من cv2.getRotationMatrix2D وظيفة ، نقوم بتدوير صورتنا باستخدام الملف الشخصي التقنية الموجودة في السطر 23. المدخل الأول للوظيفة هو الصورة التي نريد تدويرها. يتم بعد ذلك تحديد عرض وارتفاع الصورة الناتجة ، جنبًا إلى جنب مع مصفوفة الدوران M. في السطر 23 ، يتم تدوير الصورة بمقدار 55 درجة.

يمكنك ملاحظة أنه تم تدوير صورتنا.

الخطوط 28 إلى 30 تشكل الدوران الثاني. السطور من 22 إلى 23 من الشفرة متطابقة ، باستثناء أننا هذه المرة نديرها بمقدار -85 درجة مقابل 55.

لقد قمنا ببساطة بتدوير صورة حول مركزها حتى هذه النقطة. ماذا لو أردنا تدوير الصورة حول نقطة عشوائية؟

لنبدأ بفتح وإنشاء ملف جديد يسمى rotate.py:

# استيراد الحزم المطلوبة

يستورد حزر مثل على سبيل المثال

يستورد جدل

يستورد إموتيل

يستورد cv2

# إنشاء الكائن المحلل اللغوي وتحليل الوسيطة

ap_obj = جدل. حجة محلل ( )

ap_obj. add_argument ( '-ك' و '--صورة' و مطلوب = حقيقي و يساعد = 'مسار الصورة' )

جدال = ملك من ( ap_obj. parse_args ( ) )

# قم بتحميل الصورة وعرضها على الشاشة

صورة = cv2. أنا أقرأ ( جدال [ 'صورة' ] )

cv2. imshow ( 'الصورة_الأصلية' و صورة )

# احسب مركز الصورة باستخدام أبعاد الصورة.

( ارتفاع و العرض ) = صورة. شكل [ : 2 ]

( المركز X و المركز ص ) = ( العرض / 2 و ارتفاع / 2 )

# الآن ، باستخدام cv2 ، سنقوم بتدوير الصورة بمقدار 55 درجة إلى

# تحديد مصفوفة الدوران باستخدام getRotationMatrix2D ()

التناوب = cv2. getRotationMatrix2D ( ( المركز X و المركز ص ) و 55 و 1.0 )

استدارة الصورة = cv2. الاعوجاج ( صورة و التناوب و ( العرض و ارتفاع ) )

cv2. imshow ( 'تم تدوير الصورة بمقدار 55 درجة' و استدارة الصورة )

cv2. انتظر ( 0 )

# سيتم تدوير الصورة الآن بمقدار -85 درجة.

التناوب = cv2. getRotationMatrix2D ( ( المركز X و المركز ص ) و - 85 و 1.0 )

استدارة الصورة = cv2. الاعوجاج ( صورة و التناوب و ( العرض و ارتفاع ) )

cv2. imshow ( 'تم تدوير الصورة بـ -85 درجة' و استدارة الصورة )

cv2. انتظر ( 0 )

# دوران الصورة من نقطة اعتباطية ، وليس من المركز

التناوب = cv2. getRotationMatrix2D ( ( المركز X - 40 و المركز ص - 40 ) و 55 و 1.0 )

استدارة الصورة = cv2. الاعوجاج ( صورة و التناوب و ( العرض و ارتفاع ) )

cv2. imshow ( 'تدوير الصورة من نقاط عشوائية' و استدارة الصورة )

cv2. انتظر ( 0 )

السطر من 34 إلى 35: الآن ، يجب أن يبدو هذا الرمز شائعًا جدًا لتدوير كائن. لتدوير الصورة حول نقطة 40 بكسل إلى اليسار و 40 بكسل فوق مركزها ، فإننا نوجه ملف cv2.getRotationMatrix2D تعمل على الانتباه إلى المعلمة الأولى.

الصورة التي تم إنتاجها عند تطبيق هذا الدوران موضحة أدناه:

يمكننا أن نرى بوضوح أن مركز الدوران الآن هو التنسيق (س ، ص) ، وهو 40 بكسل إلى اليسار و 40 بكسل فوق مركز الصورة المحسوب.

3. حساب الصور

في الواقع ، يعد حساب الصورة مجرد إضافة مصفوفة مع بعض القيود الإضافية على أنواع البيانات التي سنغطيها لاحقًا.

دعونا نتوقف لحظة لاستعراض بعض أساسيات الجبر الخطي.

ضع في اعتبارك دمج المصفوفتين التاليتين:

ما النتيجة التي ستنتجها إضافة المصفوفة؟ الجواب البسيط هو مجموع إدخالات المصفوفة ، عنصرًا عنصرًا:

بسيط بما فيه الكفاية ، أليس كذلك؟

نحن جميعًا نفهم العمليات الأساسية للجمع والطرح في هذا الوقت. ومع ذلك ، يجب أن نضع في اعتبارنا القيود التي تفرضها مساحة اللون ونوع البيانات لدينا أثناء العمل مع الصور.

البيكسلات في صور RGB ، على سبيل المثال ، تقع بين [0 ، 255]. ماذا يحدث إذا حاولنا إضافة 10 إلى بكسل بقوة 250 أثناء النظر إليه؟

سنصل إلى القيمة 260 إذا طبقنا مبادئ حسابية قياسية. 260 ليست قيمة صالحة ، حيث يتم تمثيل صور RGB كأعداد صحيحة 8 بت بدون إشارة.

إذن ما الذي يجب أن يحدث؟ هل يجب أن نجري فحصًا للتأكد من عدم وجود بكسل خارج نطاق [0 ، 255] ، مع اقتطاع كل بكسل ليكون له قيمة بين 0 و 255؟

أم أننا 'نلتف' ونجري عملية معامل؟ وفقًا لقواعد المعامل ، فإن إضافة 10 إلى 255 ستؤدي فقط إلى الحصول على القيمة 9.

كيف يجب معالجة عمليات الجمع والطرح للصور التي تتجاوز نطاق [0 ، 255]؟

الحقيقة أنه لا يوجد أسلوب صحيح أو خاطئ. كل هذا يتوقف على كيفية عملك مع وحدات البكسل وما تأمل في تحقيقه.

لكن تذكر أن هناك اختلافات بين الإضافة في OpenCV والإضافة في NumPy. سيتم إجراء حساب المعامل و 'الالتفاف' بواسطة NumPy. في المقابل ، سيقوم OpenCV بتنفيذ القطع والتأكد من أن قيم البكسل لا تترك النطاق [0 ، 255].

لنبدأ بإنشاء ملف جديد يسمى الحساب وفتحه:

# python arithmetic.py --image squirrel.jpg

# استيراد الحزم المطلوبة

يستورد حبيبي مثل على سبيل المثال

يستورد جدل

يستورد إموتيل

يستورد cv2

# إنشاء الكائن المحلل اللغوي وتحليل الوسيطة

apObj = جدل. حجة محلل ( )

apObj. add_argument ( '-ك' و '--صورة' و مطلوب = حقيقي و يساعد = 'مسار الصورة' )

الحجج = ملك من ( apObj. parse_args ( ) )

صورة = cv2. أنا أقرأ ( الحجج [ 'صورة' ] )

cv2. imshow ( 'الصورة_الأصلية' و صورة )

''

ستكون قيم وحدات البكسل الخاصة بنا في النطاق [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

مضاف للصورة = cv2. يضيف ( صورة و مصفوفة )

cv2. imshow ( 'نتيجة الصورة المضافة' و مضاف للصورة )

# بطريقة مماثلة ، قد نجعل صورتنا أكثر قتامة من خلال التقاطها

# 60 بعيدًا عن جميع وحدات البكسل.

مصفوفة = على سبيل المثال منها ( صورة. شكل و dtype = 'uint8' ) * 60

الصورة_المطروحة = cv2. طرح او خصم ( صورة و مصفوفة )

cv2. imshow ( 'نتيجة الصورة المطروحة' و الصورة_المطروحة )

cv2. انتظر ( 0 )

الخطوط من 1 إلى 16 ستُستخدم لتنفيذ عمليتنا العادية ، والتي تستلزم استيراد حزمنا ، وتكوين محلل الوسيطة ، وتحميل صورتنا.

تذكر كيف ناقشت سابقًا التمييز بين إضافة OpenCV و NumPy؟ الآن بعد أن غطيناها تمامًا ، دعنا نلقي نظرة على حالة معينة للتأكد من استيعابنا لها.

يتم تعريف صفيفتي NumPy ذات عدد صحيح من 8 بتات على السطر 26 . القيمة 201 هي العنصر الوحيد في المصفوفة الأولى. على الرغم من وجود عضو واحد فقط في المصفوفة الثانية ، إلا أنه يحتوي على قيمة 100. ثم يتم إضافة القيم باستخدام دالة cv2.add الخاصة بـ OpenCV.

ماذا تتوقع أن تكون النتيجة؟

وفقًا للمبادئ الحسابية التقليدية ، يجب أن تكون الإجابة 301. ولكن تذكر أننا نتعامل مع أعداد صحيحة 8 بت بدون إشارة ، والتي يمكن أن تكون فقط في النطاق [0 ، 255]. نظرًا لأننا نستخدم طريقة cv2.add ، فإن OpenCV يتعامل مع القطع ويضمن أن الإضافة ترجع فقط أقصى نتيجة وهي 255.

يُظهر السطر الأول من القائمة أدناه نتيجة تشغيل هذا الرمز:

علم الحساب. السنة التحضيرية

كحد أقصى 255 : [ [ 255 ] ]

لقد أنتج المجموع بالفعل عددًا من 255.

بعد ذلك ، السطر 26 يستخدم cv2.subtract لإنجاز عملية طرح. مرة أخرى ، نحدد مصفوفتين NumPy من الأعداد الصحيحة 8 بت بدون إشارة مع عنصر واحد في كل منهما. قيمة المصفوفة الأولى هي 60 ، بينما قيمة المصفوفة الثانية هي 100.

يفرض الحساب لدينا أن الطرح يجب أن ينتج عنه قيمة -40 ، لكن OpenCV يتعامل مع القصاصة لنا مرة أخرى. نكتشف أنه تم قطع القيمة إلى 0. توضح النتيجة أدناه هذا:

علم الحساب. السنة التحضيرية

الحد الأدنى من 0 : [ [ 0 ] ]

باستخدام cv2 ، اطرح 100 من 60 ، ونحصل على القيمة 0.

ولكن ماذا يحدث إذا استخدمنا NumPy بدلاً من OpenCV لإجراء العمليات الحسابية؟

السطر 38 و 39 معالجة هذه المسألة.

أولاً ، يتم تحديد صفيفين من مصفوفتي NumPy ذات عدد صحيح من 8 بتات مع عنصر واحد لكل منهما. قيمة المصفوفة الأولى هي 201 ، في حين أن قيمة المصفوفة الثانية هي 100. سيتم اقتطاع الإضافة ، وسيتم إرجاع القيمة 255 إذا استخدمنا الدالة cv2.add.

NumPy ، من ناحية أخرى ، 'يلتف حول' ويقوم بحسابات معيارية بدلاً من القص. يلتف NumPy إلى الصفر بمجرد الوصول إلى قيمة 255 ثم يستأنف العد حتى الوصول إلى 100 خطوة. يتم تأكيد ذلك من خلال السطر الأول من الإخراج ، والذي يظهر أدناه:

علم الحساب. السنة التحضيرية
التفاف حول: [ أربعة خمسة ]

بعد ذلك ، تم تحديد مصفوفتين أخريين من NumPy ، واحدة بقيمة 50 والأخرى بقيمة 100. سيتم اقتطاع هذا الطرح بواسطة طريقة cv2.subtract لإرجاع النتيجة 0. لكننا ندرك أنه بدلاً من القطع ، يتم تنفيذ NumPy حسابي معياري. بدلاً من ذلك ، تلتف إجراءات modulo وتبدأ العد العكسي من 255 بمجرد الوصول إلى 0 أثناء الطرح. يمكننا أن نرى هذا من الإخراج التالي:

علم الحساب. السنة التحضيرية

التفاف حول: [ 207 ]

مرة أخرى ، يوضح إخراجنا الطرفي الفرق بين القص والالتفاف حول:

من الأهمية بمكان أن تضع النتيجة المرجوة في الاعتبار عند إجراء العمليات الحسابية للأعداد الصحيحة. هل تريد قطع أي قيم خارج النطاق [0 ، 255]؟ استخدم تقنيات حساب الصور المضمنة في OpenCV بعد ذلك.

هل تريد التفاف القيم إذا كانت خارج نطاق [0 ، 255] والعمليات الحسابية للمعامل؟ يتم بعد ذلك ببساطة إضافة مصفوفات NumPy وطرحها كالمعتاد.

الخط 48 يعرّف مصفوفة NumPy أحادية البعد بنفس أبعاد صورتنا. مرة أخرى ، نضمن أن نوع البيانات لدينا هو 8 بت أعداد صحيحة بدون إشارة. نقوم فقط بضرب المصفوفة المكونة من رقم واحد في 101 لتعبئتها بالقيم 101 بدلاً من 1. وأخيرًا ، نستخدم الدالة cv2.add لإضافة مصفوفة مكونة من 100s إلى الصورة الأصلية. يؤدي هذا إلى زيادة كثافة كل بكسل بمقدار 101 مع ضمان أيضًا أن أي قيم تحاول تجاوز 255 يتم قصها في النطاق [0 ، 255].

لاحظ كيف تكون الصورة أكثر سطوعًا بشكل ملحوظ وتظهر 'باهتة' أكثر من الصورة الأصلية. هذا لأننا نقود وحدات البكسل نحو ألوان أكثر إشراقًا من خلال زيادة كثافة البكسل بمقدار 101.

لطرح 60 من كثافة كل بكسل للصورة ، نقوم أولاً بإنشاء مصفوفة NumPy ثانية على السطر 54 مملوءة بـ 60 ثانية.

تظهر نتائج هذا الطرح في الصورة التالية:

تبدو العناصر من حولنا أغمق بكثير مما كانت عليه في السابق. هذا لأنه بطرح 60 من كل بكسل ، فإننا ننقل وحدات البكسل في مساحة ألوان RGB إلى المناطق الأكثر قتامة.

4. صورة التقليب

على غرار التدوير ، يعد قلب الصورة عبر محورها x أو y خيارًا آخر يقدمه OpenCV. حتى إذا لم يتم استخدام عمليات التقليب بشكل متكرر ، فإن معرفتها مفيدة للغاية لأسباب مختلفة قد لا تراها على الفور.

نحن نعمل على تطوير مصنف التعلم الآلي لشركة صغيرة ناشئة تسعى إلى تحديد الوجوه في الصور. لكي 'يتعلم' نظامنا ماهية الوجه ، سنحتاج إلى نوع من مجموعة البيانات ذات الوجوه النموذجية. لسوء الحظ ، لم تقدم لنا الشركة سوى مجموعة بيانات صغيرة من 40 وجهًا ، ولا يمكننا جمع المزيد من المعلومات.

ماذا نفعل إذن؟

نظرًا لأن الوجه يظل وجهًا سواء كان معكوسًا أم لا ، فنحن قادرون على قلب كل صورة للوجه أفقيًا واستخدام النسخ المتطابقة كبيانات تدريب إضافية.

قد يبدو هذا المثال غبيًا ومصطنعًا ، لكنه ليس كذلك. التقليب هو استراتيجية مدروسة تستخدمها خوارزميات التعلم العميق القوية لإنتاج المزيد من البيانات أثناء مرحلة التدريب.

من الواضح مما سبق أن طرق معالجة الصور التي تتعلمها في هذه الوحدة تعمل كأساس لأنظمة رؤية الكمبيوتر الأكبر.

أهداف:

باستخدام cv2.flip وظيفة ، سوف تتعلم كيفية قلب الصورة أفقيا ورأسيا في هذه الجلسة.

التقليب هو التلاعب التالي بالصورة الذي سنقوم بدراسته. يمكن قلب محوري x و y للصورة أو كليهما. قبل الغوص في الترميز ، من الأفضل أن ننظر أولاً إلى نتائج قلب الصورة. شاهد صورة مقلوبة أفقيًا في الصورة التالية:


لاحظ كيف أن صورتنا الأصلية على اليسار وكيف انعكست الصورة أفقيًا على اليمين.

لنبدأ بإنشاء ملف جديد يسمى التقليب .

لقد رأيت مثالاً على قلب الصورة ، فلنتفحص الكود:

# python flipping.py --image quirrel.jpg

# استيراد الحزم المطلوبة

يستورد جدل

يستورد cv2

# إنشاء كائن محلل الوسيطة وتحليلها

apObj = جدل. حجة محلل ( )

apObj. add_argument ( '-أنا' و '--صورة' و مطلوب = حقيقي و يساعد = 'مسار الصورة' )

جدال = ملك من ( apObj. parse_args ( ) )

صورة = cv2. أنا أقرأ ( جدال [ 'صورة' ] )

cv2. imshow ( 'إبداعي' و صورة )

# اقلب الصورة أفقيا

تخيل = cv2. يواجه ( صورة و 1 )

cv2. imshow ( 'انعكاس الصورة أفقيًا' و تخيل )

# قلب الصورة عموديًا

تخيل = cv2. يواجه ( صورة و 0 )

cv2. imshow ( 'الصورة المعكوسة عموديًا' و تخيل )

# صورة تنقلب على كلا المحورين

تخيل = cv2. يواجه ( صورة و - 1 )

cv2. imshow ( 'انعكاس أفقي ورأسي' و تخيل )

cv2. انتظر ( 0 )

يتم التعامل مع الخطوات التي نتخذها لاستيراد حزمنا وتحليل مدخلاتنا وتحميل صورتنا من القرص في l من 1 إلى 12 .

من خلال استدعاء وظيفة cv2.flip على السطر 15 ، فمن السهل قلب الصورة أفقيًا. الصورة التي نسعى إلى قلبها والرمز أو العلم المحدد الذي يحدد كيفية قلب الصورة هما الوسيطتان اللازمتان لطريقة cv2.flip.

تعني قيمة الرمز العكسي 1 أننا سنقوم بتدوير الصورة حول المحور الصادي لقلبها أفقيًا ( السطر 15 ). إذا حددنا رمز الوجه 0 ، فإننا نرغب في تدوير الصورة حول المحور السيني ( الخط 19 ). رمز الوجه السلبي ( السطر 23 ) يدير الصورة على كلا المحورين.

أحد أسهل الأمثلة في هذا الموضوع هو قلب الصورة ، وهو أمر أساسي.

بعد ذلك ، سنناقش اقتصاص الصور واستخدام شرائح مصفوفة NumPy لاستخراج أجزاء معينة من الصور.

5. اقتصاص الصورة

الاقتصاص ، كما يوحي الاسم ، هو عملية اختيار وإزالة منطقة الاهتمام (أو ببساطة عائد الاستثمار) ، وهي منطقة الصورة التي تهمنا.

يجب اقتصاص الوجه من صورة لتطبيق اكتشاف الوجه. بالإضافة إلى ذلك ، إذا كنا نقوم بإنشاء برنامج نصي بلغة Python للعثور على الكلاب في الصور ، فقد نرغب في اقتصاص الكلب من الصورة عند تحديد موقعه.

الأهداف: هدفنا الرئيسي هو التعرف بسهولة على استخدام مصفوفة NumPy لتقسيم مناطق المحاصيل من الصورة.

اقتصاص : عندما نقوم بقص صورة ما ، فإن هدفنا هو التخلص من العناصر الخارجية التي لا تهمنا. غالبًا ما يشار إلى عملية اختيار عائد الاستثمار لدينا على أنها اختيار المنطقة التي تهمنا.

قم بإنشاء ملف جديد يسمى المحاصيل وافتحه وأضف الكود التالي:

# محصول الثعبان

# استيراد الحزم المطلوبة

يستورد cv2

# تحميل الصورة وعرضها على الشاشة

صورة = cv2. أنا أقرأ ( 'squirrel.jpg' )

مطبعة ( صورة. شكل )

cv2. imshow ( 'إبداعي' و صورة )

# شرائح مصفوفة NumPy تستخدم لقص صورة بسرعة

# سنقوم بقص وجه السنجاب من الصورة

السنجاب = صورة [ 35 : 90 و 35 : 100 ]

cv2. imshow ( 'وجه السنجاب' و السنجاب )

cv2. انتظر ( 0 )

# والآن ، ها نحن ذاهبون إلى اقتصاص الجسم كله

# السنجاب

جسم السنجاب = صورة [ 35 : 148 و 23 : 143 ]

cv2. imshow ( 'جسم السنجاب' و جسم السنجاب )

cv2. انتظر ( 0 )

سنعرض الاقتصاص في Python و OpenCV باستخدام صورة نقوم بتحميلها من القرص الموجود عليه الخطان 5 و 6 .

الصورة الأصلية التي سنقوم بقصها

باستخدام تقنيات المحاصيل الأساسية فقط ، نهدف إلى فصل وجه السنجاب وجسم السنجاب عن المنطقة المحيطة.

سنستخدم معرفتنا السابقة بالصورة ونزود يدويًا شرائح مصفوفة NumPy لمكان وجود الجسم والوجه. في ظل الظروف العادية ، نستخدم بشكل عام التعلم الآلي وخوارزميات رؤية الكمبيوتر للتعرف على الوجه والجسم في الصورة. ولكن دعونا نبقي الأمور واضحة في الوقت الحالي ونتجنب استخدام أي نماذج كشف.

يمكننا تحديد الوجه في الصورة بسطر واحد فقط من التعليمات البرمجية. السطر 13 ، لاستخراج جزء مستطيل من الصورة ، بدءًا من (35 ، 35) ، نقدم شرائح مصفوفة NumPy (90 ، 100). قد يبدو محيرًا أننا نقوم بتغذية المحصول بالفهارس بترتيب الارتفاع الأول والعرض الثاني الذي نقوم به ، ولكن ضع في اعتبارك أن OpenCV يخزن الصور كمصفوفات NumPy. نتيجة لذلك ، يجب علينا توفير قيم المحور y قبل المحور x.

يتطلب NumPy الفهارس الأربعة التالية لإجراء عملية الاقتصاص لدينا:

ابدأ ص: إحداثيات y في البداية. في هذا المثال ، نبدأ عند y = 35.

نهاية ص: إحداثيات y في النهاية. سيتوقف محصولنا عندما تكون y = 90.

البدء x: بداية الشريحة x الإحداثي. يبدأ المحصول عند x = 35.

النهاية س: إحداثيات المحور س في نهاية الشريحة. عند x = 100 ، تكون الشريحة قد اكتملت.

وبالمثل ، نقوم بقص المناطق (23 ، 35) و (143 ، 148) من الصورة الأصلية لاستخراج الجسم بالكامل من الصورة الموجودة على الخط 19 .

يمكنك ملاحظة أنه تم اقتصاص الصورة لعرض الجسم والوجه فقط.

6. تغيير حجم الصورة

تُعرف عملية زيادة أو تقليل عرض الصورة وارتفاعها بالقياس أو ببساطة تغيير الحجم. يجب مراعاة نسبة العرض إلى الارتفاع ، وهي نسبة عرض الصورة إلى ارتفاعها ، عند تغيير حجم الصورة. يمكن أن يؤدي إهمال نسبة العرض إلى الارتفاع إلى ظهور صور تم تحجيمها مضغوطة ومشوهة:

صورتنا الأولية على اليسار. على اليمين ، سترى صورتين تم تغيير حجمهما دون الحفاظ على نسبة العرض إلى الارتفاع ، مما يؤدي إلى تشويه نسبة عرض الصورة إلى ارتفاعها. عند تغيير حجم صورك ، يجب أن تفكر بشكل عام في نسبة العرض إلى الارتفاع.

يجب أن تراعي تقنية الاستيفاء التي تستخدمها خوارزمية تغيير الحجم هدف وظيفة الاستيفاء لاستخدام هذه الأحياء من وحدات البكسل إما لزيادة أو تقليل حجم الصورة.

بشكل عام ، يكون تقليص حجم الصورة أكثر فاعلية. هذا لأن إزالة وحدات البكسل من الصورة هي كل ما تحتاجه وظيفة الاستيفاء. من ناحية أخرى ، قد تحتاج طريقة الاستيفاء إلى 'ملء الفجوات' بين وحدات البكسل التي لم تكن موجودة من قبل في حالة زيادة حجم الصورة.

لدينا صورتنا الأصلية على اليسار. تم تصغير الصورة إلى نصف حجمها الأصلي في المنتصف ، ولكن بخلاف ذلك ، لم يتم فقدان 'جودة' الصورة. ومع ذلك ، فقد تم تحسين حجم الصورة بشكل كبير على اليمين. يبدو الآن أنه 'مفجر' و 'منقسم'.

كما ذكرت سابقًا ، سترغب عادةً في تقليل حجم الصورة بدلاً من زيادتها. من خلال تقليل حجم الصورة ، نقوم بتحليل عدد أقل من وحدات البكسل ويتعين علينا التعامل مع 'ضوضاء' أقل ، مما يجعل خوارزميات معالجة الصور أسرع وأكثر دقة.

الترجمة والدوران هما تحويلي الصورة اللذان تم تناولهما حتى الآن. سنقوم الآن بفحص كيفية تغيير حجم الصورة.

مما لا يثير الدهشة ، أننا سنقوم بتغيير حجم صورنا باستخدام طريقة cv2.resize. كما أشرت سابقًا ، يجب أن نأخذ في الاعتبار نسبة العرض إلى الارتفاع للصورة عند استخدام هذه الطريقة. ولكن قبل أن نتعمق في التفاصيل ، اسمح لي أن أقدم لك توضيحًا:

# python resize.py --image squirrel.jpg

# استيراد الحزم المطلوبة

يستورد جدل

يستورد cv2

# إنشاء كائن محلل الوسيطة وتحليلها

apObj = جدل. حجة محلل ( )

apObj. add_argument ( '-ك' و '--صورة' و مطلوب = حقيقي و يساعد = 'مسار الصورة' )

الحجج = ملك من ( apObj. parse_args ( ) )

# قم بتحميل الصورة وعرضها على الشاشة

صورة = cv2. أنا أقرأ ( الحجج [ 'صورة' ] )

cv2. imshow ( 'إبداعي' و صورة )

# من أجل منع الصورة من الظهور منحرف ، نسبة العرض إلى الارتفاع

# يجب اعتباره أو تشوهه ؛ لذلك ، نكتشف ماذا

# نسبة الصورة الجديدة للصورة الحالية.

# لنجعل عرض صورتنا الجديدة 160 بكسل.

وجه = 160.0 / صورة. شكل [ 1 ]

البعد = ( 160 و int ( صورة. شكل [ 0 ] * وجه ) )

# سيعرض هذا الخط عمليات تغيير الحجم الفعلية

حجم الصورة = cv2. تغيير الحجم ( صورة و البعد و إقحام = cv2. INTER_AREA )

cv2. imshow ( 'عرض الصورة التي تم تغيير حجمها' و حجم الصورة )

# ماذا لو أردنا تغيير ارتفاع الصورة؟ - باستخدام

# نفس المبدأ ، يمكننا حساب نسبة العرض إلى الارتفاع

# في الارتفاع بدلاً من العرض. دعونا نجعل تحجيمها

# ارتفاع الصورة 70 بكسل.

وجه = 70.0 / صورة. شكل [ 0 ]

البعد = ( int ( صورة. شكل [ 1 ] * وجه ) و 70 )

# إجراء تغيير الحجم

حجم الصورة = cv2. تغيير الحجم ( صورة و البعد و إقحام = cv2. INTER_AREA )

cv2. imshow ( 'ارتفاع الصورة التي تم تغيير حجمها' و حجم الصورة )

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 لتغيير حجم الصورة. من الأهمية بمكان مراعاة كل من طريقة الاستيفاء التي تستخدمها ونسبة العرض إلى الارتفاع لصورتك الأصلية عند تغيير حجم صورة بحيث لا تظهر النتيجة مشوهة.

أخيرًا ، من المهم أن تتذكر أنه إذا كانت جودة الصورة تمثل مشكلة ، فمن الأفضل دائمًا التبديل من صورة أكبر إلى صورة أصغر. في معظم الحالات ، يؤدي تكبير الصورة إلى إنشاء عيوب ويقلل من جودتها.