使用Python,OpenCV转换颜色空间,追踪对象的轨迹
这篇博客可以看作是之前俩篇博客的融合,将介绍如何使用Python,OpenCV转换颜色空间,并利用HSV追踪对象,并绘制其轨迹;
- 计算HSV空间的上限与下限值;
- BGR转HSV空间;
- 追踪对像,并绘制轨迹;
1. 效果图
绿色的薄荷膏药瓶成功被检测到~
药瓶底部纯绿色也被检测到了,如图~
追踪绿色瓶并绘制最近的轨迹线效果图如下:
2. 源码
# 将图像从一种颜色空间转换为另一种颜色空间,例如 BGR、RGB、Gray、HSV 等。
# 创建一个应用程序来提取视频中的彩色对象
# OpenCV 中有超过 150 种颜色空间转换方法可用,本文只介绍最经典的2中:BGR、HSV及互转
# USAGE
# python change_colorspace_Object_Tracking.py
from collections import deque
import cv2
# 遍历查看所有颜色空间
import imutils
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)
print(len(flags))
# 对于 HSV,色调范围为 [0,179],饱和度范围为 [0,255],值范围为 [0,255]。不同的软件使用不同的尺度。因此,如果您将 OpenCV 值与它们进行比较,则需要对这些范围进行归一化。
# 对象跟踪,可以使用HSV来提取彩色对象。这是最简单的对象追踪,找到物体的质心,就可以绘制轨迹来追踪物体;
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
pts = deque(maxlen=64)
while (1):
# 获取每一帧
_, frame = cap.read()
frame = imutils.resize(frame,width=400)
if frame is None:
break
# 转换BGR为HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 定义绿色的HSV空间值
lower_blue = np.array([29, 86, 6])
upper_blue = np.array([64, 255, 255])
# 阈值化图像,只获取绿色
mask = cv2.inRange(hsv, lower_blue, upper_blue)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
# 寻找mask中的轮廓,并初始化球当前的中心(x,y)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
# 发现至少一个轮廓继续处理
if len(cnts) > 0:
# 寻找面积最大的轮廓,并计算最小外接圆,质心
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
# 当圆半径大于5时继续处理
if radius > 5:
# 在帧上绘制绿色球的外接圆及中心
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
# 更新中心点队列
pts.appendleft(center)
# 遍历追踪到的中心点坐标
for i in range(1, len(pts)):
# 如果为None,忽略
if pts[i - 1] is None or pts[i] is None:
continue
# 否则绘制线连接
thickness = int(np.sqrt(64 / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
# 展示帧到屏幕
cv2.imshow("Frame", frame)
# 对图像执行按位与操作
# res = cv2.bitwise_and(frame, frame, mask=mask)
#
# cv2.imshow('frame', frame)
# cv2.imshow('mask', mask)
# cv2.imshow('res', res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
# 如何找到HSV空间值呢?
# 比如要寻找绿色,可以找到BGR(0,255,0) ,转换为HSV,然后取[ H-10,S,V]为下限 -- [ H+10,S,V]为上限;
green = np.uint8([[[0, 255, 0]]])
hsv_green = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
print(hsv_green)
# [[[60 255 255]]]