如何在检测到的人体轮廓周围放置边界框

时间:2018-06-18 09:47:14

标签: python opencv bounding-box background-subtraction

这是我写的python代码: -

import cv2
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help = "path to the (optional) video file")
args = vars(ap.parse_args())

if not args.get("video", False):
    cap = cv2.VideoCapture(0)
else:
    cap = cv2.VideoCapture(args["video"])
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

如何在检测到的人体轮廓周围放置边界框并提高python代码的效率,以便对从网络摄像头拍摄的实时视频输入执行背景减法。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

使用背景减法绘制轮廓

import cv2
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help = "path to the (optional) video file")
args = vars(ap.parse_args())

if not args.get("video", False):
    cap = cv2.VideoCapture(0)
else:
    cap = cv2.VideoCapture(args["video"])
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)

    gray=cv2.cvtColor(fgmask,cv2.COLOR_BGR2GRAY)
    ret,th1 = cv2.threshold(gray,25,255,cv2.THRESH_BINARY)
    _,contours,hierarchy = cv2.findContours(th1,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 1000 and area < 40000:
            x,y,w,h = cv2.boundingRect(cnt)
            cv2.rectangle(fgmask,(x,y),(x+w,y+h),(255,0,0),2)

    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

使用HSV蒙版和凸壳绘制轮廓
设置hsv掩码的值。

import cv2
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help = "path to the (optional) video file")
args = vars(ap.parse_args())

if not args.get("video", False):
    cap = cv2.VideoCapture(0)
else:
    cap = cv2.VideoCapture(args["video"])
    fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
    ret, frame = cap.read()

    frame = cv2.imread(frame)
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    lower = np.array([50,103,40])
    upper = np.array([255,255, 255])

    mask = cv2.inRange(hsv, lower, upper)
    fg = cv2.bitwise_and(frame, frame, mask=255-mask)

    fg = cv2.cvtColor(fg.copy(),cv2.COLOR_HSV2BGR)
    fg = cv2.cvtColor(fg,cv2.COLOR_BGR2GRAY)

    fg = cv2.threshold(fg, 120,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
    #plt.imshow(fg)
    #plt.show()


    fgclosing = cv2.morphologyEx(fg.copy(), cv2.MORPH_CLOSE, kernel)
    se = np.ones((3,3),np.uint8)
    #fgdilated = cv2.morphologyEx(fgclosing, cv2.MORPH_CLOSE,cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (4,4)))
    fgdilated = cv2.dilate(fgclosing, kernel = se , iterations = 8)

    img = frame.copy()
    ret, threshed_img = cv2.threshold(fgdilated,
                    127, 255, cv2.THRESH_BINARY)
    image, contours, hier = cv2.findContours(threshed_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

    for cnt in contours:
        #print(cv2.contourArea(cnt))
        if cv2.contourArea(cnt) > 44000:
            # get convex hull
            hull = cv2.convexHull(cnt)
            #cv2.drawContours(img, [hull], -1, (0, 0, 255), 1)
            #print(hull)
            (x,y,w,h) = cv2.boundingRect(cnt)
            #cv2.rectangle(img, (x,y), (x+w,y+h), (255, 0, 0), 2)
            contours = hull
            #c1 = max(contours, key=cv2.contourArea)
            hull = cv2.convexHull(cnt)
            c = hull
            #print(c)
            cv2.drawContours(img, [hull], -1, (0, 0, 255), 1)
            # determine the most extreme points along the contour
            extLeft = tuple(c[c[:, :, 0].argmin()][0])
            extRight = tuple(c[c[:, :, 0].argmax()][0])
            extTop = tuple(c[c[:, :, 1].argmin()][0])
            extBot = tuple(c[c[:, :, 1].argmax()][0])

            cv2.drawContours(img, [c], -1, (0, 255, 255), 2)
            cv2.circle(img, extLeft, 8, (0, 0, 255), -1)
            cv2.circle(img, extRight, 8, (0, 255, 0), -1)
            cv2.circle(img, extTop, 8, (255, 0, 0), -1)
            cv2.circle(img, extBot, 8, (255, 255, 0), -1)

            lx = extLeft[1]
            ly = extLeft[0]
            rx = extRight[1]
            ry = extRight[0]
            tx = extTop[1]
            ty = extTop[0]
            bx = extBot[1]
            by = extBot[0]   

            x,y = lx,by
            w,h = abs(rx-lx),abs(ty-by)

            #cv2.rectangle(img, (x,y), (x+w,y+h), (255, 0, 0), 2)
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(img,str(extLeft[0])+','+str(extLeft[1]),(extLeft), font, 2,(0, 0, 255),2,cv2.LINE_AA)
            cv2.putText(img,str(extRight[0])+','+str(extRight[1]),(extRight), font, 2,(0, 255, 0),2,cv2.LINE_AA)
            cv2.putText(img,str(extTop[0])+','+str(extTop[1]),(extTop), font, 2,(255, 0, 0),2,cv2.LINE_AA)
            cv2.putText(img,str(extBot[0])+','+str(extBot[1]),(extBot), font, 2,(255, 255, 0),2,cv2.LINE_AA)

            im = frame[tx:bx,ly:ry,:]
            cx = im.shape[1]//2
            cy = im.shape[0]//2
            cv2.circle(im, (cx,cy), 15, (0, 255, 0))

    plt.imshow(img)
    plt.show()

答案 1 :(得分:0)

您可以使用findContours。

import cv2
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help = "path to the (optional) video file")
args = vars(ap.parse_args())

if not args.get("video", False):
    cap = cv2.VideoCapture(0)
else:
    cap = cv2.VideoCapture(args["video"])
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)

    mask = 255 - fgmask
    _, contours, _ = cv2.findContours(
        mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    fgmask = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR)
    for contour in contours:
        area = cv2.contourArea(contour)

        #only show contours that match area criterea
        if area > 500 and area < 20000:
            rect = cv2.boundingRect(contour)
            x, y, w, h = rect
            cv2.rectangle(fgmask, (x, y), (x+w, y+h), (0, 255, 0), 3)

    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

我已使用视频https://github.com/opencv/opencv/blob/master/samples/data/vtest.avi

进行了测试