Search code examples
pythonopencvcomputer-visiongeometryhough-transform

Why does python OpenCV GUI crashes in simple video circle detection program on linux?


Snapshot of the issue I have been trying to detect circles in a video. I checked many tutorials and stackoverflow questions, and my code seems correct. It even compiles correctly. However it takes time to open the GUI window, and as soon as it opens, it crashes. Here is my code is there any problem with it?

`

import cv2
import numpy as np

cap  = cv2.VideoCapture('Red Motion Spin Looping Motion Background.mp4')
while (cap.isOpened()):
    ret,img = cap.read()
    img = cv2.medianBlur(img,5) 
    cimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    circles = cv2.HoughCircles(cimg,cv2.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=0,maxRadius=0)

    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
            # draw the outer circle
            cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
            # draw the center of the circle
            cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

    cv2.imshow('detected circles',cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()

` UPDATE: I followed @Micka 's advice and the window showed up. However it took forever to open and it does not go beyond the first frame of the video screenshot of the current situation


Solution

  • Below is a workable code tested with Python 2.7.12 and OpenCV3.2.0.

    import numpy as np
    import cv2
    
    capture = cv2.VideoCapture("001.mp4")
    #capture = cv2.VideoCapture(0)
    
    while capture.isOpened():
        # grab the current frame and initialize the status text
        grabbed, frame = capture.read()
    
        if frame is not None:
            # convert the frame to grayscale, blur it, and detect circles
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            blur = cv2.medianBlur(gray,5) 
            circles = cv2.HoughCircles(blur,cv2.HOUGH_GRADIENT,1,20, \
                                       param1=50,param2=30,minRadius=0,maxRadius=0)
    
            if circles is not None:
                # convert the (x, y) coordinates and radius of the circles to integers
                circles = np.round(circles[0, :]).astype("int")
                #circles = np.uint16(np.around(circles[0,:]))
    
                # loop over the (x, y) coordinates and radius of the circles
                for (x, y, r) in circles:
                    # draw the circle in the output image, then draw a rectangle
                    # corresponding to the center of the circle
                    cv2.circle(frame, (x, y), r, (255, 0, 255), 2)
    
                # show the frame and record if a key is pressed
                cv2.imshow("Frame", frame)
                # if the 'q' key is pressed, stop the loop
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
    
    capture.release()
    cv2.destroyAllWindows()
    


    The major change is on the for (x, y, r) in circles: loop to get and draw the circles. The video playback is a bit slow once added cv2.medianBlur(). It even further slowed down with cv2.HoughCircles() detection.

    Here is the screenshot of the video playback with circles. Presume that you may need to modify cv2.HoughCircles() function parameters and the circles retrieval to meet your requirement.

    enter image description here

    Hope this help.