当前位置:   article > 正文

基于OpenCV对视频中色块进行追踪_opencv色块追踪

opencv色块追踪

简单学习了OpenCV,使用OpenCV框架对视频中的色块进行跟踪以及绘制轨迹

原视频

Source

图片

首先,我们使用下面的代码将Source.mp4中的一帧截取下来

  1. import cv2
  2. import numpy as np
  3. cap = cv2.VideoCapture('Source.mp4')
  4. #cap = cv2.VideoCapture('C:/Users/Test.mp4')
  5. #创建属性为WINDOW_NORMAL,名字为'Video'的窗口
  6. cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
  7. #设置窗口尺寸为640*480
  8. cv2.resizeWindow('Video', 640, 480)
  9. while True:
  10. #每次从cap中读取一帧图像
  11. ret, frame = cap.read()
  12. #如果读取视频失败则退出循环
  13. if not ret:
  14. break
  15. #正常读取显示图像帧
  16. cv2.imshow('Video', frame)
  17. #按下s保存图片(picture.jpg)并退出
  18. if cv2.waitKey(1) == ord('s'):
  19. cv2.imwrite('picture.jpg',frame)
  20. break
  21. cap.release()
  22. cv2.destroyAllWindows()

 HSV图片

使用以下代码将截取的图片调黑白图片,图片中只有一个白色矩形色块,将其保存并输出HSV值

  1. # -*- coding:utf-8 -*-
  2. import cv2
  3. import numpy as np
  4. """
  5. function:读取一张图片,显示出来,转化为HSV色彩空间,并通过滑块调节HSV阈值,实时显示
  6. """
  7. cv2.namedWindow('BGR', cv2.WINDOW_NORMAL)
  8. cv2.resizeWindow('BGR', 640, 480)
  9. cv2.namedWindow('dst', cv2.WINDOW_NORMAL)
  10. cv2.resizeWindow('dst', 640, 480)
  11. image = cv2.imread('picture.jpg') # 根据路径读取一张图片,opencv读出来的是BGR模式
  12. cv2.imshow("BGR", image) # 显示图片
  13. hsv_low = np.array([0, 0, 0])
  14. hsv_high = np.array([179, 255, 255])
  15. # 下面几个函数,写得有点冗余
  16. def h_low(value):
  17. hsv_low[0] = value
  18. def h_high(value):
  19. hsv_high[0] = value
  20. def s_low(value):
  21. hsv_low[1] = value
  22. def s_high(value):
  23. hsv_high[1] = value
  24. def v_low(value):
  25. hsv_low[2] = value
  26. def v_high(value):
  27. hsv_high[2] = value
  28. cv2.namedWindow('image',cv2.WINDOW_AUTOSIZE)
  29. #H low:
  30. # 0:指向整数变量的可选指针,该变量的值反映滑块的初始位置。
  31. # 179:表示滑块可以达到的最大位置的值为179,最小位置始终为0
  32. #h_low:指向每次滑块更改位置时要调用的函数的指针,指针指向h_low元组,有默认值0
  33. cv2.createTrackbar('H low', 'image', 0, 179, h_low)
  34. cv2.createTrackbar('H high', 'image', 0, 179, h_high)
  35. cv2.createTrackbar('S low', 'image', 0, 255, s_low)
  36. cv2.createTrackbar('S high', 'image', 0, 255, s_high)
  37. cv2.createTrackbar('V low', 'image', 0, 255, v_low)
  38. cv2.createTrackbar('V high', 'image', 0, 255, v_high)
  39. while True:
  40. dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR转HSV
  41. dst = cv2.inRange(dst, hsv_low, hsv_high) # 通过HSV的高低阈值,提取图像部分区域
  42. cv2.imshow('dst', dst)
  43. if cv2.waitKey(1) & 0xFF == ord('q'):
  44. break
  45. if cv2.waitKey(1) == ord('s'):
  46. print(hsv_low,hsv_high)
  47. cv2.imwrite('HSV_pic.jpg',dst)
  48. cv2.destroyAllWindows()

 视频

