I'm detecting contours in a video and calculating each angular displacement. Now I want to plot the angular velocities over time but I keep getting this error ValueError(f"x and y must have same first dimension, but " ValueError: x and y must have same first dimension, but have shapes (6,) and (1). Below is the code
import cv2
import numpy as np
import skimage.morphology
import matplotlib.pyplot as plt
# Load video
cap = cv2.VideoCapture("test2.mp4")
# get frame rate and frame count
fps = int(cap.get(cv2.CAP_PROP_FPS))
totalFrames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# get total duration of the video
total_duration = totalFrames / fps
... calculate prev_angle
while True:
ret, nFrame = cap.read()
if not ret:
break
roi = nFrame[304:547, 685:1044]
... pre-process roi
# find contours
newContours, _ = cv2.findContours(roi_thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
angular_velocities = []
displacements = []
time = []
# Calculate angle of the contours
for i in range(len(newContours)):
for j in range(i, len(newContours)):
new_c1 = newContours[i]
new_c2 = newContours[j]
x1, y1, w1, h1 = cv2.boundingRect(new_c1)
x2, y2, w2, h2 = cv2.boundingRect(new_c2)
# find centroid of each contours
newM1 = cv2.moments(new_c1)
if newM1['m00'] != 0:
new_cx1 = int(newM1['m10'] / newM1['m00'])
new_cy1 = int(newM1['m01'] / newM1['m00'])
else:
new_cx1, new_cy1 = 0, 0
# view the centre of contour
cv2.circle(roi, (new_cx1, new_cy1), 3, (0, 0, 255), -1)
newM2 = cv2.moments(new_c2)
if newM2['m00'] != 0:
new_cx2 = int(newM2['m10'] / newM2['m00'])
new_cy2 = int(newM2['m01'] / newM2['m00'])
else:
new_cx2, new_cy2 = 0, 0
# view the center of contour
cv2.circle(roi, (new_cx2, new_cy2), 4, (0, 255, 0), 1)
newAngle = np.arctan2(new_cy2 - new_cy1, new_cx2 - new_cx1)
newAngle = (np.rad2deg(newAngle))
# newAngle = (newAngle + 180) % 360 - 180
# print("Angle between contour {} and {} is {:.2f} degrees".format(i+1, j, newAngle)) #working
cv2.drawContours(roi, [new_c1, new_c2], 0, (0, 0, 255), 1)
text = "C" + str(i+1)
cv2.putText(roi, text, (new_cx1, new_cy1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
# calulate angular displacement
delta_angle = newAngle - prev_angle
print("Angular displacement of contour {} is {:.2f} degrees".format(i+1, delta_angle)) # working
prev_angle = newAngle
displacements.append(delta_angle)
time = [i/fps for i in range(len(displacements))]
current_Frame = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
delta_t = (current_Frame - prev_Frame) / fps
angularVelocity = delta_angle / delta_t if delta_t != 0 else 0
# skeltonize
threshSkeleton = (roi_thresh / 255).astype(np.float64)
skeleton = skimage.morphology.skeletonize(threshSkeleton)
skeleton = (255 * skeleton).clip(0, 255).astype(np.uint8)
# Thickness
cntr = newContours[i]
length = cv2.arcLength(cntr, True)
# print("length of contour {}: {:.2f}".format(i+1, length))
area = cv2.contourArea(newContours[i])
if length == 0:
continue
thickness = (area / length) * 0.264
# print("Thickness of contour {} is {:.2f} mm".format(i+1, thickness)) #working
angular_velocities.append(angularVelocity)
prev_Frame = current_Frame
current_Frame = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
# time.append(current_Frame / fps)
# time = current_Frame/fps
# cv2.imshow("ROI", roi)
cv2.imshow("frame", nFrame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
# plt.plot(angular_velocities)
for i in range(len(displacements)):
plt.plot(time, displacements[i], label='Contour{}'.format(i + 1))
plt.xlabel("Time (s)")
plt.ylabel('Angular displacement (degrees per second)')
plt.title('Angular displacement over time')
plt.show()
any help is highly appreciated. Also if there are any other errors, please do let me know. Thanks