利用的是opencv中的dnn模块进行调用的,之所以标题是对jpg的图片进行分类,主要的原因是我对bmp格式的图片分类还没有成功,成功之后再更新,
使用比较常用的花卉分类图片进行分类,因为只是为了实验,并没有对图片分类精度进行追求,代码中有许多问题,比如有很多没用的,也没有删掉,也只是对花进行了二分类
对这两种花进行二分类,daisy标签为0 dandelion为1
首先进行分类,分类使用python3.5+tensorflow-gpu1.4.0+ubuntu16.04
整个过程有3个py文件,input_data.py是对图片的读取处理
train_model.py是进行训练 t_model.py是在python中测试图片
input_data.py文件
import input_data
#from tensorflow.python.framework import graph_util
from skimage import io, transform
import glob
import os
import tensorflow as tf
import numpy as np
import time
NG_path='/home/dyf/PycharmProjects/classifer_flower/flower_photos/daisy/'
OK_path='/home/dyf/PycharmProjects/classifer_flower/flower_photos/dandelion/'
#读取图片
def _dense_to_one_hot(labels_dense, num_classes):
"""Convert class labels from scalars to one-hot vectors."""
num_labels = labels_dense.shape[0]
index_offset = np.arange(num_labels) * num_classes
labels_one_hot = np.zeros((num_labels, num_classes))
labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
return labels_one_hot
#读取图片
def read_img():
imgs = []
label = []
#for k in range(1,10):
#path1= os.path.join(os.path.abspath(NG_path), '1'+format(str(k)))
#path2=os.path.join(os.path.abspath(labels_path), 'NG'+format(str(k)+'.txt'))
piclist = os.listdir(NG_path)
for pic in piclist:
if pic.endswith(".jpg"):
old_path = os.path.join(os.path.abspath(NG_path), pic)
img=io.imread(old_path)
img=transform.resize(img,(500,500))
#print(img)
# img=img.reshape(100,100,3)
imgs.append(img)
label.append(0);
piclist = os.listdir(OK_path)
for pic in piclist:
if pic.endswith(".jpg"):
old_path = os.path.join(os.path.abspath(OK_path), pic)
img = io.imread(old_path)
img = transform.resize(img, (500, 500))
# img=img.reshape(100,100,3)
imgs.append(img)
label.append(1);
# for i in range(2180):
# new_path = os.path.join(os.path.abspath(OK_path), '1(' + format(str(i + 1)) + ').bmp')
#
# img = io.imread(new_path)
# img = transform.resize(img, (100, 100))
# #img=img.reshape(100, 100, 3)
# imgs.append(img)
# label.append(1);
# #labels.append(idx)
return np.asarray(imgs, np.float32), np.asarray(label, np.int32)
def train_test_split(ratio):
data, label = read_img()
#print(data.shape)
print(data.shape)
# data = np.array(data).reshape(-1, 200, 200,3);
# print(data.shape)
#打乱顺序
num_example=data.shape[0]
arr=np.arange(num_example)
np.random.shuffle(arr)
data=data[arr]
label=label[arr]
label=_dense_to_one_hot(label,2)
#将所有数据分为训练集和验证集
ratio=0.8
s=np.int(num_example*ratio)
x_train=data[:s]
y_train=label[:s]
x_test=data[s:]
y_test=label[s:]
return x_train,x_test,y_train,y_test
#定义一个函数,按批次取数据
def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
assert len(inputs) == len(targets)
if shuffle:
indices = np.arange(len(inputs))
np.random.shuffle(indices)
for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
if shuffle:
excerpt = indices[start_idx:start_idx + batch_size]
else:
excerpt = slice(start_idx, start_idx + batch_size)
yield inputs[excerpt], targets[excerpt]
def _test():
x_train,x_test,y_train,y_test = train_test_split(0.8)
print("dataset.train.images.shape:", x_train.shape)
print("dataset.train.labels.shape:", y_train.shape)
print("dataset.test.images.shape:", x_test.shape)
print("dataset.test.labels.shape:",y_test.shape)
train_model.py
import input_data
from tensorflow.python.framework import graph_util
import tensorflow as tf
def build_network(height, width):
"""
Function:构建网络模型。
Parameters
----------
height: Mnist图像的宽。
width: Mnist图像的宽。
"""
x = tf.placeholder(tf.float32, [None, 500, 500,3], name='input')
y_placeholder = tf.placeholder(tf.float32, shape=[None,2], name='labels_placeholder')
#keep_prob_placeholder = tf.placeholder(tf.float32, name='keep_prob_placeholder')
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
#x_image = tf.reshape(x, [-1, height, width, 3])
# First Convolutional Layer
W_conv1 = weight_variable([5, 5, 3, 16])
b_conv1 = bias_variable([16])
h_conv1 = tf.nn.relu(conv2d(x, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
# Second Convolutional Layer
W_conv2 = weight_variable([5, 5, 16, 32])
b_conv2 = bias_variable([32])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
# #
W_conv3 = weight_variable([5, 5, 32, 64])
b_conv3 = bias_variable([64])
h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)
h_pool3 = max_pool_2x2(h_conv3)
W_conv4 = weight_variable([5, 5, 64, 128])
b_conv4 = bias_variable([128])
h_conv4 = tf.nn.relu(conv2d(h_pool3, W_conv4) + b_conv4)
h_pool4 = max_pool_2x2(h_conv4)
W_conv5 = weight_variable([5, 5, 128, 256])
b_conv5 = bias_variable([256])
h_conv5 = tf.nn.relu(conv2d(h_pool4, W_conv5) + b_conv5)
h_pool5 = max_pool_2x2(h_conv5)
W_conv6 = weight_variable([5, 5, 256, 512])
b_conv6 = bias_variable([512])
h_conv6 = tf.nn.relu(conv2d(h_pool5, W_conv6) + b_conv6)
h_pool6 = max_pool_2x2(h_conv6)
# #
# W_conv3 = weight_variable([5, 5, 64, 128])
# b_conv3 = bias_variable([128])
#
# h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)
# h_pool3 = max_pool_2x2(h_conv3)
#
# W_conv4 = weight_variable([5, 5,128, 256])
# b_conv4 = bias_variable([256])
#
# h_conv4 = tf.nn.relu(conv2d(h_pool3, W_conv4) + b_conv4)
# h_pool4 = max_pool_2x2(h_conv4)
# Densely Connected Layer
W_fc1 = weight_variable([7 * 7 * 512,2])
b_fc1 = bias_variable([2])
h_pool4_flat = tf.reshape(h_pool6, [-1, 7* 7 * 512])
# h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
#
# # Dropout
# h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob_placeholder)
#
# # Readout Layer
# W_fc2 = weight_variable([64, 2])
# b_fc2 = bias_variable([2])
logits = tf.matmul(h_pool4_flat, W_fc1) + b_fc1
sofmax_out = tf.nn.softmax(logits, name="out_softmax")
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_placeholder))
optimize = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)
prediction_labels = tf.argmax(sofmax_out, axis=1)
real_labels = tf.argmax(y_placeholder, axis=1)
correct_prediction = tf.equal(prediction_labels, real_labels)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 一个Batch中预测正确的次数
correct_times_in_batch = tf.reduce_sum(tf.cast(correct_prediction, tf.int32))
return dict(
#keep_prob_placeholder=keep_prob_placeholder,
x_placeholder=x,
y_placeholder=y_placeholder,
optimize=optimize,
logits=logits,
prediction_labels=prediction_labels,
real_labels=real_labels,
correct_prediction=correct_prediction,
correct_times_in_batch=correct_times_in_batch,
cost=cost,
accuracy=accuracy,
)
def train_network(graph,
batch_size,
num_epochs,
pb_file_path, ):
"""
Function:训练网络。
Parameters
----------
graph: 一个dict,build_network函数的返回值。
dataset: 数据集
batch_size:
num_epochs: 训练轮数。
pb_file_path:要生成的pb文件的存放路径。
"""
x_train,x_test,y_train,y_test=input_data.train_test_split(0.8)
config = tf.ConfigProto(allow_soft_placement=True)
tf.GPUOptions(per_process_gpu_memory_fraction=0.9)
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
sess.run(tf.global_variables_initializer())
print("batch size:", batch_size)
# 用于控制每epoch_delta轮在train set和test set上计算一下accuracy和cost
epoch_delta = 2
for epoch_index in range(num_epochs):
#################################
# 获取TRAIN set,开始训练网络
#################################
for (batch_xs, batch_ys) in input_data.minibatches(x_train,y_train,batch_size,shuffle=True):
sess.run([graph['optimize']], feed_dict={
graph['x_placeholder']: batch_xs,
graph['y_placeholder']: batch_ys,
#graph['keep_prob_placeholder']: 0.5,
})
# 每epoch_delta轮在train set和test set上计算一下accuracy和cost
if epoch_index % epoch_delta == 0:
#################################
# 开始在 train set上计算一下accuracy和cost
#################################
# 记录训练集中有多少个batch
total_batches_in_train_set = 0
# 记录在训练集中预测正确的次数
total_correct_times_in_train_set = 0
# 记录在训练集中的总cost
total_cost_in_train_set = 0.
for (train_batch_xs, train_batch_ys) in input_data.minibatches(x_train, y_train, batch_size, shuffle=True):
return_correct_times_in_batch = sess.run(graph['correct_times_in_batch'], feed_dict={
graph['x_placeholder']: train_batch_xs,
graph['y_placeholder']: train_batch_ys,
#graph['keep_prob_placeholder']: 1.0,
})
mean_cost_in_batch = sess.run(graph['cost'], feed_dict={
graph['x_placeholder']: train_batch_xs,
graph['y_placeholder']: train_batch_ys,
#graph['keep_prob_placeholder']: 1.0,
})
total_batches_in_train_set += 1
total_correct_times_in_train_set += return_correct_times_in_batch
total_cost_in_train_set += (mean_cost_in_batch * batch_size)
#################################
# 开始在 test set上计算一下accuracy和cost
#################################
# 记录测试集中有多少个batch
total_batches_in_test_set = 0
# 记录在测试集中预测正确的次数
total_correct_times_in_test_set = 0
# 记录在测试集中的总cost
total_cost_in_test_set = 0.
for (test_batch_xs, test_batch_ys) in input_data.minibatches(x_test, y_test, batch_size, shuffle=False):
return_correct_times_in_batch = sess.run(graph['correct_times_in_batch'], feed_dict={
graph['x_placeholder']: test_batch_xs,
graph['y_placeholder']: test_batch_ys,
#graph['keep_prob_placeholder']: 1.0,
})
mean_cost_in_batch = sess.run(graph['cost'], feed_dict={
graph['x_placeholder']: test_batch_xs,
graph['y_placeholder']: test_batch_ys,
#graph['keep_prob_placeholder']: 1.0,
})
total_batches_in_test_set += 1
total_correct_times_in_test_set += return_correct_times_in_batch
total_cost_in_test_set += (mean_cost_in_batch * batch_size)
### summary and print
acy_on_test = total_correct_times_in_test_set / float(total_batches_in_test_set * batch_size)
acy_on_train = total_correct_times_in_train_set / float(total_batches_in_train_set * batch_size)
print(
'Epoch - {:2d} , acy_on_test:{:6.2f}%({}/{}),loss_on_test:{:6.2f}, acy_on_train:{:6.2f}%({}/{}),loss_on_train:{:6.2f}'.
format(epoch_index, acy_on_test * 100.0, total_correct_times_in_test_set,
total_batches_in_test_set * batch_size, total_cost_in_test_set, acy_on_train * 100.0,
total_correct_times_in_train_set, total_batches_in_train_set * batch_size,
total_cost_in_train_set))
# 每轮训练完后就保存为pb文件
constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ["out_softmax"]) # out_softmax
with tf.gfile.FastGFile(pb_file_path, mode='wb') as f:
f.write(constant_graph.SerializeToString())
def main():
batch_size = 20
num_epochs =10
# pb文件保存路径
pb_file_path = "/home/dyf/PycharmProjects/classifer_flower/output/model.pb"
g = build_network(height=500, width=500)
train_network(g, batch_size, num_epochs, pb_file_path)
main()
t_model.py
import tensorflow as tf
import numpy as np
import PIL.Image as Image
from skimage import io, transform
import os
path1="/home/dyf/PycharmProjects/classifer_flower/flower_photos/test/daisy/"
path2="/home/dyf/PycharmProjects/classifer_flower/flower_photos/test/denlian/"
def read_img():
imgs = []
# for k in range(1,10):
# path1= os.path.join(os.path.abspath(NG_path), '1'+format(str(k)))
# path2=os.path.join(os.path.abspath(labels_path), 'NG'+format(str(k)+'.txt'))
piclist = os.listdir(path1)
for pic in piclist:
if pic.endswith(".jpg"):
old_path = os.path.join(os.path.abspath(path1), pic)
img = io.imread(old_path)
img = transform.resize(img, (500, 500))
# img=img.reshape(100,100,3)
imgs.append(img)
piclist = os.listdir(path2)
for pic in piclist:
if pic.endswith(".jpg"):
old_path = os.path.join(os.path.abspath(path2), pic)
img = io.imread(old_path)
img = transform.resize(img, (500, 500))
# img=img.reshape(100,100,3)
imgs.append(img)
# label.append(0);
return np.asarray(imgs, np.float32)
def recognize(png_path, pb_file_path):
"""
Function:使用训练完的网络模型进行预测。
Parameters
----------
png_path:要预测的图片的路径。
pb_file_path: pb文件的路径。
"""
imgs=[]
with tf.Graph().as_default():
output_graph_def = tf.GraphDef()
with open(pb_file_path, "rb") as f:
output_graph_def.ParseFromString(f.read()) # rb
_ = tf.import_graph_def(output_graph_def, name="")
config = tf.ConfigProto(allow_soft_placement=True)
tf.GPUOptions(per_process_gpu_memory_fraction=0.9)
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
tf.global_variables_initializer().run()
input_x = sess.graph.get_tensor_by_name("input:0")
print(input_x)
out_softmax = sess.graph.get_tensor_by_name("out_softmax:0")
print(out_softmax)
# keep_prob = sess.graph.get_tensor_by_name("keep_prob_placeholder:0")
# print(keep_prob)
# out_label = sess.graph.get_tensor_by_name("output:0")
# print(out_label)
#img_datas = np.array(Image.open(png_path).convert('L'))
#img_datas = np.array(Image.open(png_path))
#new_path = os.path.join(os.path.abspath(NG_path), '1 (' + format(str(i + 1)) + ').bmp')
imgs = read_img()
#imgs = np.array(imgs).reshape(-1, 200, 200, 3);
# data = np.multiply(imgs, 1.0 / 255.0)
img_out_softmax = sess.run(out_softmax, feed_dict={
input_x: imgs,
# keep_prob: 1.0,
})
c = 0.0
for i in range(13):
prediction_label = np.argmax(img_out_softmax[i].reshape(1,2,1), axis=1)
print(img_out_softmax[i])
if prediction_label[0] == 0:
c = c + 1
#print(prediction_label[0])
for i in range(13, 22):
prediction_label = np.argmax(img_out_softmax[i].reshape(1,2,1), axis=1)
print(img_out_softmax[i])
#print(img_out_softmax[i].reshape(1,2,1))
if prediction_label[0] == 1:
c = c + 1
print(prediction_label[0])
print("acc:", c / 22)
recognize("/home/dyf/PycharmProjects/classifer_flower/flower_photos/test/",
"/home/dyf/PycharmProjects/classifer_flower/output/model.pb")
使用opencv调用pb模型,该代码参考了网上的代码,具体的网址现在想找又没有找到
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace cv::dnn;
using namespace std;
//自己新建一个txt文件,写入分类的标签(一行写一个标签,例如二分类)
String labels_txt_file = "/home/dyf/Documents/数字图像处理/opencv/pb/graph.txt";
String tf_pb_file = "/home/dyf/Documents/数字图像处理/opencv/pb/model.pb";
String picture="/home/dyf/Documents/数字图像处理/opencv/pb/test/daisy/5794839_200acd910c_n.jpg";
vector readClassNames();
int main()
{
Mat src = imread(picture);
int w = 500;
int h = 500;
Net net = readNetFromTensorflow(tf_pb_file);
if (net.empty()) {
cout << "error:no model" << endl;
}
Mat inputBlob = blobFromImage(src, 1.0/255. , Size(w, h), Scalar(), true, false);
vector labels = readClassNames();
//执行图像分类
Mat prob;
net.setInput(inputBlob, "input");
prob = net.forward("out_softmax");
cout << prob << endl;
Mat probMat = prob.reshape(1, 1);
Point classNumber;
double classProb;
minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber);
int classidx = classNumber.x;
cout << classidx << endl;
cout<<"分类结果为:"<readClassNames()
{
vector classNames;
fstream fp(labels_txt_file);
if (!fp.is_open())
{
cout << "does not open"<
执行效果如下:
https://download.csdn.net/download/u013263891/10849045
包括图片我已经上传到这个资源,图片数据在网上也是可以免费下载到了,如果想更方便一点儿 从这下载就可以了,代码应该是可以直接运行的,windows下可能需要稍作修改