【问题标题】:Detecting blinks of a horse from side view with opencv使用opencv从侧面检测马的眨眼
【发布时间】:2021-07-18 13:35:21
【问题描述】:

这是一个理论上的问题,而不是询问具体的代码问题。

我已经使用 Haar Cascades 进行了一些面部标志检测,但这次我手上有不同类型的视频。这是马眼的侧视图(相机安装在头部的一侧),所以基本上我看到的是一只巨大的眼睛。我尝试使用 Haar Cascades,但没有用,因为在我的视频中没有检测到人脸。

我想知道在这匹马身上检测眼睛和眨眼的最佳方法是什么?我是否尝试自定义 dlib 面部标记检测器?我没有找到太多关于动物地标的信息。

提前致谢! :)

【问题讨论】:

  • 如果您可以管理它,那么对相机所见内容进行拍照会有所帮助。一只睁眼,一只闭眼。听起来图像主要是眼睛。假设眼睛和眼睑的颜色不同,您可以计算某种颜色的像素数并将突然变化记录为眨眼。
  • 嗨,是的,这是摄像机的直接视图 - ibb.co/4dRsMNw。感谢您的建议
  • 看看深度学习对象分类+定位、检测、分割或关键点/地标检测
  • 如果你有视频可以发布吗?然后我们可以尝试一个解决方案并检查它是否有效。
  • 你好,当然,这是我的视频之一 - dropbox.com/s/hb5g16lk910szur/video.mov?dl=0 :)

标签: python opencv dlib


【解决方案1】:

在第一帧围绕眼睛画了一个边界框后,我使用对象跟踪器继续定位眼睛。

我创建了一个固定的宽度和高度边界框,因为我们可以粗略地假设眼睛相对于相机没有增长或缩小。在为跟踪器绘制边界框时,我们不仅要包括眼睛,否则只要眼睛眨眼就会失去对对象的跟踪。

我在每一帧中寻找有界区域的饱和度是否低于阈值,以检查它们是否闪烁。蓝色框是跟踪器返回的边界框,绿色框是我正在裁剪并检查饱和度的区域。

这是视频过程中饱和度的图表

你可以清楚地看到他们眨眼的地方

这是一个(高度压缩以达到 2mb 限制)结果的 gif 图像

import cv2
import numpy as np
import math

# tuplifies things for opencv
def tup(p):
    return (int(p[0]), int(p[1]));

# returns the center of the box
def getCenter(box):
    x = box[0];
    y = box[1];
    x += box[2] / 2.0;
    y += box[3] / 2.0;
    return [x,y];

# rescales image by percent
def rescale(img, scale):
    h,w = img.shape[:2];
    h = int(h*scale);
    w = int(w*scale);
    return cv2.resize(img, (w,h));

# load video
cap = cv2.VideoCapture("blinking.mov");
scale = 0.5;

# font stuff
font = cv2.FONT_HERSHEY_SIMPLEX;
org = (50, 50);
fontScale = 1;
font_color = (255, 255, 0);
thickness = 2;

# set up tracker
tracker = cv2.TrackerCSRT_create(); # I'm using OpenCV 3.4
backup = cv2.TrackerCSRT_create();

# grab the first frame
_, frame = cap.read();
frame = rescale(frame, scale);

# init tracker
box = cv2.selectROI(frame, False);
tracker.init(frame, box);
backup.init(frame, box);
cv2.destroyAllWindows();

# set center bounds
width = 75;
height = 60;

# save numbers
file_index = 0;

# blink counter
blinks = 0;
blink_thresh = 35;
blink_trigger = True;

# show video
done = False;
while not done:
    # get frame
    ret, frame = cap.read();
    if not ret:
        break;
    frame = rescale(frame, scale);

    # choose a color space
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV);
    h,s,v = cv2.split(hsv);
    channel = s;

    # grab tracking box
    ret, box = tracker.update(frame);
    if ret:
        # get the center
        center = getCenter(box);
        x, y = center;

        # make box on center
        tl = [x - width, y - height];
        br = [x + width, y + height];
        tl = tup(tl);
        br = tup(br);

        # get top left and bottom right
        p1 = [box[0], box[1]];
        p2 = [p1[0] + box[2], p1[1] + box[3]];
        p1 = tup(p1);
        p2 = tup(p2);

        # draw a roi around the image
        cv2.rectangle(frame, p1, p2, (255,0,0), 3);
        cv2.rectangle(frame, tl, br, (0,255,0), 3);
        cv2.circle(frame, tup(center), 6, (0,0,255), -1);

        # get the channel average in the box
        slc = channel[tl[1]:br[1], tl[0]:br[0]];
        ave = np.mean(slc);

        # if it dips below a set value, then trigger a blink
        if ave < blink_thresh:
            if blink_trigger:
                blinks += 1;
                blink_trigger = False;
        else:
            blink_trigger = True;

        # draw blink count
        frame = cv2.putText(frame, "Blinks: " + str(blinks), org, font, fontScale, 
                            font_color, thickness, cv2.LINE_AA);

    # show
    cv2.imshow("Frame", frame);
    key = cv2.waitKey(1);

    # check keypress
    done = key == ord('q');

【讨论】:

    猜你喜欢
    • 2015-12-11
    • 2012-11-01
    • 2019-03-14
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2023-04-02
    • 2020-11-17
    相关资源
    最近更新 更多