0

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:

enter image description here

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?

3
  • 2
    If you know the two colors, color threshold the image, and erode the resulting mask, such that the points remain, but the line disappears. Find contours on the remaining points. Do that for both colors. That approach might fail for the "background" colored line (here: red) for overlapping points. If so, use some information already obtained from the "foreground" colored line (here: blue). Commented Jan 21, 2021 at 13:52
  • A very very simple method for the starting points: scan the image by columns and stop at the first pixel of the desired color. Elementary, but bulletproof. Commented Jan 21, 2021 at 13:55
  • @HansHirse I followed your steps and it worked like a charm. Thanks! I posted the answer with the result Commented Jan 21, 2021 at 15:37

1 Answer 1

3

Just found the solution following the comment of @HansHirse. I followed these steps:

  1. Color threshold
  2. Erosion
  3. 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

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.