Python构建图像分类识别器的方法


Posted in Python onJanuary 12, 2019

机器学习用在图像识别是非常有趣的话题。

我们可以利用OpenCV强大的功能结合机器学习算法实现图像识别系统。

首先,输入若干图像,加入分类标记。利用向量量化方法将特征点进行聚类,并得出中心点,这些中心点就是视觉码本的元素。

其次,利用图像分类器将图像分到已知的类别中,ERF(极端随机森林)算法非常流行,因为ERF具有较快的速度和比较精确的准确度。我们利用决策树进行正确决策。

最后,利用训练好的ERF模型后,创建目标识别器,可以识别未知图像的内容。

当然,这只是雏形,存在很多问题:

界面不友好。

准确率如何保证,如何调整超参数,只有认真研究算法机理,才能真正清除内部实现机制后给予改进。

下面,上代码:

import os

import sys
import argparse
import json
import cv2
import numpy as np
from sklearn.cluster import KMeans
# from star_detector import StarFeatureDetector
from sklearn.ensemble import ExtraTreesClassifier
from sklearn import preprocessing

try:
 import cPickle as pickle #python 2
except ImportError as e:
 import pickle #python 3

def load_training_data(input_folder):
 training_data = []
 if not os.path.isdir(input_folder):
  raise IOError("The folder " + input_folder + " doesn't exist")
  
 for root, dirs, files in os.walk(input_folder):
  for filename in (x for x in files if x.endswith('.jpg')):
   filepath = os.path.join(root, filename)
   print(filepath)
   object_class = filepath.split('\\')[-2]
   print("object_class",object_class)
   training_data.append({'object_class': object_class, 'image_path': filepath})
     
 return training_data
class StarFeatureDetector(object):
 def __init__(self):
  self.detector = cv2.xfeatures2d.StarDetector_create()
 def detect(self, img):
  return self.detector.detect(img)

class FeatureBuilder(object):
 def extract_features(self, img):
  keypoints = StarFeatureDetector().detect(img)
  keypoints, feature_vectors = compute_sift_features(img, keypoints)
  return feature_vectors
 def get_codewords(self, input_map, scaling_size, max_samples=12):
  keypoints_all = []
  count = 0
  cur_class = ''
  for item in input_map:
   if count >= max_samples:
    if cur_class != item['object_class']:
     count = 0
    else:
     continue
   count += 1
   if count == max_samples:
    print ("Built centroids for", item['object_class'])

   cur_class = item['object_class']
   img = cv2.imread(item['image_path'])
   img = resize_image(img, scaling_size)
   num_dims = 128
   feature_vectors = self.extract_features(img)
   keypoints_all.extend(feature_vectors)

  kmeans, centroids = BagOfWords().cluster(keypoints_all)
  return kmeans, centroids
class BagOfWords(object):
 def __init__(self, num_clusters=32):
  self.num_dims = 128
  self.num_clusters = num_clusters
  self.num_retries = 10

 def cluster(self, datapoints):
  kmeans = KMeans(self.num_clusters, 
      n_init=max(self.num_retries, 1),
      max_iter=10, tol=1.0)
  res = kmeans.fit(datapoints)
  centroids = res.cluster_centers_
  return kmeans, centroids

 def normalize(self, input_data):
  sum_input = np.sum(input_data)

  if sum_input > 0:
   return input_data / sum_input
  else:
   return input_data
 def construct_feature(self, img, kmeans, centroids):
  keypoints = StarFeatureDetector().detect(img)
  keypoints, feature_vectors = compute_sift_features(img, keypoints)
  labels = kmeans.predict(feature_vectors)
  feature_vector = np.zeros(self.num_clusters)

  for i, item in enumerate(feature_vectors):
   feature_vector[labels[i]] += 1

  feature_vector_img = np.reshape(feature_vector, ((1, feature_vector.shape[0])))
  return self.normalize(feature_vector_img)
