'''
Created on 17 Oct. 2018

@author: Edgar
'''
'''
Created on 6 May 2018

@author: Edgar
'''
import numpy as np 
import cv2 



#from numpy.core._internal import _commastring

iHeight = 400
iWidth = 600
numberOfPhos = 35
sigma = 8.712
phosSep = 14
kernelSize = 19
phoSize =  3
#read and scale the image
def imread (imageName,imageHeight, imageWidth, format ):
    if format == 1 :
        img = cv2.imread(imageName,1 )
    if format == 0:
        img = cv2.imread(imageName,0)
    
    scaled = cv2.resize(img,(imageWidth,imageHeight))
    return scaled
#shows the image on the display
def imshow(name, image):
    cv2.imshow(name, image) 
    cv2.waitKey( )
    cv2.destroyAllWindows()

#gnerating kernel; 
#Phosphene seperation: 3 degrees = 3 *4.4 = 13.2 px sagma is 13.2*0.66 = 8.712
#generation of gaussain keneral and the sum
def Gkernel(kernelSize, sigma):
    kernel = np.zeros((kernelSize,kernelSize))
    for i in range(0,kernelSize):
        for j in range(0,kernelSize):
            centre = (kernelSize -1 )/2
            kernel[i,j] =  kernel[i,j]=np.exp(-((i-centre)**2+(j-centre)**2)/(2*sigma**2))
    kernelSum = np.sum(kernel)
    
    return kernel, kernelSum

def iKernel(kernelSize):
    kernel = np.zeros((kernelSize,kernelSize))
    center = (kernelSize -1)/2
    kernel[center,center] = 1
    return kernel, 1 

#numberOfPhos x means there will be x * x phosphene
#get the centre location of each section of image that is blured as vision field
#and also return a list that contains the pixels for blur as L 
# return the segmented vision the the center location of each segmented vision(phosphene)
def getVision(image, numberOfPhos,  PhosSep, kernelSize):
    visionField = np.zeros((numberOfPhos, numberOfPhos, 2))
    rightTopCornerR = 199-((numberOfPhos/2)-1) * PhosSep
    rightTopCornerC = 299-((numberOfPhos/2)-1) * PhosSep
    visionField[0,0,0] = rightTopCornerR 
    visionField[0,0,1] = rightTopCornerC    
    for i in range(0,numberOfPhos,):
        for j in range(0,numberOfPhos):
            visionField[i,j,0] = visionField[0,0,0] + i * PhosSep
            visionField[i,j,1] = visionField[0,0,1] + j * PhosSep
          
    L = list()
   
    for i in range(0,numberOfPhos):
        L.append([])
    edge = (kernelSize-1)/2
    for i in range(0, numberOfPhos):
        for j in range(0,numberOfPhos):
            #g = scale[visionField[i,j,0]-9:visionField[i,j,0]+10,visionField[i,j,1]-9:visionField[i,j,1]+10]
            g = image[visionField[i,j,0]- edge : visionField[i,j,0]+edge+1 , visionField[i,j,1]-edge : visionField[i,j,1]+edge+1]
            L[i].append(g)
    return L, visionField

#numberOfPhos x means there will be x * x phosphene
#generating the pixels that is generated by convoloving the kernel and image
def applyKernel(numberOfPhos,kernel, kernelSum,scatterVision):
    phos = np.zeros((numberOfPhos,numberOfPhos))
    for i in range(0, numberOfPhos):
        for j in range(0,numberOfPhos):
            clip = np.copy(scatterVision[i][j])
            phos[i][j] = np.sum(np.multiply(clip,kernel))/kernelSum
    phos = phos.astype('uint8')
    #print np.shape(phos)
    return phos 
#numberOfPhos x means there will be x * x phosphene
#phos is the list containg the filtered single pixels, visionfield is the centre location of the filtered section of the image
def scatterPhos(phos, visionField, numberOfPhos, phosSize):
    stimulatedVision = np.zeros((iHeight, iWidth))
    stimulatedVision = stimulatedVision.astype('uint8')
    for i in range(0, numberOfPhos):
        for j in range(0,numberOfPhos):
            stimulatedVision[visionField[i,j,0]-phosSize:visionField[i,j,0]+phosSize+1, visionField[i,j,1]-phosSize:visionField[i,j,1]+phosSize+1] = phos[i,j]
    return stimulatedVision

#Impletemneting color quantization, clluter the image
def cluster(image):
    
    floatImage = image.reshape(-1)
    #floatImage = np.reshape(image, (-1,5)) # the second number can control the quality
    floatImage = np.float32(floatImage)
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    #number of clusters
    K = 5
    ret,label,center=cv2.kmeans(floatImage,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
    center = np.uint8(center)
    res = center[label.flatten()]
    res2 = res.reshape(image.shape)
    return res2
def scale(image,imageHeight, imageWidth):
    scaled = cv2.resize(image,(imageWidth,imageHeight))
    return scaled

kernel, KernelSum = Gkernel(19, 8.712)




img = cv2.imread("timg.jpg",0)

px = img
print px.shape #(hight, length)
np.savetxt("foo.txt", img , fmt= '%i')
print type(img)
scaled = cv2.resize(img, (600, 400))
kernel, KernelSum = Gkernel(19, 8.712)
ik,iksum = iKernel(19)
scatterVision, visionField  =  getVision(scaled, numberOfPhos, phosSep,kernelSize)

phos = applyKernel(numberOfPhos,kernel,KernelSum,scatterVision)
#phos = applyKernel(numberOfPhos,ik,iksum,scatterVision)

sv = scatterPhos(phos, visionField,numberOfPhos,phoSize)



while(True):
   
    cv2.imshow('frame',sv)
    
    

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()









