1

I going to create a python script that detect a object and draw lines around it, after that i will also draw 4 lines around it that act as a border. When the object line collide with either any 4 lines around it, it will perform an action (temporary just print left, right, up, down).View the sample

The problem I facing now is, I don't know how to get the lines coordinate of the object as it is polylines. For the 4 line around the image that form a square, it is actually rectangle that draw like a line.

This is the code for initializing the coordinate of the rectangle around the image.

import pygame, sys, random
import cv2
import numpy as np
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()

WINDOWWIDTH = 640
WINDOWHEIGHT = 480
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Collision Detection')
SIZE = 7
bouncer = {'rect':pygame.Rect(300, 100, 50, 50), 'dir':UPLEFT}
RED =   (255, 0, 0)

upLine = pygame.Rect(50, 50, 540, SIZE)
leftLine = pygame.Rect(50, 50, SIZE, 380)
rightLine = pygame.Rect(583, 50, SIZE, 380)
downLine = pygame.Rect(50, 430, 540, SIZE)

This is the code for detecting the object and draw the line around it.

MIN_MATCH_COUNT=30

detector=cv2.xfeatures2d.SIFT_create()

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

trainImg=cv2.imread("ObjectTest.jpg",0)
trainKP,trainDesc=detector.detectAndCompute(trainImg,None)

cam=cv2.VideoCapture(0)
# run the game loop
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=[]

   # check for the QUIT event
    for event in pygame.event.get():
        if event.type == QUIT:
            cam.release()
            pygame.quit()
            sys.exit()

    windowSurface.fill(BLACK)

    for m,n in matches:
        if(m.distance<0.75*n.distance):
            goodMatch.append(m)
    if(len(goodMatch)>MIN_MATCH_COUNT):
        tp=[]
        qp=[]
        for m in goodMatch:
            tp.append(trainKP[m.trainIdx].pt)
            qp.append(queryKP[m.queryIdx].pt)
        tp,qp=np.float32((tp,qp))
        H,status=cv2.findHomography(tp,qp,cv2.RANSAC,3.0)
        h,w=trainImg.shape
        trainBorder=np.float32([[[0,0],[0,h-1],[w-1,h-1],[w-1,0]]])
        queryBorder=cv2.perspectiveTransform(trainBorder,H)
        cv2.polylines(QueryImgBGR,[np.int32(queryBorder)],True,(0,255,0),5)
    else:
        print("Not Enough match found- %d/%d"%(len(goodMatch),MIN_MATCH_COUNT))
    QueryImgBGR = cv2.cvtColor(QueryImgBGR, cv2.COLOR_BGR2RGB)
    QueryImgBGR = np.rot90(QueryImgBGR)
    QueryImgBGR = pygame.surfarray.make_surface(QueryImgBGR)
    QueryImgBGR = pygame.transform.flip(QueryImgBGR,True,False)
    windowSurface.blit(QueryImgBGR, (0,0))

This is the code to draw the 4 line to form a square beside the image.

    pygame.draw.rect(windowSurface, GREEN, upLine)
    pygame.draw.rect(windowSurface, GREEN, leftLine)
    pygame.draw.rect(windowSurface, GREEN, rightLine)
    pygame.draw.rect(windowSurface, GREEN, downLine)

    print(queryBorder)
     # draw the window onto the screen
    pygame.display.update()
    mainClock.tick(40)

I don't know how to get the coordinate of the polylines, i'm trying to use this to get it:

print(queryBorder)

But i get the 4 coordinate, how to only get 1 of it? or isit other way to do this? View sample

I have also refer to the code at this website https://inventwithpython.com/chapter18.html for the COLLISION DETECTION between 2 rectangle. I actually thinking to draw a rectangle around the object it detected, but i don't know how to draw it and perspectiveTransform the rectangle to my object at the same time.

Leong JC
  • 11
  • 1
  • 2

0 Answers0