I want to find a laser beam in different images.
Example image:
The Original one:
I found different approaches, but somehow it doesn't seem to work. I have now also used a threshold:
logicM = image > Threshold
plt.figure()
plt.imshow(logicM, cmap='gray')
plt.axis('image')
plt.title(laserColor + ' band intensity over ' + str(Threshold))
to identify the line. Now I want to mark the beam with a dashed line... and then plot the intensity over height (i.e., pixels)... how can this be done? I just can't figure it out.
I found this: Vertical curved line detection with OpenCV and that Draw a curve line going through the blobs in OpenCV C++
both doesn't work.
EDIT: The theoretical equations can be found here, but is there a easy opencv solution?: https://mv.in.tum.de/_media/members/steger/publications/1996/icpr-96-steger.pdf
EDIT2: I tried this, to get the values between the contour.
# Sort the contour points by their y-value
contour_points_by_row = {}
for contour in contours:
print(contour)
for point in contour:
x, y = point[0] # Zugriff auf die x- und y-Koordinaten
if y in contour_points_by_row:
contour_points_by_row[y].append(x)
else:
contour_points_by_row[y] = [x]
But the array is to short. Ony further ideas?
This does the trick to isolate the beam – there's probably some tool for getting a polyline approximation instead of an area contour too...
import cv2
from matplotlib import pyplot as plt
img = cv2.imread("hQiak.png")
# Mask in HSV space to keep only the vivid red color
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_red = (0, 100, 20)
upper_red = (10, 255, 255)
mask = cv2.inRange(hsv, lower_red, upper_red)
plt.imshow(mask, cmap="gray")
# Detect contours from mask
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Only keep the largest contour
contours = [max(contours, key=cv2.contourArea)]
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
plt.figure(dpi=250)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()