0

So this is what I have now: a picture As you can see, the neural style transfer thing is only going over the area the detection box is detecting. I am trying to put the transformed cool picture (which will always be less than 1200 x 900 because the detection box is 1200 x 900) in a black picture with dimensions 1200 x 900 so that I can save the video file.

My box is measured with: startX, endX, startY, and endY. The way I am trying to put the cool picture over the background right now is: black_background[startY:endY, startX:endX] = output, where output also has the size (endY - startY, endX - startX).

My way is not working, any insights? And also, for some reason, when I do "*black_background[startY:endY, startX:endX] = output", there is often a few pixel off broadcasting issue, like can't add (859, 100, 3) with (860, 100, 3). Is there a non-buggy solution to the black background issue? I feel like manually doing *black_background[startY:endY, startX:endX] = output is weird.

Here's my full code, I marked the if loop that actually matters with -----, thank you!

from __future__ import print_function
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
from imutils import paths
import itertools

# We need to input model prototxt

ap = argparse.ArgumentParser()
ap.add_argument("-p", "--prototxt", required=True,
    help="path to Caffe 'deploy' prototxt file")
ap.add_argument("-m", "--model", required=True,
    help="path to Caffe pre-trained model")
ap.add_argument("-c", "--confidence", type=float, default=0.2,
    help="minimum probability to filter weak detections")
ap.add_argument("-nm", "--neuralmodels", required=True,
    help="path to directory containing neural style transfer models")
args = vars(ap.parse_args())

# we should identify the class first, and then transfer that block
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
    "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
    "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
    "sofa", "train", "tvmonitor"]
COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))

# load our serialized model from disk
print("[INFO] loading model...")
DetectionNet = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])


# grab the paths to all neural style transfer models in our 'models'
# directory, provided all models end with the '.t7' file extension
modelPaths = paths.list_files(args["neuralmodels"], validExts=(".t7",))
modelPaths = sorted(list(modelPaths))

# generate unique IDs for each of the model paths, then combine the
# two lists together
models = list(zip(range(0, len(modelPaths)), (modelPaths)))

# use the cycle function of itertools that can loop over all model
# paths, and then when the end is reached, restart again
modelIter = itertools.cycle(models)
(modelID, modelPath) = next(modelIter)

NTSnet = cv2.dnn.readNetFromTorch(modelPath)


# initialize the video stream, allow the cammera sensor to warmup,
# and initialize the FPS counter
print("[INFO] starting video stream...")
vs = VideoStream(src=1).start()

fps = FPS().start()
fourcc = cv2.VideoWriter_fourcc(*'XVID')
output_video = cv2.VideoWriter('output.avi', fourcc, 20.0, (1200, 900))


while True:
    # 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=1200, height=900)

    # 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
    DetectionNet.setInput(blob)
    detections = DetectionNet.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 > args["confidence"]:
            # 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])

            if(CLASSES[idx] == "person" and confidence > .90):
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype("int")

            # draw the prediction on the frame
                label = "{}: {:.2f}%".format("PERSON",
                confidence * 100)
                cv2.rectangle(frame, (startX, startY), (endX, endY),
                    COLORS[idx], 2)
                y = startY - 15 if startY - 15 > 15 else startY + 15
                cv2.putText(frame, label, (startX, y),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)


            # print box area in background
                newimage = frame[startY:endY, startX:endX]
                (h, w) = newimage.shape[:2]
                #print(h,w)
                #print(startX, endX, startY, endY)
                noise_picture = cv2.imread('white_noise.jpg')
                black_background = cv2.imread('black.png')
-------------------------------------------------------------------
                *if(h > 0 and w > 0):



                    # to_be_transformed is the detection box area

                    # resize that area for MobileNetSSD
                    #to_be_transformed = imutils.resize(to_be_transformed, height=450)
                    (height_orig, width_orig) = noise_picture.shape[:2]
                    noise_picture[startY:endY, startX:endX] = newimage
                    noise_picture = imutils.resize(noise_picture, height=450)
                    # run it through the network, output is the image
                    (h, w) = noise_picture.shape[:2]
                    # print(h, w)
                    blob2 = cv2.dnn.blobFromImage(noise_picture, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False)
                    NTSnet.setInput(blob2)
                    output = NTSnet.forward()
                    output = output.reshape((3, output.shape[2], output.shape[3]))
                    output[0] += 103.939
                    output[1] += 116.779
                    output[2] += 123.680
                    output /= 255.0
                    output = output.transpose(1, 2, 0)
                    # set the 600 x 450 back to the original size
                    black_background = imutils.resize(black_background, width=1200, height = 900)
                    output = imutils.resize(output, width=1200)
                    #black_background[startY:endY, startX:endX] = output[startY:endY, startX:endX]


                    output = output[startY:endY, startX:endX]
                    (h2, w2) = output.shape[:2]
                    if(h2>0 and w2>0 ):
                        cv2.imshow('hmm', output)

                        black_background[startY:endY, startX:endX] = output
                        cv2.imshow("uh", black_background)
                    #output_video.write(black_background)
                    #output_video.write(background)*
---------------------------------------------------------------


    # show the output frame, which is the whole thing
    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()

# 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()
Acy
  • 589
  • 2
  • 9
  • 25

1 Answers1

0

Oh man, second time I made this mistake. You have to do * 255 when you are adding your output picture to your background. This is really weird, it seems like imread works if you only put numbers in [0, 1], but once you have a value that goes over 1, it treats the range as [0, 255], don't take my words on it though.

Acy
  • 589
  • 2
  • 9
  • 25