import sys # for command line arguments
import numpy as np # for matrix processing
from PIL import Image, ImageOps # for image processing
import time # to time part of the code

# make sure command line arguments are provided
if (len(sys.argv) < 4):
    print ('command usage :',sys.argv[0],'infile','outfile','threshold')
    exit(1)
infile = sys.argv[1]
outfile = sys.argv[2]
threshold = int(sys.argv[3])

# open the input image, convert to grayscale,
# convert to a matrix, and determine the rows and cols
input = Image.open(infile)
gray = ImageOps.grayscale(input)
carA = np.array(gray).astype(np.int32)
rows,cols = carA.shape

# pad the perimeter of the image matrix with zeros
# and create the E matrix initialized to all zeros
carA_pad = np.pad(carA,[1,1],'constant',constant_values = 0)
E = np.zeros((rows,cols),dtype='uint8')

# time just the Sobel edge detector
start = time.process_time()

# Sobel Edge Detector
for i in range(1,rows+1):
    for j in range(1,cols+1):
        P1 = carA_pad[i-1][j-1]
        P2 = carA_pad[i-1][j]
        P3 = carA_pad[i-1][j+1]
        P4 = carA_pad[i][j-1]
        P6 = carA_pad[i][j+1]
        P7 = carA_pad[i+1][j-1]
        P8 = carA_pad[i+1][j]
        P9 = carA_pad[i+1][j+1]
        Gx = P3+2*P6+P9-P1-2*P4-P7
        Gy = P1+2*P2+P3-P7-2*P8-P9
        size = np.abs(Gx)+np.abs(Gy)
        if (size > threshold):
            E[i-1][j-1] = 255

# record and print elapsed time
elapsed = time.process_time()-start
print ('Time to Run The Nested For Loop Sobel Edge Detector in Python =',
        np.round(elapsed,4),'seconds')

# create the edges image
edges = Image.fromarray(E)
edges.save(outfile)