最近一直在协助做算法平台,需要写一些边缘性的代码。由此也越发觉得自己的代码真是不忍直视。SO一直在完善各方面知识,这周主要看了面向对象方面的知识,发现工作中用的最多的还是最基本的东西,也有可能是还没遇到比较合适的场景。下面是为了巩固面向对象知识,将之前学习中的图像数据预处理部分封装了一下。
#coding:utf-8
#! /usr/bin/env python
import cv2
import numpy as np
import tensorflow as tf
import os
class DataProcess(object):
def __init__(self, batch_size, image_height, image_width, crop_height, crop_width, label_bytes, num_channels, label_dict):
self.batch_size = batch_size
self.image_height = image_height
self.image_width = image_width
self.crop_height = crop_height
self.crop_width = crop_width
self.label_bytes = label_bytes
self.num_channels = num_channels
self.label_dict = label_dict
#把图片读成一个像素矩阵,存储在二进制文件中
def read_image_to_file(self,path):
if not os.path.isdir(path) and not os.path.isfile(path):
return False
if os.path.isfile(path):
file_path = os.path.split(path) #分割出目录与文件
lists2 = file_path[1].split('.') #分割出文件与文件扩展名
file_ext = lists2[-1] #取出后缀名(列表切片操作)
img_ext = ['bmp','jpeg','gif','psd','png','jpg']
if file_ext in img_ext:
img_file = "%s" %(path)
image = cv2.imread(img_file)
#将图片从BGR转换为RGB
image1 = image[: , : , : : -1]
#对图片进行缩放
image2 = cv2.resize(image1, (self.image_height, self.image_width))
#将图片转换成一维
image3 = image2.flatten() / 255 #除以255相当于对图片的像素值归一化
#每个存放图片的文件夹为图片的标签,提取图片的标签
lists1 = file_path[0].split('/')
labels = np.array((self.label_dict[lists1[-1]]))
#将图片表示和标签合并在一起
images = np.append(labels, image3)
with open(image_file, 'wb')as fp:
fp.write(images)
elif os.path.isdir(path):
for x in os.listdir(path):
self.read_image_to_file(os.path.join(path,x))
return [image_file]
def read_cifar_files(self, filename_queue, distort_images = True):
image_vec_length = self.image_height * self.image_width * self.num_channels
record_length = self.label_bytes + image_vec_length
#读这个图片文件的文件列表,扭曲图片等于TRUE
reader = tf.FixedLengthRecordReader(record_bytes = record_length)#从文件输出固定长度的字段(每个图片的存储字节数是固定的),
#读取固定长度字节数信息(针对bin文件使用FixedLengthRecordReader读取比较合适)
key,record_string = reader.read(filename_queue)#
record_bytes = tf.decode_raw(record_string,tf.uint8)#####字符串转为张量数据decode_raw 长度是record_length 3072 + 1
#从张量中提取数据段,并用cast进行数据类型转换
image_label = tf.cast(tf.slice(record_bytes,[0],[1]),tf.int32) # tf.slice 可以是list,array,tensor #先抽取图片标签
#抽取图片的表示
image_extracted = tf.reshape(tf.slice(record_bytes,[1],[image_vec_length]),[self.num_channels,self.image_height,self.image_width])#只能将图片先转化成这个形状不然会破坏图片原有的格式
image_uint8image = tf.transpose(image_extracted,[1,2,0])#第一维转到第三维,第二维转成第一维,第三维转成第二维
reshaped_image = tf.cast(image_uint8image,tf.float32)#改变数据类型
final_image_1 = tf.image.resize_image_with_crop_or_pad(reshaped_image,self.crop_width,self.crop_height)
#剪裁或填充处理,会根据原图像的尺寸和指定的目标图像的尺寸选择剪裁还是填充,如果原图像尺寸大于目标图像尺寸,则在中心位置剪裁,
#反之则用黑色像素填充。
if distort_images:
final_image = tf.image.random_flip_left_right(final_image_1)#以一定概率从左到右翻转
final_image = tf.image.random_brightness(final_image,max_delta=63) #在某范围随机调整图片亮度
final_image = tf.image.random_contrast(final_image,lower=0.2,upper=1.8) #在某范围随机调整图片对比度
final_image = tf.image.per_image_standardization(final_image) #此函数的运算过程是将整幅图片标准化(不是归一化),加速神经网络的训练。
return final_image,image_label,final_image_1
def input_pipeline(self,path):
filename_queue = self.read_image_to_file(path)
image,label,temp_value = self.read_cifar_files(filename_queue)
min_after_dequeue = 1000 #出队后队列里至少剩下min_after_dequeue个数据
capacity = min_after_dequeue + 3 * self.batch_size #队列的长度
#随机生成batch 数据
example_batch,label_batch = tf.train.shuffle_batch([image,label],self.batch_size,capacity,min_after_dequeue)
return (example_batch,label_batch,temp_value)
下周准备学习一下Socket编程,以及多线程和多进程,以便在数据量大的时候提高处理速率。ヾ(◍°∇°◍)ノ゙!!!