{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第10章 图像分类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在前面的章节中，我们学会了滤波并在此基础上实现了模板匹配、边缘检测等一系列后续处理方法；当我们学习完如何检测图像中的角点等特征点之后，我们又进一步学习了SIFT算法，并利用SIFT实现图像拼接。至此，我们已经完整的学习了图像处理的基础知识。接下来，我们将在这些知识的基础上，学习更高阶的计算机视觉——图像语义理解部分。\n",
    "\n",
    "我们将学习....。（第二大章序）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 10.1 简介"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "图像分类是计算机视觉中一个非常重要的任务，它是指给定一张图像，根据图像信息反映的特征为其赋予一个合适的标签，而标签可以来自于预定义的标签集合。虽然从人的视角出发，我们可以很轻松的攫取一张图像的视觉内容并赋予它一个合适的标签，但是，想要让计算机理解并解释一张图像的内容是很一件非常困难的事情，因为计算机看到的图像是一个巨大的数字矩阵，而并不是直观的内容。因此，如何从一张图像中抽取具有语义信息的特征是图像分类首先需要解决的问题。\n",
    "\n",
    "幸运的是，利用SIFT算法从一张图像提取的特征具有充分的语义信息。因此，我们可以利用SIFT提取的特征来进行后续的图像分类，而BOF（Bag of Features）算法便是一个典型的范例。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 10.2 Bag of Features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Bag of Features (BOF)是一种用于图像或视频检索的技术。它借鉴了文本分类的思路（BOW），从图像抽象出很多具有代表性的特征并形成一个字典，再统计每张图像中出现的特征数量，从而得到该图像的特征向量。特征必须具有较高的区分度，而且要满足旋转不变性以及尺寸不变性等，因此，我们通常都会采用SIFT提取特征。SIFT会从图像上提取出很多特征点，每个特征点都是一个128维的向量，当图像足够多时，我们便会提取出一个巨大的特征向量库。提取完特征后，我们会采用一些聚类算法如K-means等对这些特征向量进行聚类，最后得到的k个聚类中心构成的集合称为字典，其中每一个聚类中心被称为visual word。在此之后，为了这一步对图像特征进行量化我们将根据字典重新提取图像的高层特征。具体而言体，对于图像中的每一个SIFT特征，我们可以在字典中找到一个最相似的visual word（即找到该特征对应的聚类中心），并统计一个 k 维的直方图，代表该图像的「SIFT」特征在字典中的相似度频率。至此，一张图像的特征向量便可以通过该直方图进行表示。最后，我们再训练一个常见的分类器模型如SVM等将图像进行分类即可。我们接下来将动手编写实现BOF。\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "[]\n"
     ]
    },
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn [12], line 20\u001b[0m\n\u001b[1;32m     18\u001b[0m \u001b[38;5;66;03m#生成词汇\u001b[39;00m\n\u001b[1;32m     19\u001b[0m voc \u001b[38;5;241m=\u001b[39m vocabulary\u001b[38;5;241m.\u001b[39mVocabulary(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mukbenchtest\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m---> 20\u001b[0m \u001b[43mvoc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatlist\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1000\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m     21\u001b[0m \u001b[38;5;66;03m#保存词汇\u001b[39;00m\n\u001b[1;32m     22\u001b[0m \u001b[38;5;66;03m# saving vocabulary\u001b[39;00m\n\u001b[1;32m     23\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mH:\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mPych\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124m图像检索\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124m统一大杂烩/vocabulary.pkl\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mwb\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m f:\n",
      "File \u001b[0;32m~/Material/Doctor/写书/notebook/第10章 图像分类/PCV/imagesearch/vocabulary.py:24\u001b[0m, in \u001b[0;36mVocabulary.train\u001b[0;34m(self, featurefiles, k, subsampling)\u001b[0m\n\u001b[1;32m     22\u001b[0m \u001b[38;5;66;03m# read the features from file\u001b[39;00m\n\u001b[1;32m     23\u001b[0m descr \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m---> 24\u001b[0m descr\u001b[38;5;241m.\u001b[39mappend(sift\u001b[38;5;241m.\u001b[39mread_features_from_file(\u001b[43mfeaturefiles\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m)[\u001b[38;5;241m1\u001b[39m])\n\u001b[1;32m     25\u001b[0m descriptors \u001b[38;5;241m=\u001b[39m descr[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;66;03m#stack all features for k-means\u001b[39;00m\n\u001b[1;32m     26\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m arange(\u001b[38;5;241m1\u001b[39m,nbr_images):\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "import pickle\n",
    "from PCV.imagesearch import vocabulary\n",
    "from PCV.tools.imtools import get_imlist\n",
    "from PCV.localdescriptors import sift\n",
    "print(0)\n",
    "#获取图像列表\n",
    "imlist = get_imlist('caltech-101')\n",
    "nbr_images = len(imlist)\n",
    "print(imlist)\n",
    "#获取特征列表\n",
    "featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]\n",
    "\n",
    "#提取文件夹下图像的sift特征\n",
    "for i in range(nbr_images):\n",
    "    sift.process_image(imlist[i], featlist[i])\n",
    "\n",
    "#生成词汇\n",
    "voc = vocabulary.Vocabulary('ukbenchtest')\n",
    "voc.train(featlist, 1000, 10)\n",
    "#保存词汇\n",
    "# saving vocabulary\n",
    "with open('H:\\Pych\\图像检索\\统一大杂烩/vocabulary.pkl', 'wb') as f:\n",
    "    pickle.dump(voc, f)\n",
    "print('vocabulary is:', voc.name, voc.nbr_words)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
