In [1]:
import numpy as np
import pandas as pd
import os
import cv2
from PIL import Image
from scipy.misc import imread
import matplotlib.pyplot as plt
import skimage.feature
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import keras
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, Lambda, Cropping2D
from keras.utils import np_utils

from collections import Counter

%matplotlib inline


Using TensorFlow backend.

In [2]:
class_names = ['adult_females', 'adult_males', 'juveniles', 'pups', 'subadult_males']

my_dir = "/Users/kylefrankovich/Desktop/seal_the_deal/src/data/TrainSmall2/"

file_names = os.listdir(my_dir + "Train/")
file_names = sorted(file_names, key=lambda 
                    item: (int(item.partition('.')[0]) if item[0].isdigit() else float('inf'), item)) 

# select a subset of files to run on
file_names = file_names[0:6]
print(file_names)
# dataframe to store results in
coordinates_df = pd.DataFrame(index=file_names, columns=class_names)


['41.jpg', '42.jpg', '43.jpg', '44.jpg', '45.jpg', '46.jpg']

It looks like the code below is using the dotted images to get the class pixel coordinates per image:


In [3]:
for filename in file_names:
    
    # read the Train and Train Dotted images
    image_1 = cv2.imread(my_dir + "/TrainDotted/" + filename)
    image_2 = cv2.imread(my_dir + "/Train/" + filename)
    
    cut = np.copy(image_2)
    
    # absolute difference between Train and Train Dotted
    image_3 = cv2.absdiff(image_1,image_2)
    
# mask out blackened regions from Train Dotted
    mask_1 = cv2.cvtColor(image_1, cv2.COLOR_BGR2GRAY)
    mask_1[mask_1 < 20] = 0
    mask_1[mask_1 > 0] = 255
    
    mask_2 = cv2.cvtColor(image_2, cv2.COLOR_BGR2GRAY)
    mask_2[mask_2 < 20] = 0
    mask_2[mask_2 > 0] = 255
    
    image_3 = cv2.bitwise_or(image_3, image_3, mask=mask_1)
    image_3 = cv2.bitwise_or(image_3, image_3, mask=mask_2) 
    
    # convert to grayscale to be accepted by skimage.feature.blob_log
    image_3 = cv2.cvtColor(image_3, cv2.COLOR_BGR2GRAY)
    
    # detect blobs
    blobs = skimage.feature.blob_log(image_3, min_sigma=3, max_sigma=4, num_sigma=1, threshold=0.02)
    
    adult_males = []
    subadult_males = []
    pups = []
    juveniles = []
    adult_females = [] 
    
    image_circles = image_1
    
    for blob in blobs:
        # get the coordinates for each blob
        y, x, s = blob
        # get the color of the pixel from Train Dotted in the center of the blob
        g,b,r = image_1[int(y)][int(x)][:]
        
        # decision tree to pick the class of the blob by looking at the color in Train Dotted
        if r > 200 and g < 50 and b < 50: # RED
            adult_males.append((int(x),int(y)))
            cv2.circle(image_circles, (int(x),int(y)), 20, (0,0,255), 10) 
        elif r > 200 and g > 200 and b < 50: # MAGENTA
            subadult_males.append((int(x),int(y))) 
            cv2.circle(image_circles, (int(x),int(y)), 20, (250,10,250), 10)
        elif r < 100 and g < 100 and 150 < b < 200: # GREEN
            pups.append((int(x),int(y)))
            cv2.circle(image_circles, (int(x),int(y)), 20, (20,180,35), 10)
        elif r < 100 and  100 < g and b < 100: # BLUE
            juveniles.append((int(x),int(y))) 
            cv2.circle(image_circles, (int(x),int(y)), 20, (180,60,30), 10)
        elif r < 150 and g < 50 and b < 100:  # BROWN
            adult_females.append((int(x),int(y)))
            cv2.circle(image_circles, (int(x),int(y)), 20, (0,42,84), 10)  
            
        cv2.rectangle(cut, (int(x)-112,int(y)-112),(int(x)+112,int(y)+112), 0,-1)
            
    coordinates_df["adult_males"][filename] = adult_males
    coordinates_df["subadult_males"][filename] = subadult_males
    coordinates_df["adult_females"][filename] = adult_females
    coordinates_df["juveniles"][filename] = juveniles
    coordinates_df["pups"][filename] = pups
    
print(coordinates_df)


                                            adult_females  \
