مكتبة OpenCV (الجزء السادس) : مطابقة الصور بالقوالب أو السمات

639

في هذا الدرس سنتعرف علي طريقة بسيطة جداً للتعرف علي الأشياء object recognition.

الفكرة هو التعرف علي المناطق المتشابهة في صورة ما بقالب template نقوم بتزويده بإستخدام threshold. الأمر يعمل بدقة عالية في التعرف علي نفس ال objects في ظل ثبات درجة الإضاءة.

للبداية، نحتاج صورة رئيسية بالإضافة إلي template والذي سنأخذة من نفس الصورة مما يجعل الأمر أسهل.

سنستخدم الصورة التالية لكن يمكنك إستخدام اي صورة من إختيارك.

D:\Work\Jisr Labs\3.OpenCV\11\jisrlabs-opencvtut11-fig-1.jpg

ال template هو الجزء التالي والذي يعتبر عن المخارج في الحاسوب بالصورة:

D:\Work\Jisr Labs\3.OpenCV\11\tem.jpg

يوجد 4 مخارج ونريد أن نتعرف عليهم. بإستخدام threshold، نقوم بتحديد إذا كان هناك جزء في الصورة متشابه مع ال template إذا تعدت نسبة التشابة 80% علي سبيل المثال. سنبدأ بقراءة الصورة الأصلية وال template وتحويلهم إلي ألوان رمادية:

import cv2

import numpy as np

img_rgb = cv2.imread('opencv-template-matching-python-tutorial.jpg')

img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

template = cv2.imread('opencv-template-for-matching.jpg',0)

w, h = template.shape[::-1]

سنتحتفظ بالصورة الأصلية RGB. عند التعرف علي جزء ما في الصورة الرمادية، سنقوم بتحديدة في الصورة الأصلية. سنقوم بعد ذلك بعمل template matching:

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

threshold = 0.8

loc = np.where( res >= threshold)

المتغير res هو الجزء المتشابه بين الصورة الرمادية وال template. قمنا بتحديد threshold يساوي 80% أو 0.8. بإستخدام logical statement، المناطق فقط التي تحقق الشرط سيتم إرجاعها.

بعد ذلك نقوم بتحديد المناطق في الصورة الأصلية الملونة والتي يوجد بها تشابه مع ال template:

for pt in zip(*loc[::-1]):

cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2)

cv2.imshow('Detected',img_rgb)

D:\Work\Jisr Labs\3.OpenCV\11\jisrlabs-opencvtut11-fig-2.jpg

حصلنا علي بعض المناطق. يمكننا إستخدام قيمة لل threshold أقل مثل 0.7 و النتيجة في هذه الحالة كالتالي:

D:\Work\Jisr Labs\3.OpenCV\11\jisrlabs-opencvtut11-fig-3.jpg

توجد بعض المناطق الخاطئة. يمكننا تغيير ال threshold حتي نحصل علي أفضل النتائج. حل آخر لتحسين النتيجة هو إستخدام template آخر. هذا مفيد حين التعرف علي نفس ال object في أكثر من صورة. يمكننا في هذه الحالة جعل قيمة ال threshold عالية حتي نحصل علي أدق النتائج.

في السابق، تم إستخدام ال template matching لمقارنة الصور ببعضها. الآن سنستخدم مطابقة السمات feature matching والتي تعتبر نسخة مختلفة بشكل ما عن ال template matching. تستخدم السمات في حالة أننا نريد أن نصل إلي معرفة الصورة المطابقة لصورة أخري بدقة عالية.

سنبدأ بالصورة التي نريد الحصول عليها ونبحث عنها في صورة أخري. الأمر الرائع اننا لسنا بحاجة إلى أن تكون الصور بنفس درجة الإضاءة أو الدوران أو غير ذلك من القيود التي كانت موجودة في حالة ال template matching. فقط السمات features يجب عليها أن تتطابق.

الصورة التي نريد أن نطابقها بصورة أخري هي الصورة التالية:

D:\Work\Jisr Labs\3.OpenCV\14\jisrlabs-opencvtut14-fig-1.jpg

الصورة التي سنبحث بداخلها عن تلك الصورة بالأعلي هي كالتالي:

D:\Work\Jisr Labs\3.OpenCV\14\jisrlabs-opencvtut14-fig-2.jpg

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

سنستخدم طريقة ال brute force matching والتي من خلالها سنبحث عن السمات في كل مكان في الصورة الكبيرة حتي نحصل علي الصورة التي نريدها. السمات سيتم مطابقتها بكل مكان نبحث فيه. إذا قمنا بعمل 500 مقارنة، سنحصل علي العديد من ال false positives.

import numpy as np

import cv2

import matplotlib.pyplot as plt

img1 = cv2.imread('opencv-feature-matching-template.jpg',0)

img2 = cv2.imread('opencv-feature-matching-image.jpg',0)

في الكود السابق قمنا بقراءة الصورتين. الاولي هي ال template والأخري هي الصورة التي نبحث بداخلها عن ال template.

orb = cv2.ORB_create()

سنستخدم ال ORB لإستخراج ال Features من الصور.

kp1, des1 = orb.detectAndCompute(img1,None)

kp2, des2 = orb.detectAndCompute(img2,None)

قمنا بالتعرف علي النقاط المميزة keypoints وتم وصفها بإستخدم ال ORB.

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

بإستخدام ال BFMatcher، نستطيع مقارنة السمات المستخرجة سابقاً من النقاط المميزة بين الصورتين وترتيب دقة المطابقة كالتالي:

matches = bf.match(des1,des2)

matches = sorted(matches, key = lambda x:x.distance)

أخيراً نقوم برسم أفضل 10 تطابقات تمت بين الصورتين.

img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10],None, flags=2)

plt.imshow(img3)

plt.show()

 

D:\Work\Jisr Labs\3.OpenCV\14\jisrlabs-opencvtut14-fig-3.png

المقال الأصلي:

https://pythonprogramming.net/template-matching-python-opencv-tutorial/?completed=/canny-edge-detection-gradients-python-opencv-tutorial/

https://pythonprogramming.net/feature-matching-homography-python-opencv-tutorial

تعليقات