Reputation: 1
Note; It's a Free Hand Curve line but not a straight or Polylines so it can be more complex.
I want to calculate the angle (in degree) of Free curve line on every bending position, and want to display where the curve is greater than 45, and less than 45 degree.
It's calculating the angle between two consecutive curve using
np.arccos()
method.
....
largest_contour = max(filter_coontour, key=cv2.contourArea)
# Simplify the curve using the Ramer-Douglas-Peucker algorithm
epsilon = 0.001 * cv2.arcLength(largest_contour, True)
simplified_curve = cv2.approxPolyDP(largest_contour, epsilon, True)
# Get the coordinates of the points along the simplified curve
curve_points = simplified_curve.reshape(-1, 2)
for i in range(1, len(curve_points)):
vector = curve_points[i] - curve_points[i - 1]
if prev_vector is not None:
dot = np.dot(vector, prev_vector)
norm = np.linalg.norm(vector) * np.linalg.norm(prev_vector)
angle = np.arccos(dot / norm) * 180 / np.pi
print("angle", angle)
....
Above are my Code, but it's not giving me the accurate angle value. please see the attached image
Upvotes: 0
Views: 171
Reputation: 3437
If you simplify the curve using Douglas-Peucker (or other similar methods) you introduce artifacts like straightened segments and sharper direction changes. Instead, you might prefer using any method that slightly softens the shape (blur and threshold, for example).
This paper describes a method used for measuring local properties of hand-free drawn curves, like angle and curvature.
Basically, using three neighboring pixels you can calculate the osculating circle, from which you derive local stroke angle and curvature.
The three pixels shouldn't be consecutive, otherwise you would get a limited set of possible values. They should be separated by 2 or more pixels, depending on your resolution. For example, you may calculate the result for pixels (0,3,6) associating the result to pixel 3, then (1,4,7), (2,5,8),...
I hope this helps.
Upvotes: 0