open fp = io.BytesIO(fp.read()) AttributeError: 'str' object has no attribute 'read' in PIL/image.py
Question: I'm a little new to Python especially Imaging library that I'm currently
working with. I'm working with a facial recognition code and running it in my
Raspberry Pi 2 B+ running Jessie. I'm using Opencv 2.4.9 and Python 2.7. The
code that I'm currently working with worked till a few minutes ago but now I
keep getting an error. I didn't alter the code or update anything.

What I have tried: I uninstalled pillow and installed different versions, but
it is still not working.

I just don't understand what has changed. I tried by changing the variable
names still no effect.

    
    
    import cv
    import cv2
    import sys
    import os
    import datetime
    import time
    from PIL import Image
    import numpy as np
    
    
    def EuclideanDistance(p, q):
        p = np.asarray(p).flatten()
        q = np.asarray(q).flatten()
        return np.sqrt(np.sum(np.power((p-q),2)))
    
    
    class EigenfacesModel():
    
        def __init__(self, X=None, y=None, num_components=0):
            self.num_components = 0
            self.projections = []
            self.W = []
            self.mu = []
            if (X is not None) and (y is not None):
                self.compute(X,y)
    
        def compute(self, X, y):
            [D, self.W, self.mu] = pca(asRowMatrix(X),y, self.num_components)
            # store labels
            self.y = y
            # store projections
            for xi in X:
                self.projections.append(project(self.W, xi.reshape(1,-1), self.mu))
    
        def predict(self, X):
            minDist = np.finfo('float').max
            minClass = -1
            Q = project(self.W, X.reshape(1,-1), self.mu)
            for i in xrange(len(self.projections)):
                dist = EuclideanDistance(self.projections[i], Q)
                #print i,dist
                if dist < minDist:
                    minDist = dist
                    minClass = self.y[i]
            print "\nMinimum distance ", minDist        
            return minClass,minDist
    
    
    def asRowMatrix(X):
        if len(X) == 0:
            return np.array([])
        mat = np.empty((0, X[0].size), dtype=X[0].dtype)
        for row in X:
            mat = np.vstack((mat, np.asarray(row).reshape(1,-1)))
        return mat
    
    def read_images(filename, sz=None):
        c = 0
        X,y = [], []
        with open(filename) as f:
            for line in f:
                line = line.rstrip()
                im = Image.open(line)
                im = im.convert("L")
                # resize to given size (if given)
                if (sz is None):
                    im = im.resize((92,112), Image.ANTIALIAS)
                X.append(np.asarray(im, dtype=np.uint8))
                y.append(c)
                c = c+1
    
        print c
        return [X,y]
    
    def pca(X, y, num_components=0):
        [n,d] = X.shape
        print n
        if (num_components <= 0) or (num_components>n):
            num_components = n
        mu = X.mean(axis=0)
        X = X - mu
        if n>d:
            C = np.dot(X.T,X)
            [eigenvalues,eigenvectors] = np.linalg.eigh(C)
        else:
            C = np.dot(X,X.T)
            [eigenvalues,eigenvectors] = np.linalg.eigh(C)
            eigenvectors = np.dot(X.T,eigenvectors)
            for i in xrange(n):
                eigenvectors[:,i] = eigenvectors[:,i]/np.linalg.norm(eigenvectors[:,i])
        # or simply perform an economy size decomposition
        # eigenvectors, eigenvalues, variance = np.linalg.svd(X.T, full_matrices=False)
        # sort eigenvectors descending by their eigenvalue
        idx = np.argsort(-eigenvalues)
        eigenvalues = eigenvalues[idx]
        eigenvectors = eigenvectors[:,idx]
        # select only num_components
        num_components = 25
        eigenvalues = eigenvalues[0:num_components].copy()
        eigenvectors = eigenvectors[:,0:num_components].copy()
        return [eigenvalues, eigenvectors, mu]
    
    def project(W, X, mu=None):
        if mu is None:
            return np.dot(X,W)
        return np.dot(X - mu, W)
    
    
    
    
    def reconstruct(W, Y, mu=None):
        if mu is None:
            return np.dot(W.T,Y)
        return np.dot(W.T,Y) + mu
    
    #if __name__ == "__main__":
    
    def FaceRecognitionWrapper(Database_Address,TestImages_Address):
    
        out_dir = "Output_Directory"
    
        [X,y] = read_images(Database_Address)
        y = np.asarray(y, dtype=np.int32)
        #print len(X)
    
        model = EigenfacesModel(X[0:], y[0:])
        # get a prediction for the first observation
        [X1,y1] = read_images(TestImages_Address) 
        y1 = np.asarray(y1, dtype=np.int32)
        OutputFile = open("Output.txt",'a')
        for i in xrange(len(X1)):
            predicted,difference = model.predict(X1[i])
            predicted1 = int(predicted/10) + 1
            if difference <= 1000:
                print i+1 , "th image was recognized as individual" , predicted+1
                OutputFile.write(str(predicted1))
                OutputFile.write("\n")
            else:
                os.chdir(out_dir)
                print i+1,"th image could not be recognized. Storing in error folder."
    
                errorImage = Image.fromarray(X1[i])
                current_time = datetime.datetime.now().time()
                error_img_name=current_time.isoformat()+'.png'
                errorImage.save(error_img_name)
                os.chdir('..')
        OutputFile.close()
    
    
    
    
    
    #Create Model Here
    
    cascPath = '/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_default.xml'
    faceCascade = cv2.CascadeClassifier(cascPath)
    Test_Files = []
    
    video_capture = cv2.VideoCapture(0)
    
    i = 0
    
    while True:
        # Capture frame-by-frame
        ret, frame = video_capture.read()
    
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
        faces = faceCascade.detectMultiScale(
            gray,
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(30, 30),
            flags=cv2.cv.CV_HAAR_SCALE_IMAGE
        )
    
        # Draw a rectangle around the faces
        for (x, y, w, h) in faces:
            dummy_image = frame
            cv2.rectangle(dummy_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
            dummy_image=dummy_image[y:y+h, x:x+w]
            dirname = 'detection_output'
            os.chdir(dirname)
            current_time = datetime.datetime.now().time()   
            final_img_name=current_time.isoformat()+'.png' 
            Test_Files.append(final_img_name)  
            dummy_image = cv2.cvtColor(dummy_image, cv2.COLOR_BGR2GRAY) 
            cv2.imwrite(final_img_name,dummy_image)
            os.chdir('..')
    
    
        # Display the resulting frame
        cv2.imshow('Video', frame)
    
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        i = i + 1
    
        if i % 20 == 0:
            dirname = 'detection_output'
            os.chdir(dirname)
            TestFile = open('CameraFeedFaces.txt',"w")
            for Files in Test_Files:
                TestFile.write(os.getcwd()+"/"+Files+"\n")
            TestFile.close()
            os.chdir("..")
            #Call testing.py
            FaceRecognitionWrapper("/home/pi/train_faces/temp.txt",os.getcwd()+"/detection_output/CameraFeedFaces.txt")
            #Open Output File and Copy in a separate folder where distance greater than threshold
            #Then delete all the files in the folder
            break
    
    
    # When everything is done, release the capture
    video_capture.release()
    cv2.destroyAllWindows()
    

And here's the Traceback:

    
    
    Traceback (most recent call last):
      File "hel.py", line 213, in <module>
        FaceRecognitionWrapper("/home/pi/train_faces/temp.txt",os.getcwd()+"/detection_output/CameraFeedFaces.txt")
      File "hel.py", line 127, in FaceRecognitionWrapper
        [X,y] = read_images(Database_Address)
      File "hel.py", line 68, in read_images
        im = Image.open(line)
      File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2277, in open
        fp = io.BytesIO(fp.read())
    AttributeError: 'str' object has no attribute 'read'
    

[Output when code was working](http://i.stack.imgur.com/XebZz.png)

I read it somewhere and if I try and edit im = Image.open(open(line,'rb')) I'm
getting this error instead of the previous one

    
    
    Traceback (most recent call last):
      File "hel.py", line 208, in <module>
        FaceRecognitionWrapper("/home/pi/train_faces/temp.txt",os.getcwd()+"/detection_output/CameraFeedFaces.txt")
      File "hel.py", line 122, in FaceRecognitionWrapper
        [X,y] = read_images(Database_Address)
      File "hel.py", line 63, in read_images
        im = Image.open(open(line,'rb'))
    IOError: [Errno 2] No such file or directory: ''
    


Answer: Your subject line is confusing. You fixed that problem and then exposed a
different bug.

    
    
    IOError: [Errno 2] No such file or directory: ''
    

The message shows that you are trying to open a file with no name and that
means that the input file you are reading has at least one blank line. If its
okay for that file to have blank lines, just skip those like:

    
    
    def read_images(filename, sz=None):
        c = 0
        X,y = [], []
        with open(filename) as f:
            for line in f:
                line = line.rstrip()
                if line:
                    im = Image.open(open(line,'rb')) 
                    im = im.convert("L"
                    # resize to given size (if given)
                    if (sz is None):
                        im = im.resize((92,112), Image.ANTIALIAS)
                    X.append(np.asarray(im, dtype=np.uint8))
                    y.append(c)
                    c = c+1
    

Otherwise, you have a legitimate error and you should catch and handle the
exception.

