Franc Weser
Franc Weser

Reputation: 869

Reduce image of stars into star coordinates with radius (Numpy/OpenCV)

I have an image of stars, like this one:

Stars

Now, I want to get the 100 brightest stars, and reduce these to four data points each: 1. X-coordinate, 2. Y-coordinate, 3. brightness, 4. radius. That's it. Basically, I want to reduce these 800x480px = 384000 data points into 100*4 data points while still keeping most information (star position, star brightness and star radius).

My current approach, to find the brightest stars:

np.where(star_image_array**2 > threshold, 1, 0)

Then I run a gaussian filter on the result, and do another selection for the highest values. But this still doesn't solve the problem of how to select distinct star coordinates (not to mention the brightness and radius).

Could someone point me to the right direction to solve this challenge, or provide me with some resources? Thanks!

Upvotes: 0

Views: 878

Answers (1)

shortcipher3
shortcipher3

Reputation: 1380

You could use contours to find the stars in your thresholded image, something like this:

ret, mask = cv2.threshold(img, 100, 255, cv2.CV_8U)
contours, hierarchy = cv2.findContours(mask, 1, 2)
stars = []
for cnt in contours:
  area = cv2.contourArea(cnt)
  if area < 2:
    continue
  x, y, w, h = cv2.boundingRect(cnt)
  # 1. X-coordinate
  x_coord = x + w/2.0
  # 2. Y-coordinate
  y_coord = y + h/2.0
  # 3. brightness
  star_mask = np.zeros(img.shape,np.uint8)
  cv2.drawContours(star_mask, [cnt], 0, 255, -1)
  mean_val = cv2.mean(img, mask=star_mask)[0]
  min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(img, mask=star_mask)
  # 4. radius
  radius = np.sqrt(area/(2*np.pi))
  stars.append({'x': x_coord,
                'y': y_coord,
                'mean_brightness': mean_val,
                'max_brightness': max_val,
                'radius': radius})

There is a colab with the example code here.

Upvotes: 1

Related Questions