{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install imutils","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# import the necessarry packages\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.model_selection import train_test_split\nfrom imutils import paths\nimport pandas as pd\nimport numpy as np \nimport imutils\nimport cv2\nimport os","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Next, we are going to define two methods to take an input image and convert it to a feature vector, or a list of numbers that quantify the contents of an image. The first method can be seen below:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def image_to_feature_vector(image, size=(32, 32)):\n\t# resize the image to a fixed size, then flatten the image into a list of raw pixel intensities\n\treturn cv2.resize(image, size).flatten()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### We then define our second method, this one called extract_color_histogram :"},{"metadata":{"trusted":true},"cell_type":"code","source":"def extract_color_histogram(image, bins=(8, 8, 8)):\n\t# extract a 3D color histogram from the HSV color space using\n\t# the supplied number of `bins` per channel\n\thsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n\thist = cv2.calcHist([hsv], [0, 1, 2], None, bins,\n\t\t[0, 180, 0, 256, 0, 256])\n\t# handle normalizing the histogram if we are using OpenCV 2.4.X\n\tif imutils.is_cv2():\n\t\thist = cv2.normalize(hist)\n\t# otherwise, perform \"in place\" normalization in OpenCV 3 (I\n\t# personally hate the way this is done\n\telse:\n\t\tcv2.normalize(hist, hist)\n\t# return the flattened histogram as the feature vector\n\treturn hist.flatten()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls \"/kaggle/working/train\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!unzip \"../input/dogs-vs-cats/train.zip\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"!unzip \"../input/dogs-vs-cats/test1.zip\"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"dataset = \"/kaggle/working/train\"\nneighbors = 2","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### We are now ready to prepare our images for feature extraction:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# grab the list of images that we'll be describing\nprint(\"[INFO] describing images...\")\nimagePaths = list(paths.list_images(dataset))\nprint(\"[INFO] dataset has {} images\".format(len(imagePaths)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize the raw pixel intensities matrix, the features matrix, and labels list\nrawImages = []\nfeatures = []\nlabels = []","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Let’s move on to extracting features from our dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# loop over the input images\nfor (i, imagePath) in enumerate(imagePaths):\n\t# load the image and extract the class label (assuming that our\n\t# path as the format: /path/to/dataset/{class}.{image_num}.jpg\n\timage = cv2.imread(imagePath)\n\tlabel = imagePath.split(os.path.sep)[-1].split(\".\")[0]\n    \n\t# extract raw pixel intensity \"features\", followed by a color\n\t# histogram to characterize the color distribution of the pixels\n\t# in the image\n\tpixels = image_to_feature_vector(image)\n\thist = extract_color_histogram(image)\n    \n\t# update the raw images, features, and labels matricies, respectively\n\trawImages.append(pixels)\n\tfeatures.append(hist)\n\tlabels.append(label)\n    \n\t# show an update every 1,000 images\n\tif i > 0 and i % 1000 == 0:\n\t\tprint(\"[INFO] processed {}/{}\".format(i, len(imagePaths)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### You might be curious how much memory our rawImages  and features  matrices take up — the following code block will tell us when executed:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# show some information on the memory consumed by the raw images matrix and features matrix\nrawImages = np.array(rawImages)\nfeatures = np.array(features)\nlabels = np.array(labels)\nprint(\"[INFO] pixels matrix: {:.2f}MB\".format(\n\trawImages.nbytes / (1024 * 1000.0)))\nprint(\"[INFO] features matrix: {:.2f}MB\".format(\n\tfeatures.nbytes / (1024 * 1000.0)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Next, we need to take our data partition it into two splits — one for training and another for testing:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# partition the data into training and testing splits, using 75%\n# of the data for training and the remaining 25% for testing\n(trainRI, testRI, trainRL, testRL) = train_test_split(\n\trawImages, labels, test_size=0.25, random_state=42)\n(trainFeat, testFeat, trainLabels, testLabels) = train_test_split(\n\tfeatures, labels, test_size=0.25, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Let’s apply the k-NN classifier to the raw pixel intensities:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# train and evaluate a k-NN classifer on the raw pixel intensities\nprint(\"[INFO] evaluating raw pixel accuracy...\")\nmodel = KNeighborsClassifier(n_neighbors=neighbors,\n\tn_jobs=-1)\nmodel.fit(trainRI, trainRL)\nacc = model.score(testRI, testRL)\nprint(\"[INFO] raw pixel accuracy: {:.2f}%\".format(acc * 100))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train and evaluate a k-NN classifer on the raw pixel intensities\nprint(\"[INFO] evaluating raw pixel accuracy...\")\nmodel = KNeighborsClassifier(n_neighbors=neighbors,\n\tn_jobs=-1)\nmodel.fit(trainFeat, trainLabels)\nacc = model.score(testFeat, testLabels)\nprint(\"[INFO] raw pixel accuracy: {:.2f}%\".format(acc * 100))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As the figure above demonstrates, by utilizing raw pixel intensities we were able to reach 53.55% accuracy. On the other hand, applying k-NN to color histograms achieved a slightly better 58.27% accuracy.\n\nIn both cases, we were able to obtain > 50% accuracy, demonstrating there is an underlying pattern to the images for both raw pixel intensities and color histograms.\n\nHowever, that 58% accuracy leaves much to be desired.\n\nAnd as you might imagine, color histograms aren’t the best way to distinguish between a dog and a cat:\n\nThere are brown dogs. And there are brown cats.\nThere are black dogs. And there are black cats.\nAnd certainly a dog and cat could appear in the same environment (such as a house, park, beach, etc.) where the background color distributions are similar.\nBecause of this, utilizing strictly color is not a great choice for characterizing the difference between dogs and cats — but that’s okay. The purpose of this blog post was simply to introduce the concept of image classification using the k-NN algorithm.\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"testDataset = \"../working/test1\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize the raw pixel intensities matrix, the features matrix, and labels list\ntestPaths = list(paths.list_images(testDataset))\ntestImages = []\ntestFeatures = []\n# testLabels = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loop over the input images\nfor (i, imagePath) in enumerate(testPaths):\n\t# load the image and extract the class label (assuming that our\n\t# path as the format: /path/to/dataset/{class}.{image_num}.jpg\n\timage = cv2.imread(imagePath)\n# \tlabel = imagePath.split(os.path.sep)[-1].split(\".\")[0]\n    \n\t# extract raw pixel intensity \"features\", followed by a color\n\t# histogram to characterize the color distribution of the pixels\n\t# in the image\n\tpixels = image_to_feature_vector(image)\n\thist = extract_color_histogram(image)\n    \n\t# update the raw images, features, and labels matricies, respectively\n\ttestImages.append(pixels)\n\ttestFeatures.append(hist)\n# \ttestLabels.append(label)\n    \n\t# show an update every 1,000 images\n\tif i > 0 and i % 1000 == 0:\n\t\tprint(\"[INFO] processed {}/{}\".format(i, len(testPaths)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = model.predict(testFeatures)\npred = np.array([0 if x == \"dog\" else 1 for x in pred ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}