【问题标题】:Detect person wearing red in a video检测视频中穿红衣服的人
【发布时间】:2021-01-19 11:24:05
【问题描述】:

我正在与很多人一起制作一个视频,其中很少有人穿着红色 T 恤。我使用人员检测和跟踪模型检测和跟踪了所有人员。如何区分穿红色的人和其他人。

我正在阅读 OpenCV 格式的帧。如果我知道坐标,假设 x,y 是颜色为红色的身体坐标。如何从 OpenCV 格式的坐标中获取颜色信息并检查是否在红色范围内?

我只需要突出显示其他人穿着红色的人的边界框。

谁能帮我找出解决方案。 谢谢!

【问题讨论】:

    标签: python image opencv image-processing pixel


    【解决方案1】:

    将颜色空间更改为 HSV 并找到颜色的 Hue 值范围的更好方法。

    • 拍摄视频的每一帧
    • 先检测人类,然后提取人类区域 (source)
    • 从 BGR 转换为 HSV 颜色空间
    • 为一系列红色设置 HSV 图像阈值

    识别视频中的红色 T 恤男士

    我们可以使用以下代码识别图像中的人体区域

    import time
    
    import cv2
    import imutils
    import numpy as np
    from imutils.video import FPS
    # import the necessary packages
    from imutils.video import VideoStream
    
    
    def get_centered_contours(mask):
      # find contours
      cntrs = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
      sorted_contours = sorted(cntrs, key=cv2.contourArea, reverse=True)
      filterd_contours = []
      if sorted_contours != []:
        for k in range(len(sorted_contours)):
          if cv2.contourArea(sorted_contours[k]) < 1000.0:
            filterd_contours = sorted_contours[0:k]
            return filterd_contours
      return filterd_contours
    
    
    def check_red_colour_person(roi):
      hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
      # define range of blue color in HSV
      lower_red = np.array([0, 50, 50])
      upper_red = np.array([10, 255, 255])
      # Threshold the HSV image to get only blue colors
      mask = cv2.inRange(hsv, lower_red, upper_red)
      cnts = get_centered_contours(mask)
      if cnts != []:
        return True
      else:
        return False
    
    
    # construct the argument parse and parse the arguments
    prototxt = 'MobileNetSSD_deploy.prototxt.txt'
    model = 'MobileNetSSD_deploy.caffemodel'
    confidence_level = 0.8
    
    # initialize the list of class labels MobileNet SSD was trained to
    # detect, then generate a set of bounding box colors for each class
    CLASSES = ["person"]
    COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))
    
    # load our serialized model from disk
    print("[INFO] loading model...")
    net = cv2.dnn.readNetFromCaffe(prototxt, model)
    
    # initialize the video stream, allow the cammera sensor to warmup,
    # and initialize the FPS counter
    print("[INFO] starting video stream...")
    vs = VideoStream(src=0).start()
    time.sleep(2.0)
    fps = FPS().start()
    
    # loop over the frames from the video stream
    while True:
      try:
        # grab the frame from the threaded video stream and resize it
        # to have a maximum width of 400 pixels
        frame = vs.read()
        frame = imutils.resize(frame, width=400)
    
        # grab the frame dimensions and convert it to a blob
        (h, w) = frame.shape[:2]
        blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),
                                     0.007843, (300, 300), 127.5)
    
        # pass the blob through the network and obtain the detections and
        # predictions
        net.setInput(blob)
        detections = net.forward()
    
        # loop over the detections
        for i in np.arange(0, detections.shape[2]):
          # extract the confidence (i.e., probability) associated with
          # the prediction
          confidence = detections[0, 0, i, 2]
    
          # filter out weak detections by ensuring the `confidence` is
          # greater than the minimum confidence
          if confidence > confidence_level:
            # extract the index of the class label from the
            # `detections`, then compute the (x, y)-coordinates of
            # the bounding box for the object
            idx = int(detections[0, 0, i, 1])
            box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
            (startX, startY, endX, endY) = box.astype("int")
    
            roi = frame[startY:endY, startX:endX]
            # cv2.imwrite('roi_{}_{}_{}_{}.png'.format(startX,startY,endX,endY),roi)
            if check_red_colour_person(roi):
              label = "{}: {:.2f}%".format(' Red T-shirt person',
                                           confidence * 100)
              cv2.imwrite(
                  'Red-T-shirt_guy_{}_{}_{}_{}.png'.format(startX, startY, endX,
                                                           endY), roi)
    
              cv2.rectangle(frame, (startX, startY), (endX, endY),
                            (0, 0, 255), 2)
            else:
              cv2.rectangle(frame, (startX, startY), (endX, endY),
                            (255, 0, 0), 2)
          y = startY - 15 if startY - 15 > 15 else startY + 15
          cv2.putText(frame, label, (startX, y),
                      cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)
    
          cv2.imshow("Frame", frame)
          key = cv2.waitKey(1) & 0xFF
    
          # if the `q` key was pressed, break from the loop
          if key == ord("q"):
            break
    
          # update the FPS counter
          fps.update()
      except Exception as e:
        print("Exception is occured")
        continue
    # stop the timer and display FPS information
    fps.stop()
    print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
    
    # do a bit of cleanup
    cv2.destroyAllWindows()
    vs.stop()
    

    【讨论】:

    • 当我们有红色短裤或牛仔裤时,此解决方案也会失败
    • 我给出了初步的方法
    • 这里的下边界值检测肤色也为红色,所以我将阈值更改为 [170,50,50] 效果更好
    • 酷,你可以得到边界坐标并使用 cv2.Rectangle 来绘制矩形形状
    • 谢谢@rcvaram。我如何解释“res值”来用真假来表示存在或不存在
    【解决方案2】:

    您可以设置颜色边界

    boundaries = [
    ([17, 15, 100], [50, 56, 200])]
    

    所以这里是元组 ([17, 15, 100], [50, 56, 200])。

    在这里,我们是说图像中所有具有 R >= 100、B >= 15 和 G >= 17 以及 R

    你可以像下面这样实现:

    for (lower, upper) in boundaries:
        lower = np.array(lower, dtype = "uint8")
        upper = np.array(upper, dtype = "uint8")
        # find the colors within the specified boundaries and apply
        # the mask
        mask = cv2.inRange(image, lower, upper)
        output = cv2.bitwise_and(image, image, mask = mask)
        # show the images
        cv2.imshow("images", np.hstack([image, output]))
    

    【讨论】:

    • 这将检测所有红色的地方。在这里,我们需要检测红色的人类
    • 只能通过检测到的人的图像帧
    • Yes Dhruv 如果是这样的话,我很感激
    • 嗨,Dhruv 我知道这可以检测框架中的红色区域,但是,与其在单独的窗口中以红色显示人,我如何才能获得可以指示存在的 True 或 False 值或边界框中没有红色。
    猜你喜欢
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2013-02-07
    • 2014-04-12
    • 2019-04-26
    • 1970-01-01
    相关资源
    最近更新 更多