0

I've been trying to implement a code in Python, using the OpenCV library, that is able to read some input image and look for a match, live through camera. So far, I've succeed to accomplish this goal, adapting a script found online, as posted below. It's basically read the image and if it has a match live it prints "Image found..." and if doesn't print "Not Enough match found-...".

Now, I'm trying to put a break if the image doesn't match but with a time wait. In other words, if there is no correspondent image to match, I want that the code wait for n seconds and if in this period no matching found, the loop will break.

After some research online, I've implemented the

if (time.time() - start) > MAX_TIME_ALLOWED

show in code but this isn't working as expected, since it sometimes break even if there's a match.

import cv2
import numpy as np
import time

MIN_MATCH_COUNT=30
MAX_TIME_ALLOWED = 10 # seconds
start = time.time()

# Initiate SIFT detector
detector=cv2.xfeatures2d.SIFT_create()

# FLANN parameters
FLANN_INDEX_KDITREE=0
flannParam=dict(algorithm=FLANN_INDEX_KDITREE,tree=5)
flann=cv2.FlannBasedMatcher(flannParam,{})

# read the image and find the keypoints and descriptors with SIFT
trainImg=cv2.imread('IMAGE_EXAMPLE.jpg',0)
trainKP,trainDesc=detector.detectAndCompute(trainImg,None)

cam=cv2.VideoCapture(0)

while True:
    ret, QueryImgBGR=cam.read()
    QueryImg=cv2.cvtColor(QueryImgBGR,cv2.COLOR_BGR2GRAY)
    queryKP,queryDesc=detector.detectAndCompute(QueryImg,None)
    matches=flann.knnMatch(queryDesc,trainDesc,k=2)

    goodMatch=[]
    for m,n in matches:
        if(m.distance<0.75*n.distance):
            goodMatch.append(m)

    if(len(goodMatch)>MIN_MATCH_COUNT):
        print ("Image found - %d"%(len(goodMatch)))
        continue

    else:
        if (time.time() - start) > MAX_TIME_ALLOWED:
            print ("Not Enough match found- %d/%d"%(len(goodMatch),MIN_MATCH_COUNT))
            break

cam.release()
cv2.destroyAllWindows()

Is there any other way I can put a wait of n seconds before the code break?

JPS
  • 13
  • 2
  • [`time.sleep()`](https://docs.python.org/3/library/time.html#time.sleep) – wwii Aug 23 '19 at 13:38
  • If every picture matches, your `while` loop will run forever. Is this what you want? – Dion Aug 23 '19 at 13:39
  • Possible duplicate of [How can I make a time delay in Python?](https://stackoverflow.com/questions/510348/how-can-i-make-a-time-delay-in-python) – wwii Aug 23 '19 at 13:40
  • you should use `>=` instead of `>` in `len(goodMatch)>MIN_MATCH_COUNT`. Then in `else` you will have always `len(goodMatch) – furas Aug 23 '19 at 13:51
  • @wwii I've tried the time.sleep(), and implementations from the link you send but it doesn't fit well for what I needed. Thank you anyway! – JPS Aug 23 '19 at 14:53
  • @Dion yes, for the purpose I intended to apply it will 'run forever' as long the code is running. – JPS Aug 23 '19 at 14:53

1 Answers1

0

You should change the start variable inside the if block if there is a match. Otherwise, after you exceed the MAX_TIME_ALLOWED the first non-match frame will break the while loop.

import cv2
import numpy as np
import time

MIN_MATCH_COUNT=30
MAX_TIME_ALLOWED = 10 # seconds
start = time.time()

# Initiate SIFT detector
detector=cv2.xfeatures2d.SIFT_create()

# FLANN parameters
FLANN_INDEX_KDITREE=0
flannParam=dict(algorithm=FLANN_INDEX_KDITREE,tree=5)
flann=cv2.FlannBasedMatcher(flannParam,{})

# read the image and find the keypoints and descriptors with SIFT
trainImg=cv2.imread('IMAGE_EXAMPLE.jpg',0)
trainKP,trainDesc=detector.detectAndCompute(trainImg,None)

cam=cv2.VideoCapture(0)

while True:
    ret, QueryImgBGR=cam.read()
    QueryImg=cv2.cvtColor(QueryImgBGR,cv2.COLOR_BGR2GRAY)
    queryKP,queryDesc=detector.detectAndCompute(QueryImg,None)
    matches=flann.knnMatch(queryDesc,trainDesc,k=2)

    goodMatch=[]
    for m,n in matches:
        if(m.distance<0.75*n.distance):
            goodMatch.append(m)

    if(len(goodMatch)>MIN_MATCH_COUNT):
        print ("Image found - %d"%(len(goodMatch)))
        start = time.time()
        continue

    else:
        if (time.time() - start) > MAX_TIME_ALLOWED:
            print ("Not Enough match found- %d/%d"%(len(goodMatch),MIN_MATCH_COUNT))
            break

cam.release()
cv2.destroyAllWindows()
aesari
  • 207
  • 1
  • 6
  • Thank you @aesari, that's exactly what I needed. Now I understand what I've been doing wrong. – JPS Aug 23 '19 at 14:47