使用Python,OpenCV转换颜色空间,追踪对象的轨迹

使用Python,OpenCV转换颜色空间,追踪对象的轨迹

这篇博客可以看作是之前俩篇博客的融合,将介绍如何使用Python,OpenCV转换颜色空间,并利用HSV追踪对象,并绘制其轨迹;

  1. 计算HSV空间的上限与下限值;
  2. BGR转HSV空间;
  3. 追踪对像,并绘制轨迹;

1. 效果图

绿色的薄荷膏药瓶成功被检测到~
使用Python,OpenCV转换颜色空间,追踪对象的轨迹药瓶底部纯绿色也被检测到了,如图~
使用Python,OpenCV转换颜色空间,追踪对象的轨迹追踪绿色瓶并绘制最近的轨迹线效果图如下:
使用Python,OpenCV转换颜色空间,追踪对象的轨迹

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]]]

参考

上一篇:计算图像FID


下一篇:2万字20个项目实例,2021大厂面试合集