I have an image where there are some star streaks, with the help of edge detection and non max suppression, I am able to convert it into grayscale Image with Edges. I need to get the angle w.r.t. the x-axis at which the streaks are pointing. These are my Images
From this Image I generate the Image containing edges. (The orientation is different because the ds9 software for viewing astronomical images plot it with lower origin coordinates)
I have tried a number of ways including PCA and Connected components but the results are not consistent. All I want is the mean angle at which the streaks are oriented with minimum possible error. I'd be grateful if anyone can help me with this
CodePudding user response:
Imho one option could be convert each streak into a 2d vector, and calculate the average angular coefficient
For getting the lines I suggest to look into the Hough lines method https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html
With some image cleanup and tuning a bit the function parameters(especially min lenght and max gap values), you should be able to get those vectors
Then, calculate for each vector the inclination (y2-y1) / (x2-x1), take the average and here you go
CodePudding user response:
Here's a possibility with following method:
- threshold to black and white
- find contours
- iterate over contours fitting rotated rectangle to each
- discard small contours
- print angle of rotation of rectangle
#!/usr/bin/env python3
import cv2
# Load image as greyscale
im = cv2.imread('trails.png', cv2.IMREAD_GRAYSCALE)
# Threshold for just the brightest things
_, thr = cv2.threshold(im, 192,255,type=cv2.THRESH_BINARY)
# Find contours
contours,hierarchy = cv2.findContours(thr, 1, 2)
# Iterate over contours
for cnt in contours:
# Get area of blob
area = cv2.contourArea(cnt)
# Only work with decent size blobs - ignore smallest ones
if area > 8:
center, size, angle = cv2.minAreaRect(cnt)
print(f'Area: {area}, angle: {angle}')
I get these results:
Area: 10.5, angle: 11.309932708740234
Area: 11.5, angle: 18.43494987487793
Area: 12.0, angle: 14.03624439239502
Area: 74.5, angle: 9.462322235107422
Area: 9.5, angle: 14.03624439239502
Area: 35.0, angle: 11.309932708740234
Area: 30.5, angle: 18.434947967529297
Area: 11.5, angle: 18.43494987487793
Area: 16.0, angle: 18.43494987487793
Area: 9.0, angle: 11.309932708740234
Area: 27.0, angle: 26.56505012512207
Area: 15.5, angle: 21.801410675048828
Area: 9.0, angle: 14.03624439239502
Area: 10.5, angle: 11.309932708740234
Area: 16.0, angle: 18.43494987487793
Area: 32.0, angle: 14.03624439239502
Area: 14.0, angle: 14.03624439239502
Area: 46.0, angle: 11.309932708740234
Area: 25.0, angle: 15.945395469665527
Area: 14.0, angle: 14.03624439239502
Area: 18.0, angle: 90.0
Area: 24.5, angle: 11.309932708740234
Area: 10.0, angle: 14.03624439239502
Area: 36.0, angle: 9.462322235107422
Area: 16.5, angle: 18.43494987487793
Area: 23.5, angle: 11.309932708740234
Area: 11.0, angle: 18.43494987487793
Area: 11.5, angle: 14.03624439239502
Area: 16.5, angle: 14.03624439239502
Area: 12.0, angle: 14.03624439239502
Area: 18.0, angle: 18.43494987487793
Area: 11.5, angle: 14.03624439239502
Area: 23.5, angle: 11.309932708740234
Area: 14.0, angle: 14.03624439239502
Area: 28.0, angle: 11.309932708740234
Area: 18.0, angle: 18.434947967529297
Area: 16.0, angle: 15.945395469665527
Area: 9.0, angle: 15.945395469665527
Area: 10.0, angle: 14.03624439239502
Area: 10.5, angle: 14.03624439239502
Area: 11.0, angle: 14.03624439239502
Area: 8.5, angle: 14.03624439239502
Area: 15.0, angle: 18.43494987487793
Area: 19.0, angle: 14.03624439239502
Area: 20.5, angle: 14.03624439239502
Area: 37.5, angle: 90.0
Area: 34.5, angle: 90.0
Area: 11.5, angle: 14.03624439239502
Area: 27.0, angle: 14.03624439239502
Area: 22.5, angle: 90.0
Area: 8.5, angle: 18.434947967529297
Area: 13.0, angle: 14.03624439239502
Area: 10.0, angle: 15.945394515991211
Area: 12.0, angle: 14.03624439239502
Area: 25.0, angle: 14.03624439239502
Area: 16.0, angle: 90.0
Area: 9.0, angle: 14.03624439239502
I guess you could further refine the assumptions and parameters, and smooth or statistically analyse the angles further - but they seem to average around 14 degrees
I just guessed a threshold of 192 to get something sensible. Tune this.
I just plucked a minimum area of 8 from thin air so that I am only looking at decent size blobs, and disregarding tiny, direction-less blobs. Tune this.