سؤال

إنني أتطلع إلى إنشاء نظام معرف لفهرسة الصور.لا يمكنني استخدام md5() لأن ذلك سيتغير إذا قمت بتغيير علامات EXIF ​​الخاصة بالصورة.

أستخدم حاليًا المجموع الاختباري SHA1 المحسوب بواسطة imagemagick.إنه يعمل بشكل مثالي، لكنه بطيء حقًا في الصور الأكبر حجمًا (حوالي 15 ثانية على معالج Xeon رباعي النواة لـ JPG بدقة 21 ميجابكسل).

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

هل كانت مفيدة؟

المحلول

يمكنك محاولة تشغيل MD5 على بيانات الصورة النقطية الفعلية بدلاً من ملف JPEG.لقد اختبرت على جهازي (أيضًا معالج Xeon رباعي النواة) وتم تشغيل ما يلي في حوالي 900 مللي ثانية على صورة بدقة 23 ميجابكسل.

uint32_t width  = MagickGetImageWidth(imageWand);
uint32_t height = MagickGetImageHeight(imageWand);

uint8_t *imageData = malloc(width * height * 3);

MagickExportImagePixels(imageWand,
   0, 0, width, height, "RGB", CharPixel, imageData);

unsigned char *imageDigest = MD5(imageData, width * height * 3, NULL);

free(imageData);

نصائح أخرى

ماذا تقصد ب "المجموع الاختباري البصري"؟تعمل الخوارزميات التي ذكرتها (md5/sha/crc) بطريقة تعتمد على البايت، ولكنها لا تأخذ في الاعتبار المعلومات المرئية للصورة.إذا قمت بتحويل إحدى صورك إلى JPEG، فسيظهر الملفان نفس الصورة، لكن بمجموعات اختبارية مختلفة تمامًا لـ md5/sha/crc.

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

إذا كانت جميع ملفات الصور الخاصة بك تأتي مباشرة من الكاميرا، فأنت أفضل حالًا:يمكنك استخراج الصورة المصغرة exif التي تم إنشاؤها مسبقًا باستخدام exiv2 (عادةً بضعة كيلو بايت فقط) وحساب مجموعها الاختباري.

حول النهج التصغيري:انتبه أيضًا إلى حقيقة أن ImageMagick قد يغير خوارزميات القياس الخاصة به في المستقبل، الأمر الذي قد يؤدي إلى إبطال المجموع الاختباري الخاص بك (ستتغير بنية البايت للإصدارات المصغرة بعد ذلك).

كما لاحظ تود يانديل، ربما يكون MD5 سريعًا بدرجة كافية.إذا لم يكن الأمر كذلك، فيمكنك الحصول على شيء أسرع باستخدام 32 بت أو 64 بت اتفاقية حقوق الطفل للمجموع الاختباري الخاص بك.والفرق الرئيسي هو أنه يمكن لأي شخص أن يشكل صورة جديدة بنفس CRC؛من السهل جدًا التزوير.من الصعب جدًا على أي شخص أن ينتحل المجموع الاختباري MD5.هناك اختلاف بسيط وهو أن CRC تحتوي على عدد أقل من البتات، ولكن ما لم يكن لديك عدد كبير جدًا من الصور، فلا يزال الاصطدام غير محتمل.

exiftool يدعي أنه قادر على استخراج الصورة الثنائية من ملف JPEG، بحيث يمكنك حساب المجموع الاختباري الخاص بك دون فك الضغط، ولكن لا يمكنني معرفة كيفية القيام بذلك من صفحة الدليل.

لقد أجريت بعض التجارب على جهاز كمبيوتر محمول Intel Core 2 Duo L7100 CPU، ويستغرق ملف JPEG بدقة 8 ميجابكسل حوالي ثانية واحدة للضغط إلى تنسيق PPM، ثم ثانية واحدة أخرى لإجراء المجموع الاختباري.لم تكن أوقات المجموع الاختباري مختلفة بشكل كبير باستخدام md5sum, sum, ، و sha1sum.لذلك قد يكون أفضل رهان هو إيجاد طريقة لاستخراج البيانات الثنائية دون فك ضغطها.

وألاحظ أيضًا أن المجموع الاختباري الخاص بك سيكون جيدًا تقريبًا حتى لو كان يستخدم عددًا أقل بكثير من وحدات البكسل.قارن بين هذين:

djpeg -scale 1/8 big.jpg | /usr/bin/sha1sum   # 0.70s
djpeg            big.jpg | /usr/bin/sha1sum   # 2.15s

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top