johannestang / yolo_service

Dockerized YOLO object detection service
19 stars 9 forks source link

combine with fastapi celery and rabbitmq + video detection #5

Open haviduck opened 4 years ago

haviduck commented 4 years ago

heya! I got your repo working with videos, its amazing thanks for sharing your code. I found a different repo that included queueing, fastapi and workers. trying to combine your dockerized darknet with it as .so needs to be compiled, but im not that good with docker. wanna trade pokemon and see if we can do some good?

optimally i want to do a generator so the json stream can be grabbed continously, but this is atleast a start!

`def convertBack(x, y, w, h): xmin = int(round(x - (w / 2))) xmax = int(round(x + (w / 2))) ymin = int(round(y - (h / 2))) ymax = int(round(y + (h / 2))) return xmin, ymin, xmax, ymax

def cvDrawBoxes(detections, img): res="" for detection in detections: x, y, w, h = detection[2][0],\ detection[2][1],\ detection[2][2],\ detection[2][3] xmin, ymin, xmax, ymax = convertBack( float(x), float(y), float(w), float(h)) pt1 = (xmin, ymin) pt2 = (xmax, ymax)

    #res+=detection[0]
    return detection[0]

netMain = None metaMain = None altNames = None

def YOLO(): global metaMain, netMain, altNames, curframe, hue, saturation, brightness, listcoords configPath = "./" weightPath = "./" metaPath = "./" if not os.path.exists(configPath): raise ValueError("Invalid config path " + os.path.abspath(configPath) + "") if not os.path.exists(weightPath): raise ValueError("Invalid weight path " + os.path.abspath(weightPath) + "") if not os.path.exists(metaPath): raise ValueError("Invalid data file path " + os.path.abspath(metaPath) + "") if netMain is None: netMain = darknet.load_net_custom(configPath.encode( "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 if metaMain is None: metaMain = darknet.load_meta(metaPath.encode("ascii")) if altNames is None: try: with open(metaPath) as metaFH: metaContents = metaFH.read() import re match = re.search("names = (.*)$", metaContents, re.IGNORECASE | re.MULTILINE) if match: result = match.group(1) else: result = None try: if os.path.exists(result): with open(result) as namesFH: namesList = namesFH.read().strip().split("\n") altNames = [x.strip() for x in namesList] except TypeError: pass except Exception: pass

file_to_upload = connexion.request.files['image_file']
fd, filename = tempfile.mkstemp()
file_to_upload.save(filename)
#cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture(filename)
cap.set(3, 1280)
cap.set(4, 720)
darknet_image = darknet.make_image(darknet.network_width(netMain),
                                darknet.network_height(netMain),3)
res = list()
while cap.isOpened():
    ret, frame_read = cap.read()
    if not ret:
        return json.dumps(res)
    start = time.time()
    frame_rgb = cv2.cvtColor(frame_read, cv2.COLOR_BGR2RGB)
    frame_resized = cv2.resize(frame_rgb,
                               (darknet.network_width(netMain),
                                darknet.network_height(netMain)),
                               interpolation=cv2.INTER_LINEAR)
    darknet.copy_image_from_bytes(darknet_image, frame_resized.tobytes())
    detections = darknet.detect_image(network, class_names, darknet_image, thresh=0.3, nms=.35)
    image = cvDrawBoxes(detections, frame_resized)
    res.append(image)
    cv2.waitKey(1)
return json.dumps(res)`

`/yolo: post: operationId: app.YOLO summary: Perform object detection on uploaded video. consumes:

heres what i followed: https://github.com/GregaVrbancic/fastapi-celery

johannestang commented 4 years ago

Sounds interesting :) Did you make any progress? I'm not quite sure what you're trying to do. Do you want to upload a video file or have the API process the video frame by frame (as individual images)?

haviduck commented 4 years ago

yes! i have it working :) only draw back is that docker stack deploy doesnt support gpus yet. but docker compose with some tweaks works Great. i have it working both via your repo and tiangolos full postgres stack. it is lacking good api work with file upload etc, but that is trivial. ill be glad to share.

its doing frame by frame. i have 1 function for json and 1 for mjpeg

johannestang commented 4 years ago

Good to hear. I unfortunately don't have time to try to implement something like that myself currently, so if you plan to make what you've done publicly available then I'd love to have a look at how you've done it :)

haviduck commented 4 years ago

Good to hear. I unfortunately don't have time to try to implement something like that myself currently, so if you plan to make what you've done publicly available then I'd love to have a look at how you've done it :)

absolutely, Will ping once its published