اذهب إلى المحتوى
  • 0

إيجاد صورة داخل صورة أخرى باستخدام OpenCV في بايثون

Ali Ismael

السؤال

كيف يمكننا إيجاد صورة داخل صورة أخرى؟ على سبيل المثال لدي صورة وجه لشخص ما وأريد البحث عنها ضمن صورة تحتوي مجموعة من صور الوجوه الأخرى (ومن ضمنهم صورة وجهه)؟
 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

يمكنك استخدام مفهوم مطابقة القوالب Template matching، بحيث تكون صورة الوجه هي القالب "Template"  (أو النافذة) والصورة التي نريد البحث فيها "Target" أي صورة الهدف. وتتم العملية من خلال التفاف (تمرير) القالب على صورة الهدف، ومقارنتها مع كل بقعة من الصورة (على سبيل المثال تكون صورة القالب بأبعاد 40*40 بكسل وصورة الهدف ب 400*400، ثم نقوم بتمرير هذا القالب على الصورة بدءاً من الجانب العلوي الأيسر وصولاً للسفلي الأيمن، بحيث تتم المقارنة مع كل بقعة من الصورة). 
لتنفيذ هذه المهمة نستخدم الدالة cv2.matchTemplate من مكتبة OpenCV:

cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)

حيث أن الوسيط الأول يمثل الصورة الرمادية (إذا كانت الصورة ملونة فحولها للرمادي)، والوسيط الثاني يمثل القالب (أيضاً حولها للرمادي)، أما الوسيط الثالث فهو يمثل طريقة المقارنة.  انظر للمثال التالي الذي يمكنك استخدامها مع المهام الأخرى التي تحتاجها:
الصورة الهدف:template_matching_coke_bottle.png.041242719cbf6e0ab6aad5ca084ee4f4.png
القالب:
template_matching_coke_logo.png.9d34e17bd3cacb306642f2886aa05b4f.png
الكود:

import cv2
import numpy as np
from matplotlib import pyplot as plt
# قراءة الصورة الهدف 
target = cv2.imread('/content/template_matching_coke_bottle.png')
# تحويلها للصيغة الرمادية
img = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
# RGB  ل BGR تحويل نظام الصورة من 
target=cv2.cvtColor(target, cv2.COLOR_BGR2RGB) # هذه الخطوة فقط من أجل الرسم
# أخذ نسخة عنها
img2 = img.copy()
# قراءة القالب
template = cv2.imread('/content/template_matching_coke_logo.png',0)
# استخلاص أبعاد القالب
w, h = template.shape[::-1]
# سنقوم هنا بتطبيق كل أنواع المقارنة ونعرض نتائجها
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
for meth in methods:
  img = img2.copy()
  t = target.copy()
  method = eval(meth) # هذا التابع فقط لإزالة علامتي الاقتباس
  # تطبيق العملية
  res = cv2.matchTemplate(img,template,method)
  # minMaxLoc الآن سنستخدم التابع 
  # هذا التابع يقوم بإيجاد قيمة أكبر وأقل عنصر في المصفوفة وأيضاً موقع هذين العنصرين الإحداثي
  # الآن سنحدد المنطقة التي تم إيجاد صورة القالب ضمنها وسنحددها بمستطيل من خلال
  #  الذي يعيد لنا أعلى وأدنى قيمة للبيكسل  minMaxLoc استخدام التابع  
  # في الصورة الناتجة عن المطابقة مع موضع هذين البيكسلين ضمن الصورة الهدف
  # نختار احداثيات أحد هذين الموضعين لنحدد إحداثيات أحد هذين الموضعين لنحدد احداثيات
  # الزاويا العليا اليسارية للمستطيل
  # max_loc والأعلى في  min_loc يتم تخزين الحد الأدنى في المتغير 
  # وكما حصلنا على احداثيات زاوية المستطيل، ونحتاج الآن لتحديد حدود
  # منطقة المطابقة لذلك يجب أن نعرف طول وعرض هذا المستطيل وهما بالطبع طول وعرض القالب
  min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  # الآن سنختار احداثيات أعلى وأدنى قيمة للبكسل وذلك حسب كل طريقة مقارنة
  # فبالنسبة لآخر طريقتي مقارنة نختار احداثيات القيمة الأدنى فهو الحد المناسب لتحديد 
  # احداثيات زاوية مستطيل منطقة المطابقة، أما بالنسبة للبقية فاخترنا القيمة العليا فهي الأنسب 
  # ثم فمت برسم المستطيل حول منطقة القالب الموجودة في الصورةالهدف
  if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
    top_left = min_loc
  else:
    top_left = max_loc
  bottom_right = (top_left[0] + w, top_left[1] + h)
  cv2.rectangle(t,top_left, bottom_right, (0,255,0), 4)
  plt.subplot(121),plt.imshow(res,cmap = 'gray')
  plt.title('Matching Result')
  plt.xticks([])
  plt.yticks([])
  plt.subplot(122)
  plt.imshow(t)
  plt.title('Detected Point') 
  plt.xticks([])
  plt.yticks([])
  plt.suptitle(meth)
  plt.show()

النتائج:
1.png.0679229ece4fb9bbde177b727e326174.png2.png.bc47d90a964fa55ab858fc0542563c07.png3.png.5c80fcd80230f8026a87c6a348ba98ce.png4.png.02eee2e5d242f288f94b4442d2e6f01a.png لاحظ أن الطريقة الأولى للمقارنة أعطت  نتائج سيئة

تم التعديل في بواسطة Ali Haidar Ahmad
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

يمكنك كذلك استخدام ما يسمي object detection أو تحديد الكائنات والمقصود منها تحديد الأجسام أو الصور داخل صورة، ويتم ذلك عن طريق احتواء opencv على بعض النماذج المتعلمة مسبقا باستخدام التعلم العميق والتي يمكن استخدامها مباشرة، الكود التالي يوضح استخدامها بسهولة:

import cv2
from matplotlib import pyplot as plt

# فتح الصورة
img = cv2.imread("image.jpg")

# قراءة الصورة بالألوان الصحيحة
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


# استدعاء النموذج المتعلم
stop_data = cv2.CascadeClassifier('stop_data.xml')

found = stop_data.detectMultiScale(img_gray,
								minSize =(20, 20))

#لا يقوم بعمل شئ لولم يوجد اشارة مرور
amount_found = len(found)

if amount_found != 0:
	
	# اذا كان هناك اكثر من علامة مرور
	for (x, y, width, height) in found:
		
		# رسم اشارة خضراء
		cv2.rectangle(img_rgb, (x, y),
					(x + height, y + width),
					(0, 255, 0), 5)
		
# طباعة الصورة
plt.subplot(1, 1, 1)
plt.imshow(img_rgb)
plt.show()

والنتيجة كالتالي:

stop_recognition_output.png.1d6efcde8a86edb27ccc5b1ec2ddbf3f.png

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...