Detect glasses and get coordinates

Hello, I am working on a Python script which uses a live video from a camera and detects every circle in the image. My goal is to detect glasses in the video and return the coordinates of every circle or glass in a CSV file. My problem is now that if I light the video with a bright light from above I can detect the glasses more easily but the problem is that I every glass has multiple circles (Image).
Normal_Frame
These are the images. Since all the circles are in about the right position I just want to get an average of every circle and store it in a csv file. The next step would be to modify the program so that it can detect multiple glasses and store every average of every circle in a separate file. I would be very grateful for every idea. I understand that that’s a fairly difficult task. Here is my current code:

import cv2
import numpy as np
import os

def save_coordinates_to_csv(circle_index, circle_array):
    csv_file_path = f"raw_Coordinates\circle_{circle_index}_coordinates.csv"
    with open(csv_file_path, "a") as file:
        file.write(f"{circle_array[0]},{circle_array[1]}\n")


def detect_circles(frame):
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    _, bw_frame = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)

    blurred = cv2.GaussianBlur(bw_frame, (9, 9), 2)

    circles = cv2.HoughCircles(
        blurred,
        cv2.HOUGH_GRADIENT,
        dp=1,
        minDist=5,
        param1=50,
        param2=30,
        minRadius=10,
        maxRadius=45
    )

    cv2.imshow('Black and White Frame', bw_frame)

    if circles is not None:
        circles = np.uint16(np.around(circles))
        printed_circle_arrays = set()
        detected_circles_count = 0

        for i in circles[0, :]:
            circle_array = tuple(i)

            if circle_array not in printed_circle_arrays:
                cv2.circle(frame, (i[0], i[1]), i[2], (0, 255, 0), 2)  # inner
                cv2.circle(frame, (i[0], i[1]), 2, (0, 0, 255), 3)  # outer

                printed_circle_arrays.add(circle_array)
                detected_circles_count += 1

                save_coordinates_to_csv(detected_circles_count, i)

        print(f"Detected Circles: {detected_circles_count}")

    return frame


def delete_small_files(input_folder, percentage_threshold):
    file_sizes = []

    # Iterate through all files in the input folder
    for filename in os.listdir(input_folder):
        file_path = os.path.join(input_folder, filename)
        if os.path.isfile(file_path):
            file_sizes.append((filename, os.path.getsize(file_path)))

    # Calculate the average file size
    total_size = sum(size for _, size in file_sizes)
    average_size = total_size / len(file_sizes) if file_sizes else 0

    # Delete files smaller than the specified percentage of the average size
    for filename, size in file_sizes:
        if size < (1 - percentage_threshold / 100) * average_size:
            file_path = os.path.join(input_folder, filename)
            os.remove(file_path)
            print(f"Deleted file: {filename}")
        else:
            print("No File deleted")


def main():
    cap = cv2.VideoCapture(0)

    if not cap.isOpened():
        print("Error: Could not open camera.")
        return

    while True:
        ret, frame = cap.read()
        if not ret:
            print("Error: Failed to capture frame.")
            break

        frame_with_circles = detect_circles(frame)

        cv2.imshow('Circle Detection', frame_with_circles)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

I am also open for other solutions.

… are rarely circles.

are those real world photos or is this in-game graphics? I can’t tell from that image you posted.

as a beginner, you should steer clear of all the newbie traps: Canny, Hough, matchTemplate.

Thats real-world footage. Why isn’t Hough the best solution and what could I also try?

Hough requires a circle, not just something roundish.

let me reiterate: steer clear of the noob traps. don’t even touch those things. you don’t have the experience to know when to choose what approach. present your problem (the task to solve) standalone, clearly. then you can consider approaches. don’t present the failure of one chosen approach and ask how to make it work. your chosen approach may simply not work. this can’t be discussed without having proper facts, like…

you might wanna present a clear picture of your object. all the stuff drawn over it obscures the object itself.

you also might wanna present the expected variation in appearance of your objects.

you speak of “glasses”. what exactly does that mean? in your picture, I can’t see anything that looks like eyeglasses, spectacles, …

also: crosspost:

Ok so here is what I want to do:
I built a scara robot that should pour out drinks. The robot itself works fine but now I need a program that can detect glasses which are put in a certain area and return the coordinates of it. Here is a more clear image of a glass:

I know that a clear glass isn’t ideal but the solution that worked is that I just illuminate it from above with a bright light so that I get a clear spot when I apply a black and white filter (The weird underlay reduces the reflection so that only the glass reflects). Now I want to find a way with which I can detect this roundish glass. I of course know the approximate size of the glass so I can filter out everything that’s below or above this size. If Hough isn’t really a solution what could I try?

just use AI. I’m sure any of the currently popular object detection models can find these objects. you may have to finetune one of them a little. that means you take a trained net and train the last layer to respond to your object class.

1 Like