Lesson_27_Matching

  |   Source

مطابقة السمات + تحويلات لايجاد الاجسام:

الهدف:

  • سندمج بهذا الفصل مطابقة السمات مع ايجاد التحويلات , عبر calib3d لايجاد أجسام معروفة بصور مختلطة المشهد.

الاساسيات:

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

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

ولهذا يمكننا استخدام التابع التالي : ()cv2.findHomography . واذا مررنا مجموعة من النقاط من كلا الصورتين , فسنجد التحويلات الاسقاطية لهذا الجسم . ومن ثم يمكننا استخدام ()cv2.perspectivTransform لايجاد الجسم , ونحتاج على الاقل أربعة نقاط متطابقة لايجاد التحويل .

ولقد راينا سابقاً إمكانية حدوث أخطاء أثناء المطابقة تؤثر على النتيجة .

ولحل هذه المشكلة نستخدم خوارزمية RANSAC أو LEAST_MEDIAN (ونحدد ذلك عبر الاعلام ). ولذلك فالمطابقات الجيدة التي تعطي تقديرات جيدة تدعى inliers والمتبقية تدعى outliers , والتابع ()cv2.findHomography يعطي قناعاً يصنف السمات لاحد المجموعتين السابقتين .

البرنامج :

أولا نبحث عن سمات SIFT أو ORB أو FAST , بالصورتين ونطابق الموصفات ثم نعزل المطابقات الغير دقيقة وفق اختبار النسبة

In [2]:
import cv2
import numpy as np

import matplotlib.pyplot as plt

%matplotlib inline

img1 = cv2.imread('images/query.png',0)          # queryImage
img2 = cv2.imread('images/train.jpg',0) # trainImage
In [6]:
# Initiate ORB detector
orb = cv2.ORB_create()

# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Match descriptors.
matches = bf.match(des1,des2)

# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# Take the Best
good = matches[:40]

والان نضع شرطأ انه يجب ايجاد عشرة مطابقات على الاقل لايجاد الجسم . والا ستظهر رسالة تقول أن عدد النقاط غير كافي .

أما اذا أوجدنا مطابقات كافية , سنشتق الخصائص للنقاط المتطابقة بكلا الصورتين , ومن ثم نمررها لايجاد التحويل الاسقاطي . وبعد حصولنا على المصفوفة 3x3 , نستخدمها لتحويل زوايا الصورة المستفسر عنها للمكان المرتبط بالصورة , المستفسر فيها , ومن ثم نرسم .

In [7]:
MIN_MATCH_COUNT = 10

if len(good)>MIN_MATCH_COUNT:
    src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
    dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
    
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
    matchesMask = mask.ravel().tolist()
    
    h,w = img1.shape
    pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
    dst = cv2.perspectiveTransform(pts,M)
    
    img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA)
    
else:
    print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT)
    matchesMask = None
    

أخيرأً نرسم النقاط الصحيحة (إذا وجدنا الجسم) أو النقاط المتطابقة (إذا فشلت العملية ) .

In [ ]:
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
                   singlePointColor = None,
                   matchesMask = matchesMask, # draw only inliers
                   flags = 2)

img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)

cv2.imwrite('figure_4.png',img3)
In [9]:
from IPython.display import Image

Image('images/figure_4.png')
Out[9]:

لاحظ النتائج اعلاه , حددنا الجسم باللون الابيض بالصورة .

مراجع اضافية

تمارين

Comments powered by Disqus