#code from https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py 
#try https://www.pyimagesearch.com/2018/08/27/neural-style-transfer-with-opencv/
import cv2 as cv
import numpy as np
import argparse
import time
import os

import faulthandler

faulthandler.enable()
MODEL_BASE_PATH = os.path.join('models','instance_norm')
MAX_FRAMES = 15#60
parser = argparse.ArgumentParser(
        description='This script is used to run style transfer models from '
                    'https://github.com/jcjohnson/fast-neural-style using OpenCV')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
parser.add_argument('--model', default='starry_night.t7', help='Path to .t7 model')
parser.add_argument('--width', default=-1, type=int, help='Resize input to specific width.')
parser.add_argument('--height', default=-1, type=int, help='Resize input to specific height.')
parser.add_argument('--median_filter', default=0, type=int, help='Kernel size of postprocessing blurring.')
args = parser.parse_args()

net = cv.dnn.readNetFromTorch(os.path.join(MODEL_BASE_PATH, args.model))

if args.input:
    cap = cv.VideoCapture(args.input)
else:
    cap = cv.VideoCapture(0)

cv.namedWindow('Styled image', cv.WINDOW_NORMAL)
out_vid = []
size = (720, 1280)
frame_count = 0
while cv.waitKey(1) < 0:
    hasFrame, frame = cap.read()
    if not hasFrame:
        cv.waitKey(0)
        break
    frame_count += 1 
    inWidth = args.width if args.width != -1 else frame.shape[1]/3
    inHeight = args.height if args.height != -1 else frame.shape[0]/3
    
    #cv.imshow('BaseImage', frame)
    #inp = cv.dnn.blobFromImage(frame, 1.0, (int(inWidth), int(inHeight)), (103.939, 116.779, 123.68), swapRB=False, crop=False)
    inp = cv.dnn.blobFromImage(frame, 1.0, size, (103.939, 116.779, 123.68), swapRB=False, crop=False)
    #print(inp)
    net.setInput(inp)
    out = net.forward()
   

    out = out.reshape(3, out.shape[2], out.shape[3])
    out[0] += 103.939
    out[1] += 116.779
    out[2] += 123.68
    out /= 255
    out = out.transpose(1, 2, 0)

    if args.median_filter:
        out = cv.blur(out, (10,10))   
    cv.imshow('Styled image', out)
    out_vid.append(out)
    if(frame_count == MAX_FRAMES):
        break

fourcc = cv.VideoWriter_fourcc(*'MP4V')
#final_out = cv.VideoWriter('out.mp4', fourcc = fourcc, fps = 1, frameSize=(1280, 720,3))
for i in range(len(out_vid)):
    print(out_vid[i].shape)
    #final_out.write(out_vid[i])
    cv.imwrite(f'output/img{i}.jpg', out_vid[i])
#final_out.release()

    
    

      
#code from https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py 
#try https://www.pyimagesearch.com/2018/08/27/neural-style-transfer-with-opencv/
import cv2 as cv
import numpy as np
import argparse
import time
import os

import faulthandler

faulthandler.enable()
MODEL_BASE_PATH = os.path.join('models','instance_norm')
MAX_FRAMES = 15#60
parser = argparse.ArgumentParser(
        description='This script is used to run style transfer models from '
                    'https://github.com/jcjohnson/fast-neural-style using OpenCV')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
parser.add_argument('--model', default='starry_night.t7', help='Path to .t7 model')
parser.add_argument('--width', default=-1, type=int, help='Resize input to specific width.')
parser.add_argument('--height', default=-1, type=int, help='Resize input to specific height.')
parser.add_argument('--median_filter', default=0, type=int, help='Kernel size of postprocessing blurring.')
args = parser.parse_args()

net = cv.dnn.readNetFromTorch(os.path.join(MODEL_BASE_PATH, args.model))

if args.input:
    cap = cv.VideoCapture(args.input)
else:
    cap = cv.VideoCapture(0)

cv.namedWindow('Styled image', cv.WINDOW_NORMAL)
out_vid = []
size = (720, 1280)
frame_count = 0
while cv.waitKey(1) < 0:
    hasFrame, frame = cap.read()
    if not hasFrame:
        cv.waitKey(0)
        break
    frame_count += 1 
    inWidth = args.width if args.width != -1 else frame.shape[1]/3
    inHeight = args.height if args.height != -1 else frame.shape[0]/3
    
    #cv.imshow('BaseImage', frame)
    #inp = cv.dnn.blobFromImage(frame, 1.0, (int(inWidth), int(inHeight)), (103.939, 116.779, 123.68), swapRB=False, crop=False)
    inp = cv.dnn.blobFromImage(frame, 1.0, size, (103.939, 116.779, 123.68), swapRB=False, crop=False)
    #print(inp)
    net.setInput(inp)
    out = net.forward()
   

    out = out.reshape(3, out.shape[2], out.shape[3])
    out[0] += 103.939
    out[1] += 116.779
    out[2] += 123.68
    out /= 255
    out = out.transpose(1, 2, 0)

    if args.median_filter:
        out = cv.blur(out, (10,10))   
    cv.imshow('Styled image', out)
    out_vid.append(out)
    if(frame_count == MAX_FRAMES):
        break

fourcc = cv.VideoWriter_fourcc(*'MP4V')
#final_out = cv.VideoWriter('out.mp4', fourcc = fourcc, fps = 1, frameSize=(1280, 720,3))
for i in range(len(out_vid)):
    print(out_vid[i].shape)
    #final_out.write(out_vid[i])
    cv.imwrite(f'output/img{i}.jpg', out_vid[i])
#final_out.release()

    
    

      
#code from https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py #try https://www.pyimagesearch.com/2018/08/27/neural-style-transfer-with-opencv/ #60 #cv.imshow('BaseImage', frame) #inp = cv.dnn.blobFromImage(frame, 1.0, (int(inWidth), int(inHeight)), (103.939, 116.779, 123.68), swapRB=False, crop=False) #print(inp) #final_out = cv.VideoWriter('out.mp4', fourcc = fourcc, fps = 1, frameSize=(1280, 720,3)) #final_out.write(out_vid[i]) #final_out.release()