يعد ضغط الصور تقنية مهمة في رؤية الكمبيوتر والتي تسمح لنا بتخزين الصور ونقلها بشكل أكثر كفاءة مع الحفاظ على الجودة البصرية. ومن الناحية المثالية، نود أن يكون لدينا ملفات صغيرة ذات جودة أفضل. ومع ذلك، يجب علينا أن نجري مقايضة ونقرر أيهما أكثر أهمية.
سيعلم هذا البرنامج التعليمي ضغط الصور باستخدام OpenCV، ويغطي النظرية والتطبيقات العملية. في النهاية، ستفهم كيفية ضغط الصور بنجاح لمشاريع رؤية الكمبيوتر (أو أي مشاريع أخرى قد تكون لديك).
يعمل ضغط الصور على تقليل حجم ملف الصورة مع الحفاظ على مستوى مقبول من الجودة المرئية. هناك نوعان رئيسيان من الضغط:
إذا كانت "مساحة القرص رخيصة"، كما نسمع كثيرًا، فلماذا ضغط الصور على الإطلاق؟ على نطاق صغير، لا يهم ضغط الصور كثيرًا، ولكن على نطاق واسع، يعد أمرًا بالغ الأهمية.
على سبيل المثال، إذا كان لديك بعض الصور على محرك الأقراص الثابتة لديك، فيمكنك ضغطها وحفظ بضعة ميغابايت من البيانات. وهذا ليس له تأثير كبير عندما يتم قياس محركات الأقراص الثابتة بالتيرابايت. ولكن ماذا لو كان لديك 100000 صورة على محرك الأقراص الثابتة لديك؟ بعض عمليات الضغط الأساسية توفر الوقت والمال الحقيقيين. من منظور الأداء، الأمر نفسه. إذا كان لديك موقع ويب يحتوي على الكثير من الصور ويزوره 10000 شخص يوميًا، فإن الضغط مهم.
ولهذا السبب نقوم بذلك:
تستغل تقنيات ضغط الصور نوعين من التكرار:
يستفيد التكرار المكاني من حقيقة أن وحدات البكسل المجاورة تميل إلى أن تكون لها قيم مماثلة في معظم الصور الطبيعية. وهذا يخلق انتقالات سلسة. العديد من الصور "تبدو حقيقية" لأن هناك تدفقًا طبيعيًا من منطقة إلى أخرى. عندما يكون لوحدات البكسل المجاورة قيم مختلفة تمامًا، فإنك تحصل على صور "مشوشة". تم تغيير وحدات البكسل لجعل هذه التحولات أقل "سلاسة" عن طريق تجميع وحدات البكسل في لون واحد، مما يجعل الصورة أصغر.
تكرار اللون ، من ناحية أخرى، يركز على كيفية مشاركة المناطق المتجاورة في الصورة في كثير من الأحيان للألوان المتشابهة. فكر في سماء زرقاء أو حقل أخضر، فقد تحتوي أجزاء كبيرة من الصورة على قيم ألوان متشابهة جدًا. ويمكن أيضًا تجميعها معًا وصنعها في لون واحد لتوفير المساحة.
يوفر OpenCV أدوات قوية للتعامل مع هذه الأفكار. باستخدام التكرار المكاني، تقوم وظيفة cv2.inpaint() الخاصة بـ OpenCV، على سبيل المثال، بملء المناطق المفقودة أو التالفة من الصورة باستخدام معلومات من وحدات البكسل القريبة. يتيح OpenCV للمطورين استخدام cv2.cvtColor() لترجمة الصور بين مساحات ألوان متعددة فيما يتعلق بتكرار الألوان. يمكن أن يكون هذا مفيدًا إلى حد ما كخطوة معالجة مسبقة في العديد من تقنيات الضغط نظرًا لأن بعض مساحات الألوان أكثر فعالية من غيرها في تشفير أنواع معينة من الصور.
سنقوم باختبار بعض هذه النظرية الآن. دعونا نلعب معها.
دعنا نستكشف كيفية ضغط الصور باستخدام روابط Python الخاصة بـ OpenCV. اكتب هذا الرمز أو انسخه:
يمكنك أيضًا الحصول على الكود المصدري هنا
import cv2 import numpy as np def compress_image(image_path, quality=90): # Read the image img = cv2.imread(image_path) # Encode the image with JPEG compression encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality] _, encoded_img = cv2.imencode('.jpg', img, encode_param) # Decode the compressed image decoded_img = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR) return decoded_img # Example usage original_img = cv2.imread('original_image.jpg') compressed_img = compress_image('original_image.jpg', quality=50) # Display results cv2.imshow('Original', original_img) cv2.imshow('Compressed', compressed_img) cv2.waitKey(0) cv2.destroyAllWindows() # Calculate compression ratio original_size = original_img.nbytes compressed_size = compressed_img.nbytes compression_ratio = original_size / compressed_size print(f"Compression ratio: {compression_ratio:.2f}")
يحتوي هذا المثال على دالة Compress_image التي تأخذ معلمتين:
ثم سنقوم بتحميل الصورة الأصلية إلى original_img. نقوم بعد ذلك بضغط نفس الصورة بنسبة 50% ونحملها في نسخة جديدة، Compressed_image.
ثم سنعرض الصور الأصلية والمضغوطة حتى تتمكن من مشاهدتها جنبًا إلى جنب.
ثم نقوم بحساب وعرض نسبة الضغط.
يوضح هذا المثال كيفية ضغط صورة باستخدام ضغط JPEG في OpenCV. تتحكم معلمة الجودة في حجم الملف ومقايضة جودة الصورة.
لنقم بتشغيله:
أثناء النظر إلى الصور في البداية، ترى اختلافًا بسيطًا. ومع ذلك، التكبير يظهر لك الفرق في الجودة:
وبعد إغلاق النوافذ والنظر إلى الملفات، يمكننا أن نرى أن حجم الملف قد انخفض بشكل كبير:
أيضًا، إذا قمنا بتخفيضها أكثر، فيمكننا تغيير الجودة لدينا إلى 10٪
compressed_img = compress_image('sampleimage.jpg', quality=10)
والنتائج أكثر جذرية:
ونتائج حجم الملف أكثر جذرية أيضًا:
يمكنك ضبط هذه المعلمات بسهولة تامة وتحقيق التوازن المطلوب بين الجودة وحجم الملف.
لتقييم تأثير الضغط، يمكننا استخدام مقاييس مثل:
يقيس متوسط الخطأ التربيعي (MSE) مدى اختلاف الصورتين عن بعضهما البعض. عندما تقوم بضغط صورة، يساعدك MSE على تحديد مدى تغير الصورة المضغوطة مقارنة بالصورة الأصلية.
يتم ذلك عن طريق أخذ عينات من الاختلافات بين ألوان وحدات البكسل المقابلة في الصورتين، وتربيع تلك الاختلافات وحساب متوسطها. والنتيجة هي رقم واحد: انخفاض MSE يعني أن الصورة المضغوطة أقرب إلى الصورة الأصلية. وبالمقارنة، فإن ارتفاع MSE يعني أن هناك خسارة ملحوظة في الجودة.
إليك بعض أكواد بايثون لقياس ذلك:
def calculate_mse(img1, img2): return np.mean((img1 - img2) ** 2) mse = calculate_mse(original_img, compressed_img) print(f"Mean Squared Error: {mse:.2f}")
إليك الشكل الذي يبدو عليه ضغط الصور التجريبي لدينا:
نسبة الذروة للإشارة إلى الضوضاء (PSNR) هي مقياس يوضح مدى تدهور جودة الصورة بعد الضغط. غالبًا ما يكون هذا مرئيًا بعينيك، ولكنه يعين قيمة محددة. يقوم بمقارنة الصورة الأصلية بالصورة المضغوطة ويعبر عن الفرق كنسبة.
تعني قيمة PSNR الأعلى أن الصورة المضغوطة أقرب في الجودة إلى الصورة الأصلية، مما يشير إلى فقدان أقل للجودة. انخفاض PSNR يعني تدهورًا أكثر وضوحًا. غالبًا ما يتم استخدام PSNR جنبًا إلى جنب مع MSE، حيث يوفر PSNR مقياسًا أسهل في التفسير حيث يكون الأعلى أفضل.
إليك بعض أكواد Python التي تقيس ذلك:
def calculate_psnr(img1, img2): mse = calculate_mse(img1, img2) if mse == 0: return float('inf') max_pixel = 255.0 return 20 * np.log10(max_pixel / np.sqrt(mse)) psnr = calculate_psnr(original_img, compressed_img) print(f"PSNR: {psnr:.2f} dB")
إليك الشكل الذي يبدو عليه ضغط الصور التجريبي لدينا:
يعد "فحص" صورك بعد الضغط لتحديد الجودة أمرًا جيدًا؛ ومع ذلك، على نطاق واسع، فإن قيام البرامج النصية بذلك يعد طريقة أسهل بكثير لوضع المعايير والتأكد من أن الصور تتبعها.
دعونا نلقي نظرة على بعض التقنيات الأخرى:
للحصول على ضغط أكثر تقدمًا، يدعم OpenCV خوارزميات مختلفة:
يمكنك تحويل صورك إلى صيغة PNG وهذا له العديد من المزايا. استخدم السطر التالي من التعليمات البرمجية، ويمكنك ضبط الضغط من 0 إلى 9، حسب احتياجاتك. 0 يعني عدم وجود ضغط على الإطلاق، و9 هو الحد الأقصى. ضع في اعتبارك أن ملفات PNG عبارة عن تنسيق "بدون فقد البيانات"، لذلك حتى عند الضغط الأقصى، يجب أن تظل الصورة سليمة. المقايضة الكبيرة هي حجم الملف ووقت الضغط.
إليك الكود لاستخدام ضغط PNG مع OpenCV:
cv2.imwrite('compressed.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
وهذه هي النتيجة:
ملاحظة: قد تلاحظ أحيانًا أن ملفات PNG أكبر حجمًا في الواقع، كما في هذه الحالة. يعتمد ذلك على محتوى الصورة.
يمكنك أيضًا تحويل صورك إلى تنسيق webp. هذه طريقة أحدث للضغط تكتسب شعبية. لقد كنت أستخدم هذا الضغط على الصور الموجودة في مدونتي لسنوات.
في الكود التالي، يمكننا كتابة صورتنا إلى ملف webp وتعيين مستوى الضغط من 0 إلى 100. وهو عكس مقياس PNG لأن 0، لأننا نضبط الجودة بدلاً من ضغط. هذا التمييز البسيط مهم، لأن الإعداد 0 هو أقل جودة ممكنة، مع حجم ملف صغير وخسارة كبيرة. 100 هو أعلى جودة، مما يعني الملفات الكبيرة ذات أفضل جودة للصورة.
إليك كود بايثون لتحقيق ذلك:
cv2.imwrite('compressed.webp', img, [cv2.IMWRITE_WEBP_QUALITY, 80])
وهذه هي النتيجة:
تعتبر هاتان التقنيتان رائعتين لضغط كميات كبيرة من البيانات. يمكنك كتابة نصوص برمجية لضغط آلاف أو مئات الآلاف من الصور تلقائيًا.
ضغط الصور رائع. إنه ضروري لمهام رؤية الكمبيوتر بعدة طرق، خاصة عند توفير المساحة أو زيادة سرعة المعالجة. هناك أيضًا العديد من حالات الاستخدام خارج نطاق رؤية الكمبيوتر في أي وقت تريد فيه تقليل مساحة القرص الصلب أو توفير النطاق الترددي. يمكن أن يساعد ضغط الصور كثيرًا.
من خلال فهم النظرية الكامنة وراء ذلك وتطبيقها، يمكنك القيام ببعض الأشياء القوية في مشاريعك.
تذكر أن مفتاح الضغط الفعال هو العثور على النقطة المثالية بين تقليل حجم الملف والحفاظ على جودة مرئية مقبولة لتطبيقك.
شكرًا على القراءة، ولا تتردد في التواصل معنا إذا كان لديك أي تعليقات أو أسئلة!
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3