41.jpg  [(3049, 2550), (2981, 2536), (3052, 2497), (29...   
42.jpg  [(3832, 1686), (4319, 1658), (4198, 1643), (43...   
43.jpg  [(3319, 3622), (3203, 3606), (3097, 3504), (30...   
44.jpg  [(3301, 2214), (3256, 2171), (3427, 2166), (34...   
45.jpg  [(2267, 2665), (2151, 2132), (2046, 2037), (20...   
46.jpg                                                 []   

                                              adult_males  \
41.jpg  [(2749, 2516), (3110, 2349), (2293, 2315), (25...   
42.jpg  [(4940, 2506), (4973, 1930), (4816, 1883), (44...   
43.jpg  [(3365, 3405), (3295, 3267), (2636, 3115), (28...   
44.jpg         [(3360, 2145), (3599, 1867), (3068, 1494)]   
45.jpg  [(2633, 3199), (2108, 2048), (2546, 1423), (25...   
46.jpg                                     [(5418, 1338)]   

                                                juveniles  \
41.jpg  [(2922, 2514), (3081, 2421), (3015, 2240), (29...   
42.jpg                                      [(4175, 546)]   
43.jpg  [(3168, 3552), (3152, 3542), (3408, 3351), (25...   
44.jpg  [(3273, 2242), (3272, 2221), (3326, 2206), (31...   
45.jpg  [(2199, 1917), (1756, 1874), (1725, 1868), (18...   
46.jpg                                                 []   

                                                     pups  \
41.jpg  [(2977, 2576), (2960, 2561), (2833, 2530), (29...   
42.jpg                                                 []   
43.jpg  [(3268, 3585), (3279, 3572), (3029, 3513), (29...   
44.jpg                                                 []   
45.jpg                                                 []   
46.jpg                                                 []   

                                           subadult_males  
41.jpg                                                 []  
42.jpg  [(3617, 1716), (4010, 1641), (4337, 1605), (36...  
43.jpg  [(2999, 3583), (3801, 3125), (1817, 2212), (27...  
44.jpg                       [(3375, 1740), (2950, 1240)]  
45.jpg  [(1711, 1699), (1549, 1650), (1689, 1424), (26...  
46.jpg  [(5372, 2086), (5600, 1485), (5569, 1432), (54...  

In [4]:
f, ax = plt.subplots(1,1,figsize=(10,16))
ax.imshow(cv2.cvtColor(image_circles, cv2.COLOR_BGR2RGB))
plt.show()



In [9]:
f, ax = plt.subplots(1,1,figsize=(10,16))
ax.imshow(cv2.cvtColor(cut, cv2.COLOR_BGR2RGB))
plt.show()



In [5]:
x = []
y = []

for filename in file_names:    
    image = cv2.imread(my_dir + "/Train/" + filename)
    for lion_class in class_names:
        for coordinates in coordinates_df[lion_class][filename]:
            thumb = image[coordinates[1]-32:coordinates[1]+32,coordinates[0]-32:coordinates[0]+32,:]
            if np.shape(thumb) == (64, 64, 3):
                x.append(thumb)
                y.append(lion_class)

In [6]:
for i in range(0,np.shape(cut)[0],224):
    for j in range(0,np.shape(cut)[1],224):                
        thumb = cut[i:i+64,j:j+64,:]
        if np.amin(cv2.cvtColor(thumb, cv2.COLOR_BGR2GRAY)) != 0:
            if np.shape(thumb) == (64,64,3):
                x.append(thumb)
                y.append("negative")

In [7]:
class_names.append("negative")

In [8]:
x = np.array(x)
y = np.array(y)

In [9]:
for lion_class in class_names:
    f, ax = plt.subplots(1,10,figsize=(12,1.5))
    f.suptitle(lion_class)
    axes = ax.flatten()
    j = 0
    for a in axes:
        a.set_xticks([])
        a.set_yticks([])
        for i in range(j,len(x)):
            if y[i] == lion_class:
                j = i+1
                a.imshow(cv2.cvtColor(x[i], cv2.COLOR_BGR2RGB))
                break



In [10]:
encoder = LabelBinarizer()
encoder.fit(y)
y = encoder.transform(y).astype(float)

In [11]:
model = Sequential()

model.add(Lambda(lambda x: (x / 255.0) - 0.5, input_shape=(64,64,3)))


model.add(Conv2D(32, (5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(128, (5, 5), activation='relu', padding='same'))

model.add(Flatten())

model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(6, activation='softmax'))

model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])

In [12]:
history = model.fit(x, y, epochs=10, verbose=0)

In [13]:
plt.plot(history.history['acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()



In [28]:
img = cv2.imread(my_dir + "/Train/"  + filename)

x_test = []

for i in range(0,np.shape(img)[0],64):
    for j in range(0,np.shape(img)[1],64):                
        thumb = img[i:i+64,j:j+64,:]        
        if np.shape(thumb) == (64,64,3):
            x_test.append(thumb)

x_test = np.array(x_test)
print(x_test)
len(x_test)


[[[[127 116 108]
   [136 127 118]
   [146 137 128]
   ..., 
   [ 84  77  52]
   [ 84  77  52]
   [ 83  76  51]]

  [[108  97  93]
   [123 113 106]
   [129 121 114]
   ..., 
   [ 85  78  53]
   [ 85  78  53]
   [ 83  76  51]]

  [[115 105 105]
   [122 113 110]
   [123 114 110]
   ..., 
   [ 84  77  52]
   [ 83  76  51]
   [ 82  75  50]]

  ..., 
  [[ 91  82  48]
   [ 92  83  49]
   [ 96  85  53]
   ..., 
   [ 84  79  48]
   [ 83  78  47]
   [ 84  79  46]]

  [[ 89  80  47]
   [ 89  80  47]
   [ 93  82  52]
   ..., 
   [ 84  78  49]
   [ 82  77  46]
   [ 83  78  47]]

  [[ 91  82  49]
   [ 91  81  51]
   [ 94  83  53]
   ..., 
   [ 83  77  48]
   [ 81  75  46]
   [ 81  76  45]]]


 [[[ 82  80  50]
   [ 83  81  51]
   [ 83  79  50]
   ..., 
   [ 91  83  54]
   [ 86  78  48]
   [ 82  74  44]]

  [[ 81  77  48]
   [ 82  78  49]
   [ 82  78  49]
   ..., 
   [ 87  79  50]
   [ 85  77  48]
   [ 82  74  44]]

  [[ 77  73  45]
   [ 78  74  46]
   [ 78  74  46]
   ..., 
   [ 86  78  49]
   [ 89  78  50]
   [ 87  76  48]]

  ..., 
  [[ 88  81  56]
   [ 89  82  57]
   [ 89  82  57]
   ..., 
   [ 77  74  46]
   [ 77  74  46]
   [ 79  77  47]]

  [[ 85  77  54]
   [ 86  78  55]
   [ 87  79  56]
   ..., 
   [ 77  74  46]
   [ 75  74  46]
   [ 78  78  48]]

  [[ 81  73  50]
   [ 83  75  52]
   [ 84  76  53]
   ..., 
   [ 82  81  53]
   [ 80  79  51]
   [ 76  78  48]]]


 [[[ 91  74  53]
   [ 90  73  52]
   [ 89  73  50]
   ..., 
   [ 86  76  46]
   [ 89  78  48]
   [ 87  76  46]]

  [[ 87  73  50]
   [ 86  72  49]
   [ 86  73  47]
   ..., 
   [ 91  81  51]
   [ 91  80  50]
   [ 89  78  48]]

  [[ 85  74  46]
   [ 84  73  45]
   [ 85  74  46]
   ..., 
   [ 95  84  56]
   [ 94  82  54]
   [ 91  79  51]]

  ..., 
  [[ 86  78  49]
   [ 85  77  48]
   [ 86  77  50]
   ..., 
   [ 87  79  49]
   [ 89  81  51]
   [ 92  84  54]]

  [[ 86  78  48]
   [ 86  78  49]
   [ 87  78  51]
   ..., 
   [ 86  78  49]
   [ 86  78  49]
   [ 89  81  52]]

  [[ 85  77  47]
   [ 86  78  49]
   [ 86  77  50]
   ..., 
   [ 89  78  51]
   [ 87  76  49]
   [ 90  79  52]]]


 ..., 
 [[[120 112  95]
   [116 108  91]
   [109 101  84]
   ..., 
   [124 114 107]
   [109 100  90]
   [122 113 103]]

  [[119 111  94]
   [113 105  88]
   [109 101  84]
   ..., 
   [116 107  98]
   [112 103  93]
   [131 123 110]]

  [[122 114  97]
   [119 111  94]
   [111 103  86]
   ..., 
   [125 116 107]
   [116 108  95]
   [124 116 103]]

  ..., 
  [[141 131 131]
   [154 146 146]
   [151 147 146]
   ..., 
   [227 211 212]
   [175 156 159]
   [124 102 107]]

  [[161 153 153]
   [181 176 175]
   [189 186 182]
   ..., 
   [185 173 167]
   [200 185 182]
   [142 127 124]]

  [[187 182 181]
   [247 243 242]
   [234 233 229]
   ..., 
   [137 131 120]
   [168 159 150]
   [143 134 125]]]


 [[[134 128 115]
   [129 124 109]
   [125 121 103]
   ..., 
   [201 203 183]
   [223 225 205]
   [213 215 195]]

  [[142 137 122]
   [151 147 129]
   [128 124 106]
   ..., 
   [202 204 184]
   [211 213 193]
   [212 214 194]]

  [[133 129 110]
   [138 134 115]
   [132 128 109]
   ..., 
   [204 206 186]
   [203 205 185]
   [212 214 194]]

  ..., 
  [[126 108 107]
   [122 104 103]
   [125 106 109]
   ..., 
   [196 196 180]
   [177 176 162]
   [160 158 147]]

  [[117 104  96]
   [142 128 122]
   [177 162 160]
   ..., 
   [191 188 174]
   [172 168 157]
   [168 163 154]]

  [[116 107  97]
   [129 120 111]
   [150 140 133]
   ..., 
   [172 168 157]
   [157 152 143]
   [158 153 144]]]


 [[[207 208 182]
   [205 206 180]
   [206 209 183]
   ..., 
   [255 255 255]
   [255 253 255]
   [255 253 255]]

  [[210 211 185]
   [208 209 183]
   [201 204 178]
   ..., 
   [255 253 253]
   [255 254 255]
   [255 254 255]]

  [[216 216 192]
   [212 212 188]
   [200 203 178]
   ..., 
   [255 255 255]
   [255 255 255]
   [255 255 255]]

  ..., 
  [[161 161 145]
   [170 170 154]
   [197 197 185]
   ..., 
   [224 224 210]
   [231 231 217]
   [242 242 228]]

  [[168 165 150]
   [156 156 140]
   [161 161 149]
   ..., 
   [210 211 195]
   [224 225 209]
   [236 237 221]]

  [[157 155 137]
   [147 147 131]
   [134 134 122]
   ..., 
   [193 195 176]
   [206 208 189]
   [219 223 204]]]]
Out[28]:
5046

In [34]:
y_predicted = model.predict(x_test, verbose=1)


5046/5046 [==============================] - 47s    

In [30]:
print(y_predicted)


[[  7.49331036e-07   6.18605645e-06   7.26505505e-06   9.99957085e-01
    1.63168752e-05   1.24156868e-05]
 [  1.56927621e-03   5.84475056e-04   6.94450398e-04   9.96094406e-01
    4.44577774e-04   6.12854201e-04]
 [  4.97077417e-04   4.45462763e-04   3.96563788e-04   9.97191966e-01
    5.16406668e-04   9.52554459e-04]
 ..., 
 [  2.12655562e-18   8.99773725e-20   7.34603722e-20   1.00000000e+00
    7.67388675e-14   1.51712049e-20]
 [  9.89737551e-17   1.54642424e-19   2.09804072e-17   1.00000000e+00
    1.64563604e-15   2.32728444e-18]
 [  8.20161484e-13   1.19651976e-14   1.01679936e-13   1.00000000e+00
    1.88889442e-12   4.52446376e-14]]

In [40]:
y_predicted = encoder.inverse_transform(y_predicted)

In [41]:
print(y_predicted)


['negative' 'negative' 'negative' ..., 'negative' 'negative' 'negative']

In [42]:
print(Counter(y_predicted).items())


dict_items([('juveniles', 43), ('adult_males', 7), ('subadult_males', 3), ('adult_females', 59), ('pups', 11), ('negative', 4923)])

In [63]:
blah = Counter(y_predicted)
dict(blah)


Out[63]:
{'adult_females': 59,
 'adult_males': 7,
 'juveniles': 43,
 'negative': 4923,
 'pups': 11,
 'subadult_males': 3}

In [25]:
reference = pd.read_csv(my_dir + "/Train/"  + 'train.csv')
reference.iloc[:1]
reference.iloc[46]


Out[25]:
train_id          46
adult_males        1
subadult_males     4
adult_females      0
juveniles          0
pups               0
Name: 46, dtype: int64

In [22]:
reference.head()
reference.tail()


Out[22]:
train_id adult_males subadult_males adult_females juveniles pups
943 943 1 1 24 26 0
944 944 1 4 1 0 0
945 945 6 0 79 6 45
946 946 3 1 34 33 0
947 947 6 4 29 6 24

In [21]:
print(filename)


46.jpg

In [ ]: