I need to detect the points along these curves, in particular I need the position on the image of one of the two points starting from the left:
I tried to detect Hough Points like that:
import cv2 import numpy as np # detect circles in the image output = image.copy() gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100) # ensure at least some circles were found if circles is not None: # convert the (x, y) coordinates and radius of the circles to integers circles = np.round(circles[0, :]).astype("int") # 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(output, (x, y), r, (0, 255, 0), 4) cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1) # show the output image cv2.imshow("output", np.hstack([image, output])) cv2.waitKey(0)
But it doesn’t get the right points and I suppose that this is because the points are positioned along the two curves. Is there a way to detect points along a curve?
Advertisement
Answer
Just found the solution following the comment of @HansHirse. I followed these steps:
- Color threshold
- Erosion
- Finding contours
This is the code:
import cv2 import numpy as np hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv_image, lowerb=(85, 0, 0), upperb=(95, 255, 255)) # Masking with green imask = mask > 0 green = np.zeros_like(hsv_image, np.uint8) green[imask] = hsv_image[imask] kernel = np.ones((8, 8), np.uint8) erosion = cv2.erode(green, kernel, iterations=1) gray = cv2.cvtColor(erosion, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # Filter out large non-connecting objects cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: area = cv2.contourArea(c) if area < 500: cv2.drawContours(thresh,[c],0,0,-1) # Morph open using elliptical shaped kernel kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3) # Find circles cnts = cv2.findContours(opening, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2] for c in cnts: area = cv2.contourArea(c) if area > 0 and area < 50: ((x, y), r) = cv2.minEnclosingCircle(c) cv2.circle(image, (int(x), int(y)), int(r), (36, 255, 12), 2) cv2.imshow('image', image) cv2.waitKey()
The result is the following image where the dots are represented by the green circles