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 相关文章推荐
关于pip的安装,更新,卸载模块以及使用方法(详解)
May 19 Python
Python中扩展包的安装方法详解
Jun 14 Python
Python 删除连续出现的指定字符的实例
Jun 29 Python
对python读取CT医学图像的实例详解
Jan 24 Python
详解Python sys.argv使用方法
May 10 Python
python try except返回异常的信息字符串代码实例
Aug 15 Python
python pillow模块使用方法详解
Aug 30 Python
Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法
Sep 17 Python
Python3实现二叉树的最大深度
Sep 30 Python
python读取hdfs上的parquet文件方式
Jun 06 Python
python中用ggplot绘制画图实例讲解
Jan 26 Python
Python创建SQL数据库流程逐步讲解
Sep 23 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
在MongoDB中模拟Auto Increment的php代码
2011/03/06 PHP
php ci框架中加载css和js文件失败的原因及解决方法
2014/07/29 PHP
PHP中使用strpos函数实现屏蔽敏感关键字功能
2014/08/21 PHP
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
2007/08/15 Javascript
最简单的jQuery程序 入门者学习
2009/07/09 Javascript
jquery中防刷IP流量软件影响统计的一点对策
2011/07/10 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
2012/05/23 Javascript
Extjs4 GridPanel的主要配置参数详细介绍
2013/04/18 Javascript
JavaScript实现动态创建CSS样式规则方案
2014/09/06 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
html判断当前页面是否在iframe中的实例
2016/11/30 Javascript
js精确的加减乘除实例
2017/11/14 Javascript
利用JS判断客户端类型你应该知道的四种方法
2017/12/22 Javascript
Vue入门之animate过渡动画效果
2018/04/08 Javascript
JS实现字符串中去除指定子字符串方法分析
2018/05/17 Javascript
layui实现点击按钮给table添加一行
2018/08/10 Javascript
vue-cli在 history模式下的配置详解
2019/11/26 Javascript
JavaScript回调函数callback用法解析
2020/01/14 Javascript
Python脚本实现下载合并SAE日志
2015/02/10 Python
jupyter notebook引用from pyecharts.charts import Bar运行报错
2020/04/23 Python
解决Django生产环境无法加载静态文件问题的解决
2019/04/23 Python
Django处理Ajax发送的Get请求代码详解
2019/07/29 Python
Django发送邮件功能实例详解
2019/09/02 Python
Python3实现将一维数组按标准长度分隔为二维数组
2019/11/29 Python
如何基于python实现画不同品种的樱花树
2020/01/03 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
解决Pycharm双击图标启动不了的问题(JetBrains全家桶通用)
2020/08/07 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
2020/08/17 Python
html5中canvas图表实现柱状图的示例
2017/11/13 HTML / CSS
初中生自我鉴定
2014/02/04 职场文书
客户答谢会活动方案
2014/08/31 职场文书
法制演讲稿
2014/09/10 职场文书
入党现实表现材料
2014/12/23 职场文书
优秀教研组申报材料
2014/12/26 职场文书
《为人民服务》教学反思
2016/02/20 职场文书