# Extract features from the input images and 
# map them to the corresponding object classes
def get_feature_map(input_map, kmeans, centroids, scaling_size):
 feature_map = []
 for item in input_map:
  temp_dict = {}
  temp_dict['object_class'] = item['object_class']
 
  print("Extracting features for", item['image_path'])
  img = cv2.imread(item['image_path'])
  img = resize_image(img, scaling_size)

  temp_dict['feature_vector'] = BagOfWords().construct_feature(img, kmeans, centroids)
  if temp_dict['feature_vector'] is not None:
   feature_map.append(temp_dict)
 return feature_map

# Extract SIFT features
def compute_sift_features(img, keypoints):
 if img is None:
  raise TypeError('Invalid input image')

 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 keypoints, descriptors = cv2.xfeatures2d.SIFT_create().compute(img_gray, keypoints)
 return keypoints, descriptors

# Resize the shorter dimension to 'new_size' 
# while maintaining the aspect ratio
def resize_image(input_img, new_size):
 h, w = input_img.shape[:2]
 scaling_factor = new_size / float(h)

 if w < h:
  scaling_factor = new_size / float(w)

 new_shape = (int(w * scaling_factor), int(h * scaling_factor))
 return cv2.resize(input_img, new_shape)

def build_features_main():
 data_folder = 'training_images\\'
 scaling_size = 200
 codebook_file='codebook.pkl'
 feature_map_file='feature_map.pkl'
 # Load the training data
 training_data = load_training_data(data_folder)

 # Build the visual codebook
 print("====== Building visual codebook ======")
 kmeans, centroids = FeatureBuilder().get_codewords(training_data, scaling_size)
 if codebook_file:
  with open(codebook_file, 'wb') as f:
   pickle.dump((kmeans, centroids), f)
 
 # Extract features from input images
 print("\n====== Building the feature map ======")
 feature_map = get_feature_map(training_data, kmeans, centroids, scaling_size)
 if feature_map_file:
  with open(feature_map_file, 'wb') as f:
   pickle.dump(feature_map, f)
# --feature-map-file feature_map.pkl --model- file erf.pkl
#----------------------------------------------------------------------------------------------------------
class ERFTrainer(object):
 def __init__(self, X, label_words):
  self.le = preprocessing.LabelEncoder()
  self.clf = ExtraTreesClassifier(n_estimators=100,
    max_depth=16, random_state=0)

  y = self.encode_labels(label_words)
  self.clf.fit(np.asarray(X), y)

 def encode_labels(self, label_words):
  self.le.fit(label_words)
  return np.array(self.le.transform(label_words), dtype=np.float32)

 def classify(self, X):
  label_nums = self.clf.predict(np.asarray(X))
  label_words = self.le.inverse_transform([int(x) for x in label_nums])
  return label_words
#------------------------------------------------------------------------------------------

class ImageTagExtractor(object):
 def __init__(self, model_file, codebook_file):
  with open(model_file, 'rb') as f:
   self.erf = pickle.load(f)

  with open(codebook_file, 'rb') as f:
   self.kmeans, self.centroids = pickle.load(f)

 def predict(self, img, scaling_size):
  img = resize_image(img, scaling_size)
  feature_vector = BagOfWords().construct_feature(
    img, self.kmeans, self.centroids)
  image_tag = self.erf.classify(feature_vector)[0]
  return image_tag

def train_Recognizer_main():
 feature_map_file = 'feature_map.pkl'
 model_file = 'erf.pkl'
 # Load the feature map
 with open(feature_map_file, 'rb') as f:
  feature_map = pickle.load(f)
 # Extract feature vectors and the labels
 label_words = [x['object_class'] for x in feature_map]
 dim_size = feature_map[0]['feature_vector'].shape[1]
 X = [np.reshape(x['feature_vector'], (dim_size,)) for x in feature_map]

 # Train the Extremely Random Forests classifier
 erf = ERFTrainer(X, label_words)
 if model_file:
  with open(model_file, 'wb') as f:
   pickle.dump(erf, f)
 #--------------------------------------------------------------------
 # args = build_arg_parser().parse_args()
 model_file = 'erf.pkl'
 codebook_file ='codebook.pkl'
 import os
 rootdir=r"F:\airplanes"
 list=os.listdir(rootdir)
 for i in range(0,len(list)):
  path=os.path.join(rootdir,list[i])
  if os.path.isfile(path):
   try:
    print(path)
    input_image = cv2.imread(path)
    scaling_size = 200
    print("\nOutput:", ImageTagExtractor(model_file,codebook_file)\
      .predict(input_image, scaling_size))
   except:
    continue
 #-----------------------------------------------------------------------
