import cv2
import numpy as np
import matplotlib.pyplot as plt
# 给角点排序
def order_points(pts):
# 创建全是0的矩阵, 来接收等下找出来的4个角的坐标.
rect = np.zeros((4, 2), dtype='float32')
s = pts.sum(axis=1)
# 左上的坐标一定是x,y加起来最小的坐标. 右下的坐标一定是x,y加起来最大的坐标.
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
# 右上角的x,y相减的差值一定是最小的.
# 左下角的x,y相减的差值, 一定是最大.
diff = np.diff(pts, axis=1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
return rect
# 求出圆心
def cpoint(box):
a = []
a.append(box[0])
a.append(box[1])
a.append(box[2])
a.append(box[3])
pt1 = np.array(a).mean(axis=0)
y = int(4/3 * (pt1[1] - 242) + 242)
x = int(4/3 * (pt1[0] - 247) + 247)
return x,y
cap = cv2.VideoCapture('./movie.mp4')
ret, frame = cap.read()
plt.imshow(frame)
while cap.isOpened():
# 读一帧数据, 返回标记和这一帧数据. True表示读到了数据, False表示没读到数据.
ret, frame = cap.read()
# 可以根据ret做个判断
if not ret:
# 没读到数据, 直接退出
break
f = frame.copy()
frame = frame[200:650, 700:1200]
# 二值化
dst = cv2.inRange(frame, (70, 150, 50), (120, 255, 255))
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
dst = cv2.dilate(dst, kernel, iterations=3)
canny = cv2.Canny(dst, 100, 200)
contours, hierarchy = cv2.findContours(
dst, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = list(contours)
contours2 = []
for c in contours:
if cv2.contourArea(c) >= 3000:
contours2.append(c)
contours = sorted(contours2, key=lambda x: cv2.contourArea(x), reverse=True)
if len(contours) >= 4:
c = contours[3]
else:
c = contours[-1]
# rect是一个Rotated Rect 旋转的矩形, 矩形的起始坐标(x,y), 矩形的长宽(w, h), 矩形旋转角度
rect = cv2.minAreaRect(c)
# cv2.boxPoints其实就是帮我们把旋转矩形的4个坐标点计算出来了.
box = cv2.boxPoints(rect)
# 注意坐标必须是整数的, 所以需要转化一下
# 四舍五入
box = np.round(box).astype('int64')
# 绘制最小外接矩形
cv2.drawContours(frame, [box], 0, (255, 0, 0), 2)
# 给角点排序
box = order_points(box)
# 圆心
cv2.circle(frame, cpoint(box), 5, (0, 255, 0), -1)
# 绘制轮廓
cv2.drawContours(canny, contours, -1, (255, 0, 0), 2)
f[200:650, 700:1200] = frame
# 显示数据
cv2.imshow('video', f)
# 假如一个视频是30帧, 那么每张图之间要间隔多少毫秒
# 只能是整数
key = cv2.waitKey(1000 // 30)
if key & 0xFF == ord('q'):
break
# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()
cv2.waitKey(1)
-1
激活大能量机关