赞
踩
简单学习了OpenCV,使用OpenCV框架对视频中的色块进行跟踪以及绘制轨迹
Source
首先,我们使用下面的代码将Source.mp4中的一帧截取下来
- import cv2
- import numpy as np
-
- cap = cv2.VideoCapture('Source.mp4')
- #cap = cv2.VideoCapture('C:/Users/Test.mp4')
-
- #创建属性为WINDOW_NORMAL,名字为'Video'的窗口
- cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
- #设置窗口尺寸为640*480
- cv2.resizeWindow('Video', 640, 480)
-
- while True:
- #每次从cap中读取一帧图像
- ret, frame = cap.read()
-
- #如果读取视频失败则退出循环
- if not ret:
- break
-
- #正常读取显示图像帧
- cv2.imshow('Video', frame)
-
- #按下s保存图片(picture.jpg)并退出
- if cv2.waitKey(1) == ord('s'):
- cv2.imwrite('picture.jpg',frame)
- break
-
- cap.release()
- cv2.destroyAllWindows()
使用以下代码将截取的图片调黑白图片,图片中只有一个白色矩形色块,将其保存并输出HSV值
- # -*- coding:utf-8 -*-
-
- import cv2
- import numpy as np
-
- """
- function:读取一张图片,显示出来,转化为HSV色彩空间,并通过滑块调节HSV阈值,实时显示
- """
- cv2.namedWindow('BGR', cv2.WINDOW_NORMAL)
- cv2.resizeWindow('BGR', 640, 480)
-
- cv2.namedWindow('dst', cv2.WINDOW_NORMAL)
- cv2.resizeWindow('dst', 640, 480)
-
- image = cv2.imread('picture.jpg') # 根据路径读取一张图片,opencv读出来的是BGR模式
- cv2.imshow("BGR", image) # 显示图片
-
- hsv_low = np.array([0, 0, 0])
- hsv_high = np.array([179, 255, 255])
-
- # 下面几个函数,写得有点冗余
- def h_low(value):
- hsv_low[0] = value
-
- def h_high(value):
- hsv_high[0] = value
-
- def s_low(value):
- hsv_low[1] = value
-
- def s_high(value):
- hsv_high[1] = value
-
- def v_low(value):
- hsv_low[2] = value
-
- def v_high(value):
- hsv_high[2] = value
-
- cv2.namedWindow('image',cv2.WINDOW_AUTOSIZE)
-
- #H low:
- # 0:指向整数变量的可选指针,该变量的值反映滑块的初始位置。
- # 179:表示滑块可以达到的最大位置的值为179,最小位置始终为0。
- #h_low:指向每次滑块更改位置时要调用的函数的指针,指针指向h_low元组,有默认值0。
- cv2.createTrackbar('H low', 'image', 0, 179, h_low)
- cv2.createTrackbar('H high', 'image', 0, 179, h_high)
- cv2.createTrackbar('S low', 'image', 0, 255, s_low)
- cv2.createTrackbar('S high', 'image', 0, 255, s_high)
- cv2.createTrackbar('V low', 'image', 0, 255, v_low)
- cv2.createTrackbar('V high', 'image', 0, 255, v_high)
-
- while True:
- dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR转HSV
- dst = cv2.inRange(dst, hsv_low, hsv_high) # 通过HSV的高低阈值,提取图像部分区域
- cv2.imshow('dst', dst)
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
- if cv2.waitKey(1) == ord('s'):
- print(hsv_low,hsv_high)
- cv2.imwrite('HSV_pic.jpg',dst)
- cv2.destroyAllWindows()
利用OpenCV将实时读取视频流,将每一帧的图像转换为hsv类型,标记HSV值为设置的值,使用findContours()函数找出轮廓,通过contourArea()函数,经过判断找出最大面积的那个轮廓,最后使用drawContours()函数画出轮廓。
- import cv2
- import numpy as np
-
- cap = cv2.VideoCapture('Source.mp4')#入口
- cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
- cv2.resizeWindow('Video', 640, 480)#窗口大小
-
- lower_green = np.array([30,205,200]) #hsv值 # lower_green = np.array([30, 220,188])
- upper_green = np.array([40,255,255]) # upper_green = np.array([34, 254,215])
-
- while True:
- ret, frame = cap.read() #每次从cap中读取一帧图像
- if not ret: #如果读取视频失败则退出循环
- break
-
- hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
- cv2.imshow('Video', frame) #正常读取显示图像帧
-
- mask = cv2.inRange(hsv, lower_green, upper_green)
- contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
-
- #找最大面积的那个
- max = 0.0
- max_num = 0
- if len(contours) > 1: # 找到面积最大的轮廓
- for i in range(len(contours)):
- c = cv2.contourArea(contours[i])
- if c > max:
- max = c
- max_num = i
-
- M = cv2.moments(contours[max_num])#中点
- cx = int(M['m10']/M['m00'])#这两行是计算中心点坐标
- cy = int(M['m01']/M['m00'])
- print((cx, cy))
- frame = cv2.circle(frame, (cx, cy), 3, (0, 0, 255), -1)
- result=cv2.drawContours(frame, contours[max_num], -1, (0,0,255), 3)#最终图像
-
- cv2.imshow('result',result)
- if cv2.waitKey(1) == ord('q'):
- cv2.imwrite('picture.jpg',frame)
- break
-
- #释放
- cap.release()
- cv2.destroyAllWindows()
mid_demo
首先获取视频的第一帧,找出轮廓的中点并保存在pot列表中,然后读取视频,依次计算并保存,使用line()函数在视频上层画线,最后使用add()函数将画的轨迹展示在原视频上。
- import cv2
- import numpy as np
-
-
- cap = cv2.VideoCapture('hwk.mp4')
- cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
- cv2.resizeWindow('Video', 640, 480)
- #hsv值
- lower_green = np.array([32,205,199]) # lower_green = np.array([30, 220,188])
- upper_green = np.array([39,255,255]) # upper_green = np.array([34, 254,215])
-
- #这里可以使用moments函数计算中点并保存
- pot = [(121,123)]#保留点的位置
-
- ret_old, frame_old = cap.read() #每次从cap中读取第一帧图像
- hsv_old = cv2.cvtColor(frame_old, cv2.COLOR_BGR2HSV)
-
- mask_L = np.zeros_like(frame_old)
-
- while True:
- ret_new, frame_new = cap.read() #每次从cap中读取一帧图像
- if not ret_old: #如果读取视频失败则退出循环
- break
-
- hsv_new = cv2.cvtColor(frame_new, cv2.COLOR_BGR2HSV)
-
- cv2.imshow('Video', frame_new) #正常读取显示图像帧
-
- mask = cv2.inRange(hsv_new, lower_green, upper_green)
- contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
-
- #找最大面积的那个
- max = 0.0
- max_num = 0
- if len(contours) > 1: # 找到面积最大的轮廓
- for i in range(len(contours)):
- c = cv2.contourArea(contours[i])
- if c > max:
- max = c
- max_num = i
- #c = max(contours, key=cv2.contourArea)
-
- M = cv2.moments(contours[max_num])#中点
- cx = int(M['m10']/M['m00'])#这两行是计算中心点坐标
- cy = int(M['m01']/M['m00'])
- pot.append((cx,cy))
- print((cx, cy))
-
- a = 121
- b = 123
- for x, y in (pot):
- mask_L = cv2.line(mask_L, (a,b),(x,y), (0, 0, 255), 2)#画直线
- pot_old = cv2.circle(frame_old,(a,b),3,(0, 0, 255), -1)#画点
- a = x
- b = y
-
- #pot_old = cv2.circle(frame_old, (cx, cy), 3, (0, 0, 255), -1)
-
- result_old = cv2.drawContours(frame_new, contours[max_num], -1, (0,0,255), 3)
- #print(contours[max_num])
-
- # 更新上一帧的图像和追踪点
- hsv_old = hsv_new.copy()
- #frame_old = frame_new.copy()
- img = cv2.add(mask_L, frame_new)
-
- cv2.imshow('frame',img)
-
- if cv2.waitKey(1) == ord('q'):
- cv2.imwrite('picture.jpg',frame_old)
- break
-
- #释放
- cap.release()
- cv2.destroyAllWindows()
final_demo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。