build_features_main()
train_Recognizer_main()

以上这篇Python构建图像分类识别器的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现括号匹配的思路详解
Aug 23 Python
python 文本单词提取和词频统计的实例
Dec 22 Python
浅谈Python批处理文件夹中的txt文件
Mar 11 Python
python判断文件夹内是否存在指定后缀文件的实例
Jun 10 Python
pandas dataframe的合并实现(append, merge, concat)
Jun 24 Python
python实现最大子序和(分治+动态规划)
Jul 05 Python
python之pexpect实现自动交互的例子
Jul 25 Python
Python缓存技术实现过程详解
Sep 25 Python
Python原始套接字编程实例解析
Jan 29 Python
Python 使用生成器代替线程的方法
Aug 04 Python
python 密码学示例——理解哈希(Hash)算法
Sep 21 Python
python 利用百度API识别图片文字(多线程版)
Dec 14 Python
使用python opencv对目录下图片进行去重的方法
Jan 12 #Python
python变量赋值方法(可变与不可变)
Jan 12 #Python
python交换两个变量的值方法
Jan 12 #Python
对Pyhon实现静态变量全局变量的方法详解
Jan 11 #Python
浅谈Python中的全局锁(GIL)问题
Jan 11 #Python
Python 实现子类获取父类的类成员方法
Jan 11 #Python
python使用xlrd模块读取xlsx文件中的ip方法
Jan 11 #Python
You might like
人族 Terran 魔法与科技
2020/03/14 星际争霸
PHP生成月历代码
2007/06/14 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
jQuery Autocomplete自动完成插件
2010/07/17 Javascript
从盛大通行证上摘下来的身份证验证js代码
2011/01/11 Javascript
解析js如何获取当前url中的参数值并复制给input
2013/06/23 Javascript
JavaScript脚本判断蜘蛛来源的方法
2015/09/22 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
BootStrap的alert提示框的关闭后再显示怎么解决
2016/05/17 Javascript
用js实现放大镜的效果的简单实例
2016/05/23 Javascript
EasyUI加载完Html内容样式渲染完成后显示
2016/07/25 Javascript
js实现页面刷新滚动条位置不变
2016/11/27 Javascript
整理关于Bootstrap警示框的慕课笔记
2017/03/29 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
详解Vue.js搭建路由报错 router.map is not a function
2017/06/27 Javascript
react.js使用webpack搭配环境的入门教程
2017/08/14 Javascript
vue2.0学习之axios的封装与vuex介绍
2018/05/28 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
EXTJS7实现点击拖拉选择文本
2020/12/17 Javascript
[04:47]DOTA2-潍坊风行电子俱乐部探秘
2014/08/08 DOTA
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
python如何统计序列中元素
2020/07/31 Python
对Python生成汉字字库文字,以及转换为文字图片的实例详解
2019/01/29 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
2019/04/10 Python
Python实现平行坐标图的两种方法小结
2019/07/04 Python
pycharm 安装JPype的教程
2019/08/08 Python
Python autoescape标签用法解析
2020/01/17 Python
python os模块在系统管理中的应用
2020/06/22 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
韩国爱茉莉太平洋化妆品美国站:Amore Pacific US
2016/10/28 全球购物
即时搜索数百万张门票:SeatsForEveryone.com
2018/08/26 全球购物
Interflora澳大利亚:同日鲜花速递
2019/06/25 全球购物
大学生专科学习生活的自我评价
2013/12/07 职场文书
大二法学专业职业生涯规划范文
2014/02/12 职场文书
小学数学教研活动总结
2014/07/01 职场文书
MySQL数据库之存储过程 procedure
2022/06/16 MySQL