1

I started learning Python and Deep learning a week back as I wanted to help my daughter analyze her cricket playing skills. I am using the following code from the web as my starting point as that's the closest code which I can refer.. Here is the link of the code.. https://www.analyticsvidhya.com/blog/2020/03/ball-tracking-cricket-computer-vision/

While I was able to understand and execute the code till the last step, however I got stuck with the following part of the code and I am unable to proceed since last 2 days, this is after doing all possible research at my end.

Following is the part of the code, The code line x,y,w,h = cv2.boundingRect(countours[i]) is giving an error.

!rm -r ball/*

ball_df = pd.DataFrame(columns=['frame','x','y','w','h'])
for idx in range(len(frames)):

    img= cv2.imread('FFrames/' + frames[idx])
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray,(25, 25),0)
    _ , mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
    image, contours = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)


    num=20
    cnt=0
    df = pd.DataFrame(columns=['frame','x','y','w','h'])
    for i in range(len(contours)):
        x,y,w,h = cv2.boundingRect(contours[i]) 

        numer=min([w,h])
        denom=max([w,h])
        ratio=numer/denom

        if(x>=num and y>=num):
            xmin=x-num
            ymin=y-num
            xmax=x+w+num
            ymax=y+h+num
        else:
            xmin=x
            ymin=y
            xmax=x+w
            ymax=y+h

        if(ratio>=0.5):    
            #print(cnt,x,y,w,h,ratio)
            df.loc[cnt,'frame'] = frames[idx]
            df.loc[cnt,'x']=x
            df.loc[cnt,'y']=y
            df.loc[cnt,'w']=w
            df.loc[cnt,'h']=h

            cv2.imwrite("patch/"+str(cnt)+".png",img[ymin:ymax,xmin:xmax])
            cnt=cnt+1

Error:

cv2.error: OpenCV(4.2.0) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/shapedescr.cpp:784: error: (-215:Assertion failed) npoints >= 0 && (depth == CV_32F || depth == CV_32S) in function 'pointSetBoundingRect'

Sachin
  • 11
  • 3
  • First of all, you used 'FFrames' as a folder name while mentioning 'Frames'. Make sure you're using the correct folder. And you're getting an assertion failed. This could happen because of contours[i] that you passed as a parameter of boundingRect function. Take a look at this (https://stackoverflow.com/questions/54734538/opencv-assertion-failed-215assertion-failed-npoints-0-depth-cv-32). I think this will solve your problem. – Md Shafiul Islam May 16 '20 at 14:30
  • Thanks Md Shaiful Islam for your quick response.. The folder name FFrames is correct and the first part of the code is working fine ( Basically getting the Contours).. However, when I have passed Contours[i] as parameter then its giving me an error. When I used only one frame /image to test the code, this code worked fine, however when I passed on the entire frames as stated in the previous step then I was getting the error. I also had already looked at your suggested link, but couldn't get the clue and hence thought of asking the question her.. – Sachin May 16 '20 at 15:01
  • This seems like an obvious step, but is every single file producing the error, or just a small set? Can you print out `i` and the filename before you try your operation and maybe identify a problem? – aghast May 16 '20 at 15:40

1 Answers1

1

Try using the following:

cnt = contours[i]
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])

x, w = leftmost[0], rightmost[0]
y, h = topmost[1], bottommost[1]
  • I tried your code and even printed as suggested by @ aghast.. Below is the error which I got.num=20 vcnt=0 df = pd.DataFrame(columns=['frame','x','y','w','h']) for i in range(len(contours)): cnt = contours[i] print i ,cnt leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) rightmost = tuple(cnt[cnt[:,:,0].argmax()][0]) topmost = tuple(cnt[cnt[:,:,1].argmin()][0]) bottommost = tuple(cnt[cnt[:,:,1].argmax()][0]) x, w = leftmost[0], rightmost[0] leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) too many indices for array – Sachin May 17 '20 at 02:26
  • 0 [[ 1 -1 -1 -1] [ 2 0 -1 -1] [ 3 1 -1 -1] [ 4 2 -1 -1] [ 5 3 -1 -1] [ 6 4 -1 -1] [-1 5 -1 -1]] – Sachin May 17 '20 at 02:30
  • @ Muhammad, When I printed the contours for the upper section of the code (cv2.findcontours) , surprisingly all contours values are same for all 30 frames of the interest. Is that something which is causing problem for the boundingRect function.. – Sachin May 17 '20 at 08:42
  • Can you draw the extracted contours on an individual frame and check if they're correct: cnt = contours[i] cv2.drawContours(frame, [cnt], 0, (0,255,0), 3) cv2.imwrite("test.jpg", frame) – Muhammad Taha Suhail May 17 '20 at 10:19
  • 1
    Thanks a lot @ Muhammad.. I was able to identify the problem and it happened because I tried your suggestion.. In the interest of all, I will mention it here... On one of the code line : --- contours ,hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE).. I was using this LINE :----Image, contours = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) and not including "hierarchy" .. I think this was causing the whole issue.. I was able to go past the boundingRect function.. Thanks a lot for your help.. You rock ! – Sachin May 17 '20 at 10:51
  • Oh nice, really glad you figured it out. – Muhammad Taha Suhail May 17 '20 at 18:27
  • Yes Muhammad, Thanks for your help.. How do I vote for your support.. As you could have figured out , I am bit new to even this forum, so guide me here too... Thanks again ! – Sachin May 18 '20 at 05:57
  • You're very welcome, you can just up-vote the comment that you think helped you. There's an Up arrow at the left of the comment. – Muhammad Taha Suhail May 18 '20 at 09:44