extract the sites from XML
Presumably, this part was the same as what it did in my last week’s blog.
import xml.dom.minidom
import numpy as np
import os
path = r'C:\Users\ghx\Desktop\pycharm_codes\Annotations\.idea\.idea\inspectionProfiles'
num_xml = len(os.listdir(path)) - 2
k = 0
def get_XY(filename):
if os.path.exists(filename):
dom = xml.dom.minidom.parse(filename)
# 得到文档元素对象
root = dom.documentElement
X_min = root.getElementsByTagName('xmin')
X_max = root.getElementsByTagName('xmax')
Y_min = root.getElementsByTagName('ymin')
Y_max = root.getElementsByTagName('ymax')
#print(len(X_min))
if (len(X_min))==0:
#print("%s%s" % ('no fire in ', filename))
return np.array([1])
for n in range(len(X_min)):
if n==0:
XY = [[X_min[n].firstChild.data, X_max[n].firstChild.data,
Y_min[n].firstChild.data, Y_max[n].firstChild.data]]
else:
XY = np.vstack((XY, [X_min[n].firstChild.data, X_max[n].firstChild.data,
Y_min[n].firstChild.data, Y_max[n].firstChild.data]))
#print(XY)
return np.array(XY)
else:
#print("%s%s" % ('no fire in ',filename))
return np.array([1])
k=0
m=0
for i in range(3181):
I = '%d' %(i+1)
I_xml="%s%s" % (I,'.xml')
filename="%s%s" % ('fire_', I_xml)
get_XY(filename)
if (get_XY(filename)) == 1:
m = m + 1
continue
elif i==0:
m = m + 1
XY = get_XY('fire_1.xml')
label = np.array([[1, XY.shape[0], 0, 0]])
XYall = np.vstack((label, XY))
else:
m = m + 1
XY = get_XY(filename)
label = np.array([[m, XY.shape[0], 0, 0]])
XYall = np.vstack((XYall, np.vstack((label,XY))))
XYall = np.array(XYall, dtype='int16')
np.save("a.npy",XYall)
Preprocess on the pictures
Use the extracted sites of fire flames and the nearby none fire area to form our dataset(jpg.)
import cv2
import numpy as np
import os
import matplotlib.pyplot as plt
import matplotlib.image as mp
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
print('x' in np.arange(5)) #returns False, without Warning
os.chdir( r'C:\Users\ghx\Desktop\pycharm_codes\Annotations\.idea\.idea\inspectionProfiles')
a=np.load("a.npy")
N = 0
M = 0
DST0=[]
for j in range(len(a)):
if a[j][2]==0 and a[j][3]==0:
N = N + 1
m=a[j][0]
n=a[j][1]
I = '%d' %(m)
I_jpg ="%s%s" % (I,'.jpg')
filename = "%s%s" % ('fire_', I_jpg)
os.chdir(r'C:\Users\ghx\Desktop\pycharm_codes\Annotations\.idea\.idea\inspectionProfiles')
img1 = cv2.imread(filename, 1)
sites = a[j+1:j+n+1][:]
else:
continue
for k in range(n):
img_fire = img1[sites[k][2]: sites[k][3],sites[k][0]: sites[k][1]]
M = M + 1
imgInfo = img_fire.shape
h = imgInfo[0]
w = imgInfo[1]
if sites[k][2]-101>0:
img_nofire = img1[sites[k][2] - 100: sites[k][2], sites[k][0]: sites[k][1]]
elif sites[k][3]+101<h:
img_nofire = img1[sites[k][3]: sites[k][2] + 100, sites[k][0]: sites[k][1]]
elif sites[k][1]+101<w:
img_nofire = img1[sites[k][2]: sites[k][3], sites[k][1]: sites[k][1] + 100]
elif sites[k][0]-101>0:
img_nofire = img1[sites[k][2]: sites[k][3], sites[k][0] - 100: sites[k][0]]
else:
img_nofire = np.zeros((100 , 100 , 3),dtype='float32')
W = 100
H = 100
dst_fire = cv2.resize(img_fire, (W, H))
filename_onlyfi = "%s%s" % ("%s%s" % ('fire_only', '%d' % (M)), '.jpg')
os.chdir(r'C:\whether_fire\fire')
dst_fire = dst_fire[:, :, [2, 1, 0]]
mp.imsave(filename_onlyfi, dst_fire)
dst_nofi = cv2.resize(img_nofire, (W, H))
filename_nonfire = "%s%s" % ("%s%s" % ('nonfire', '%d' % (N)), '.jpg')
os.chdir(r'C:\whether_fire\nofire')
dst_nofi = dst_nofi[:, :, [2, 1, 0]]
mp.imsave(filename_nonfire, dst_nofi)
None fire groups
Fire only groups
##Improvement about CNN
Unlike the codes used last week, I quote the function to feed my dictionary in the certain scale of a batch. In doing so, the efficiency of CNN has been promoted a lot.
Attention!!!
This training process was extremely time-soncuming, make sure you can debug this code step-by-step in a Python console.
(一步一步的在调试台运行,不然一报错就哭了)
And I just finished such process for 3 times to change my parameters. Otherwise, I can get a more precise outcome I guess.
from skimage import io, transform
import glob
import os
import tensorflow as tf
import numpy as np
import time
import cv2
path = r'C:\whether_fire'
os.chdir(path)
# 将所有的图片resize成100*100
w = 100
h = 100
c = 3
# 读取图片
def read_img(path):
cate = ['fire','nofire']
imgs = []
labels = []
for idx, folder in enumerate(cate):
for im in glob.glob(folder + '/*.jpg'):
#print('reading the images:%s' % (im))
img = io.imread(im)
img = transform.resize(img, (w, h))
imgs.append(img)
labels.append(idx)
return np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
data, label = read_img(path)
# 打乱顺序
num_example = data.shape[0]
arr = np.arange(num_example)
np.random.shuffle(arr)
data = data[arr]
label = label[arr]
# 将所有数据分为训练集和验证集
ratio = 0.8
s = np.int(num_example * ratio)
x_train = data[:s]
y_train = label[:s]
x_val = data[s:]
y_val = label[s:]
# -----------------构建网络----------------------
# 占位符
x = tf.placeholder(tf.float32, shape=[None, w, h, c], name='x')
y_ = tf.placeholder(tf.int32, shape=[None, ], name='y_')
# 第一个卷积层(100——>50)
conv1 = tf.layers.conv2d(
inputs=x,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
# 第二个卷积层(50->25)
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=64,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
# 第三个卷积层(25->12)
conv3 = tf.layers.conv2d(
inputs=pool2,
filters=128,
kernel_size=[3, 3],
padding="same",
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool3 = tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2)
# 第四个卷积层(12->6)
conv4 = tf.layers.conv2d(
inputs=pool3,
filters=128,
kernel_size=[3, 3],
padding="same",
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool4 = tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2)
re1 = tf.reshape(pool4, [-1, 6 * 6 * 128])
# 全连接层
dense1 = tf.layers.dense(inputs=re1,
units=1024,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
dense2 = tf.layers.dense(inputs=dense1,
units=512,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
logits = tf.layers.dense(inputs=dense2,
units=2,
activation=None,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
# ---------------------------网络结束---------------------------
loss = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=logits)
train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(tf.abs(logits), 1), tf.int32), y_)
acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 定义一个函数,按批次取数据
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]
# 训练和测试数据,可将n_epoch设置更大一些
n_epoch = 12
batch_size = 64
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
for epoch in range(n_epoch):
start_time = time.time()
# training
train_loss, train_acc, n_batch = 0, 0, 0
for x_train_a, y_train_a in minibatches(x_train, y_train, batch_size, shuffle=True):
_, err, ac = sess.run([train_op, loss, acc], feed_dict={x: x_train_a, y_: y_train_a})
train_loss += err;
train_acc += ac;
n_batch += 1
print(" train loss: %f" % (train_loss / n_batch))
print(" train acc: %f" % (train_acc / n_batch))
# validation
val_loss, val_acc, n_batch = 0, 0, 0
for x_val_a, y_val_a in minibatches(x_val, y_val, batch_size, shuffle=False):
err, ac = sess.run([loss, acc], feed_dict={x: x_val_a, y_: y_val_a})
val_loss += err;
val_acc += ac;
n_batch += 1
print(" validation loss: %f" % (val_loss / n_batch))
print(" validation acc: %f" % (val_acc / n_batch))
os.chdir(r'C:\Users\ghx\Desktop\pycharm_codes\Annotations\.idea\.idea\inspectionProfiles')
img_test = io.imread("fire_72.jpg")
row = int(img_test.shape[0]/100)
col = int(img_test.shape[1]/100)
for i in range(col):
for j in range(row):
test = np.asarray([transform.resize(img_test[(100 * j + 0):(100 * j + 100), (100 * i + 0):(100 * i + 100), 0:3], (w, h))],np.float32)
#print(sess.run(tf.abs(logits), feed_dict={x: test, y_:np.asarray([0]) }))
err, ac = sess.run([loss, acc], feed_dict={x: test, y_: np.asarray([0])})
ACT = ac
if ACT <=1.0:
img_test[100 * j + 1, 100 * i + 1:100 * i + 99] = (0,255,0)
img_test[100 * j + 99, 100 * i + 1:100 * i + 99] = (0,255,0)
img_test[100 * j + 1:100 * j + 99, 100 * i + 1] = (0,255,0)
img_test[100 * j + 1:100 * j + 99, 100 * i + 99] = (0,255,0)
else:
img_test[100 * j + 1, 100 * i + 1:100 * i + 99] = (255,0,0)
img_test[100 * j + 99, 100 * i + 1:100 * i + 99] = (255,0,0)
img_test[100 * j + 1:100 * j + 99, 100 * i + 1] = (255,0,0)
img_test[100 * j + 1:100 * j + 99, 100 * i + 99] = (255,0,0)
img_test = img_test[:, :, [2, 1, 0]]
cv2.imshow('image_test',img_test)
cv2.waitKey(0)
Here comes my training process:
the final results of fire recognise by CNN
The green frames cover the areas with flames while the red frames cover the non fire area:
However, it seems that CNN was told to attribute the somke and some peripheral area beside the fire to areas with fire.
By the way, there still some pictures that can not be recognised with an ideal result.
For example:
(1):size and resize conflict.
When we label this picture it was a rectangular frame, however, what our CNN exactly needed was a '100 by 100 by 3 ’ picture.
Then we run our CNN to test a original picture by calculating all its frames covering the '100 by 100 by 3 ’ areas
(2)the sames results in a picture with distinctive fieatures.
For no reason! 😦
Overview
In conclusion, this fire recognise didn’t strictly show a high accuracy. Nevertheless, I learned a lot on how to set the parameters of convoluted neural network as well as how to handle pictures in python.
reference:
(1) Batch function:
Python Batch
Attempt to create the batch function to organise the data, however not yet.
(2) CNN structure_1:
Tensorflow卷积神经网络(CNN)手写数字识别
(3) CNN structure_2:
TensorFlow之CNN图像分类及模型保存与调用