سبب غبي لماذا لا يعمل تطبيق رؤية الماكرة لديك: الاتجاه في EXIF

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



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

كيف الكاميرات الرقمية تدوير الصور تلقائيا


عندما تلتقط صورة ، تسجل الكاميرا موضع الهاتف ، بحيث يتم عرض الصورة في الاتجاه الآخر في برنامج آخر:



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



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

يُطلق على تنسيق بيانات تعريف الصورة الأكثر شيوعًا اسم EXIF (اختصار لتنسيق ملف صورة قابل للتبديل). تم تضمين بيانات EXIF ​​الأولية في كل ملف بتنسيق jpeg. لا يمكنك رؤيتها على الشاشة ، لكن يتم قراءتها بواسطة أي برنامج يعرف مكانه.

فيما يلي بيانات EXIF الأولية داخل صورة JPEG الخاصة بأوزنا من أداة exiftool :



راجع عنصر "التوجيه"؟ يخبر المشاهد أنه قبل عرضها على الشاشة ، يجب تدوير الصورة 90 درجة في اتجاه عقارب الساعة. إذا نسي البرنامج القيام بذلك ، فستكون الصورة إلى جانبها!



لماذا هذا كسر العديد من تطبيقات رؤية الجهاز في بيثون؟


لم تكن بيانات EXIF ​​الأولية جزءًا من تنسيق JPEG. تم تقديمها في وقت لاحق ، واستعارة الفكرة من تنسيق TIFF. للتوافق مع الإصدارات السابقة ، تعد بيانات التعريف هذه اختيارية ، ولا تهتم بعض البرامج بتحليلها.

تعتبر معظم مكتبات صور Python ، مثل numpy ، scipy ، TensorFlow ، Keras ، إلخ ، أدوات علمية للأشخاص الجادين الذين يعملون مع مجموعات البيانات المشتركة. إنهم لا يهتمون بالمشكلات على مستوى المستهلك ، مثل تدوير الصور تلقائيًا ، على الرغم من أن هذا مطلوبًا تقريبًا لجميع الصور الفوتوغرافية في العالم التي يتم التقاطها بالكاميرات الحديثة.

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

قد تعتقد أن المشاكل تنشأ فقط في برامج المبتدئين والطلاب ، ولكن هذا ليس كذلك! حتى الإصدار التجريبي من واجهة برمجة تطبيقات Vision Vision من Google لا يتعامل مع اتجاه EXIF ​​بشكل صحيح:


لا يعرف الإصدار التجريبي من Google Vision API كيفية تدوير الصورة الموجهة نحو الصورة المأخوذة من هاتف محمول قياسي

على الرغم من أن Google Vision تتعرف على بعض الحيوانات من جانبها ، إلا أنها تميزها بالعلامة الشائعة "الحيوان" ، لأن نماذج رؤية الماكينة يصعب التعرف عليها أوزة على جانبها أكثر من أوزة رأسية. هذه هي النتيجة ، إذا قمت بتدوير الصورة بشكل صحيح قبل إرسالها إلى النموذج:



باستخدام الاتجاه الصحيح ، تكتشف Google الطيور التي تحمل علامة أوزة أكثر تحديدًا ومؤشر ثقة أعلى. أفضل بكثير!

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


يعرض الباحث في Mac دائمًا الصور التي يتم تدويرها بشكل صحيح من EXIF. لا توجد طريقة لمعرفة أن الصورة مخزنة بالفعل على جانبها

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

تصحيح


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

فيما يلي رمز تحميل أي صورة في صفيف numpy مع الاتجاه الصحيح:

import PIL.Image import PIL.ImageOps import numpy as np def exif_transpose(img): if not img: return img exif_orientation_tag = 274 # Check for EXIF data (only present on some files) if hasattr(img, "_getexif") and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif(): exif_data = img._getexif() orientation = exif_data[exif_orientation_tag] # Handle EXIF Orientation if orientation == 1: # Normal image - nothing to do! pass elif orientation == 2: # Mirrored left to right img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT) elif orientation == 3: # Rotated 180 degrees img = img.rotate(180) elif orientation == 4: # Mirrored top to bottom img = img.rotate(180).transpose(PIL.Image.FLIP_LEFT_RIGHT) elif orientation == 5: # Mirrored along top-left diagonal img = img.rotate(-90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT) elif orientation == 6: # Rotated 90 degrees img = img.rotate(-90, expand=True) elif orientation == 7: # Mirrored along top-right diagonal img = img.rotate(90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT) elif orientation == 8: # Rotated 270 degrees img = img.rotate(90, expand=True) return img def load_image_file(file, mode='RGB'): # Load the image with PIL img = PIL.Image.open(file) if hasattr(PIL.ImageOps, 'exif_transpose'): # Very recent versions of PIL can do exit transpose internally img = PIL.ImageOps.exif_transpose(img) else: # Otherwise, do the exif transpose ourselves img = exif_transpose(img) img = img.convert(mode) return np.array(img) 

من هنا ، يمكنك نقل مجموعة من بيانات الصور إلى أي مكتبة رؤية لآلة Python القياسية تتوقع مجموعة مدخلات: على سبيل المثال ، Keras أو TensorFlow.

نظرًا لأن المشكلة منتشرة في كل مكان ، فقد نشرت هذه الوظيفة كمكتبة تدعى " image_to_numpy" . يمكنك تثبيته على النحو التالي:

  pip3 تثبيت image_to_numpy 

يعمل مع أي برنامج Python ، وتحديد تحميل الصور ، على سبيل المثال:

 import matplotlib.pyplot as plt import image_to_numpy # Load your image file img = image_to_numpy.load_image_file("my_file.jpg") # Show it on the screen (or whatever you want to do) plt.imshow(img) plt.show() 

انظر الملف التمهيدي لمزيد من التفاصيل.

استمتع بها!

Source: https://habr.com/ru/post/ar471112/


All Articles