from os import listdir from PIL import Image, ImageOps import numpy ROWS = 28 #Height of image COLS = 28 #Width of image ''' Reads the MNIST handwriten digits IDx3 and IDx1 files. Returns a list of lists. every list contains the 784 pixels (0...255)of an image (row by row) and the label of the image (0...9). images is the name of the IDx3 file of the images. labels is the name of the IDx1 file of the labels. ''' def idx2list(images,labels): lst = [] #initializes the returned list fimages = open(images,"rb")#"rb" is "read bytes" flabels = open(labels,"rb") ''' Your code will move the cursors in flabels and fimage to the first "interesting" byte: a byte that contains data of the image ''' x = fimages.read(1)#Reads the first byte of an image while x != b"": line = [ord(x)] #Line will acummulate all the image's pixels ''' Your code will read the rest of the pixels in the image and add them to line. ''' line += [ord(flabels.read(1))]#Reads the label lst += [line]#Adds the image to lst x = fimages.read(1) fimages.close() flabels.close() return lst ''' Transforms a list of data (compatible with MINST training dataset) to a grayscale COLSXROWS image. ''' def data2img(lst): lst2d = [] #Transforms the list to a 2D list for i in range(ROWS): lst2d += [lst[COLS*i : COLS*(i+1)]] #Image.fromarray converts a numpy 2D array to an image return Image.fromarray(numpy.uint8(numpy.array(lst2d))) ''' Displays the image representes by ds[i]. If i is too big - does nothing ''' def display_image(ds, i): if i < len(ds): im = data2img(ds[i]) ''' Your code will display the image im. A hint: find the method (in Image) that displays an image. ''' ''' Returns the Euclidean distance between a and b ''' def distance(a, b): dis = 0 ''' Your code will calculate the euclidean distance between a and b ''' return dis ''' Returns the label of the line in dataset that is closest to instance ''' def nearest_neighbour(dataset, instance): mindis = float("inf")#mindis is the dis to the nearest neighbour ''' Your code will scan the dataset and find the nearest neighbour to instance. the label of this neighbor will be returned. ''' ''' Test the accuracy of classification using as dataset the first train instances and using as a test set the last test instances ''' def test(ds, train, test): training_set = ds[:train] count = 0 ''' Your code will count the number of correctly classified images from the last test images in the dataset ''' return count / test ''' Transforms the image in filename to a list of data compatible with MINST training dataset. The image is resized and converted to grayscale. if neg is True then a negative of the is computed ''' def img2data(filename, neg = False): im = Image.open( filename ) #reads the image im = im.convert("L") #converts to grayscale im = im.resize([COLS, ROWS])#resizes the image ''' Your code will produce the negative of im, if neg is True. Find how to convert an image into it's negative. Hint: ImageOps ''' a = list(im.getdata()) #converts to a list of ints 0-255 return a ''' Classifies all the jpg files in path using the dataset ds Prints file name and its class. ''' def classify_images(ds, path): for f in listdir(path): if len(f)> 4 and f[-4:].upper() == ".JPG":#the file is a jpg? im = img2data(path + "\\" + f , neg = True) print(f, nearest_neighbour(ds, im))