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网络编程学习笔记(五):socket的一些补充
Jun 09 Python
Python多线程、异步+多进程爬虫实现代码
Feb 17 Python
Python实现Linux的find命令实例分享
Jun 04 Python
Python基础学习之常见的内建函数整理
Sep 06 Python
python的变量与赋值详细分析
Nov 08 Python
理解python中生成器用法
Dec 20 Python
python实现随机森林random forest的原理及方法
Dec 21 Python
Python 实现12306登录功能实例代码
Feb 09 Python
Django框架模板文件使用及模板文件加载顺序分析
May 23 Python
Python实现最大子序和的方法示例
Jul 05 Python
Pytorch实现LSTM和GRU示例
Jan 14 Python
使用Python解决图表与画布的间距问题
Apr 11 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
杏林同学录(八)
2006/10/09 PHP
Zend Studio去除编辑器的语法警告设置方法
2012/10/24 PHP
php定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
PHP实现的堆排序算法详解
2017/08/17 PHP
PHP实现数组的笛卡尔积运算示例
2017/12/15 PHP
IE8 下的Js错误HTML Parsing Error...
2009/08/14 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
angularjs实现与服务器交互分享
2014/06/24 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
JS取数字小数点后两位或n位的简单方法
2016/10/24 Javascript
js 能实现监听F5页面刷新子iframe 而父页面不刷新的方法
2016/11/09 Javascript
jQuery模拟实现的select点击选择效果【附demo源码下载】
2016/11/09 Javascript
bootstrap模态框垂直居中效果
2016/12/03 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
新版小程序登录授权的方法
2018/12/12 Javascript
jQuery中实现text()的方法
2019/04/04 jQuery
javascript事件监听与事件委托实例详解
2019/08/16 Javascript
Python中的闭包详细介绍和实例
2014/11/21 Python
python获取元素在数组中索引号的方法
2015/07/15 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
2019/09/11 Python
基于Python实现签到脚本过程解析
2019/10/25 Python
基于python3 的百度图片下载器的实现代码
2019/11/05 Python
python argparse模块通过后台传递参数实例
2020/04/20 Python
美国最好的保健品打折网店:Swanson
2017/08/04 全球购物
物流仓储实习自我鉴定
2013/09/25 职场文书
党委书记岗位职责
2013/11/24 职场文书
学术会议邀请函范文
2014/01/22 职场文书
会计工作决心书
2014/03/11 职场文书
鸿星尔克广告词
2014/03/21 职场文书
节能减排倡议书
2014/04/15 职场文书
篮球赛口号
2014/06/18 职场文书
公司承诺函范文
2015/01/21 职场文书
SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理
2022/06/21 Java/Android