利用OpenCV将实时读取视频流,将每一帧的图像转换为hsv类型,标记HSV值为设置的值,使用findContours()函数找出轮廓,通过contourArea()函数,经过判断找出最大面积的那个轮廓,最后使用drawContours()函数画出轮廓。

  1. import cv2
  2. import numpy as np
  3. cap = cv2.VideoCapture('Source.mp4')#入口
  4. cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
  5. cv2.resizeWindow('Video', 640, 480)#窗口大小
  6. lower_green = np.array([30,205,200]) #hsv值 # lower_green = np.array([30, 220,188])
  7. upper_green = np.array([40,255,255]) # upper_green = np.array([34, 254,215])
  8. while True:
  9. ret, frame = cap.read() #每次从cap中读取一帧图像
  10. if not ret: #如果读取视频失败则退出循环
  11. break
  12. hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  13. cv2.imshow('Video', frame) #正常读取显示图像帧
  14. mask = cv2.inRange(hsv, lower_green, upper_green)
  15. contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  16. #找最大面积的那个
  17. max = 0.0
  18. max_num = 0
  19. if len(contours) > 1: # 找到面积最大的轮廓
  20. for i in range(len(contours)):
  21. c = cv2.contourArea(contours[i])
  22. if c > max:
  23. max = c
  24. max_num = i
  25. M = cv2.moments(contours[max_num])#中点
  26. cx = int(M['m10']/M['m00'])#这两行是计算中心点坐标
  27. cy = int(M['m01']/M['m00'])
  28. print((cx, cy))
  29. frame = cv2.circle(frame, (cx, cy), 3, (0, 0, 255), -1)
  30. result=cv2.drawContours(frame, contours[max_num], -1, (0,0,255), 3)#最终图像
  31. cv2.imshow('result',result)
  32. if cv2.waitKey(1) == ord('q'):
  33. cv2.imwrite('picture.jpg',frame)
  34. break
  35. #释放
  36. cap.release()
  37. cv2.destroyAllWindows()

mid_demo

 

绘制轨迹

首先获取视频的第一帧,找出轮廓的中点并保存在pot列表中,然后读取视频,依次计算并保存,使用line()函数在视频上层画线,最后使用add()函数将画的轨迹展示在原视频上。

  1. import cv2
  2. import numpy as np
  3. cap = cv2.VideoCapture('hwk.mp4')
  4. cv2.namedWindow('Video', cv2.WINDOW_NORMAL)
  5. cv2.resizeWindow('Video', 640, 480)
  6. #hsv值
  7. lower_green = np.array([32,205,199]) # lower_green = np.array([30, 220,188])
  8. upper_green = np.array([39,255,255]) # upper_green = np.array([34, 254,215])
  9. #这里可以使用moments函数计算中点并保存
  10. pot = [(121,123)]#保留点的位置
  11. ret_old, frame_old = cap.read() #每次从cap中读取第一帧图像
  12. hsv_old = cv2.cvtColor(frame_old, cv2.COLOR_BGR2HSV)
  13. mask_L = np.zeros_like(frame_old)
  14. while True:
  15. ret_new, frame_new = cap.read() #每次从cap中读取一帧图像
  16. if not ret_old: #如果读取视频失败则退出循环
  17. break
  18. hsv_new = cv2.cvtColor(frame_new, cv2.COLOR_BGR2HSV)
  19. cv2.imshow('Video', frame_new) #正常读取显示图像帧
  20. mask = cv2.inRange(hsv_new, lower_green, upper_green)
  21. contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  22. #找最大面积的那个
  23. max = 0.0
  24. max_num = 0
  25. if len(contours) > 1: # 找到面积最大的轮廓
  26. for i in range(len(contours)):
  27. c = cv2.contourArea(contours[i])
  28. if c > max:
  29. max = c
  30. max_num = i
  31. #c = max(contours, key=cv2.contourArea)
  32. M = cv2.moments(contours[max_num])#中点
  33. cx = int(M['m10']/M['m00'])#这两行是计算中心点坐标
  34. cy = int(M['m01']/M['m00'])
  35. pot.append((cx,cy))
  36. print((cx, cy))
  37. a = 121
  38. b = 123
  39. for x, y in (pot):
  40. mask_L = cv2.line(mask_L, (a,b),(x,y), (0, 0, 255), 2)#画直线
  41. pot_old = cv2.circle(frame_old,(a,b),3,(0, 0, 255), -1)#画点
  42. a = x
  43. b = y
  44. #pot_old = cv2.circle(frame_old, (cx, cy), 3, (0, 0, 255), -1)
  45. result_old = cv2.drawContours(frame_new, contours[max_num], -1, (0,0,255), 3)
  46. #print(contours[max_num])
  47. # 更新上一帧的图像和追踪点
  48. hsv_old = hsv_new.copy()
  49. #frame_old = frame_new.copy()
  50. img = cv2.add(mask_L, frame_new)
  51. cv2.imshow('frame',img)
  52. if cv2.waitKey(1) == ord('q'):
  53. cv2.imwrite('picture.jpg',frame_old)
  54. break
  55. #释放
  56. cap.release()
  57. cv2.destroyAllWindows()

final_demo

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/566845
推荐阅读
相关标签
  

闽ICP备14008679号