How to detect many small red laser dots correctly using CV?

I am working on a project, which needs to detect many small red laser dots correctly using Opencv. In the end, I want to find all the red laser dots out correctly. Now I changed the rgb to hsv and set the range to detect red dots, then used the canny and findContours function in the opencv to detect the edge and find countours. However, the result isn’t very good. There are about 44 lasers here, some red dots weren’t detected well. you could see the picture below. Could you give me some advice about it?

The code is below:

cap = cv2.VideoCapture(0)
# set red thresh 
lower_red = np.array([0,0,255])
#156, 100, 40
upper_red = np.array([180,255,255])
while(1):
    ret, frame0 = cap.read()
    frame = cv2.flip(frame0,0)
    frame = frame[50:360,280:380]
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower_red, upper_red)   
    edged = cv2.Canny(mask, 30, 200)    
    cv2.imshow('Canny Edges After Contouring', edged)
    _, contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    print("Number of Contours found = " + str(len(contours)))

    # Draw all contours
    # -1 signifies drawing all contours
    # for c in contours:
    #   M = cv2.moments(c)
    #   cX = int(M["m10"] / M["m00"])
    #   cY = int(M["m01"] / M["m00"])
    #   cv2.drawContours(frame, c, -1, (0, 255, 0), 3)
    #   cv2.circle(frame,(cX,cY),2,(255,255,255),-1)
    #   cv2.putText(frame,"center",(cX - 20, cY - 20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),2)
    cv2.imshow('Capture',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()

cv2.destroyAllWindows()


The laser lights picture is here.

your first mistake was to use Canny. don’t use it.

First, try to underexpose the image. As the laser is more powerful than the light, you might have a dark image with a few bright spots to detect.
Then, try to binarize the image (threshold or inRange), clean it up with morphological operations and run connectedComponentsWithStats to get the centroid of the dots.

Hi crackwitz, You are right, tks. I stop using Canny, the result is better. But the result is not very stable. The total number of red dots changed sometimes, but the precise final result is very import to me. Right now I put the camera and laser lights on the same side and the camera position is higher than laser lights, so it is kind of a top view, making the laser lights in the bottom really close to each other in the picture from the camera. I think that is the reason why the final result is not stable. Do you know how to solve it?

This is the result right now

This is the picture captured by the camera

you need more underexposure (i.e. less exposure).

and you should refrain from posting literal photos of a computer screen. there’s a “Print Screen” key on most keyboards and most operating systems do something sensible when that key is pressed.

Hey there.
I am working on something similar to this i.e. marksman simulator. A laser light emits from the gun and points on the bullseye on LED screen. The backend code and all the calculations are in OpenCV and frontend is in .NET and both are connected with local server using IP address. And a camera is placed in front of LED which detects the red laser dot(emits from the gun) and give detected coordinates to python code and and after calculation the coordinates it decodes the points to .NET code and it places the bullet like hole in the canvas ON THE SCREEN
Now i need help with the following :

  1. Detection Accuracy.
  2. Camera not able to detect some shots. Reason?
  3. Do i need to go towards the ML or this is fine?
    4.Will ask more