def transpose_image_and_label_tf(image, label): """ 转置翻转图像和标签 :param image:输入图像,四维[b,h,w,c]的tensor :param label:输入标签,四维[b,h,w,c]的tensor或者None :return:返回翻转后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image_shape = tf.shape(image) image_type = image.dtype label_type = label.dtype image_transpose = tf.image.transpose_image(image) image_transpose = tf.image.resize_bilinear( image_transpose, size=[image_shape[1], image_shape[2]]) if label is None: return image_transpose label_shape = tf.shape(label) label_transpose = tf.image.transpose_image(label) label_transpose = tf.image.resize_nearest_neighbor( label_transpose, size=[label_shape[1], label_shape[2]]) image_transpose = tf.cast(image_transpose, image_type) label_transpose = tf.cast(label_transpose, label_type) return image_transpose, label_transpose
def add_salt_and_pepper_noise_pyfunc(image, scale, value=255): """ 图像添加椒盐噪声 :param image: 输入图像,四维[b,h,w,c]的tensor :param scale: 噪声的比例系数 :param value: 噪声的值 :return: 添加噪声的图像 """ def add_salt_and_pepper_noise_func(img, scale): height, width = img.shape[1:3] img_copy = img.copy() noise_num = np.int32(np.round(scale * height * width)) random_coordinate = np.array( [[np.random.randint(height), np.random.randint(width)] for i in range(noise_num)]) img_copy[:, random_coordinate[:, 0], random_coordinate[:, 1], :] = value return img_copy if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image_noise = tf.py_func(add_salt_and_pepper_noise_func, [image, scale], [image.dtype]) return image_noise
def flip_image_and_label_tf(image, label): """ 翻转图像和标签,包括上下翻转,左右翻转,对角线翻转,和不翻转 :param image:输入图像,四维[b,h,w,c]的tensor :param label:输入标签,四维[b,h,w,c]的tensor或者None :return:返回翻转后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') flip_index = tf.round(tf.random.uniform([], 0, 3.0)) if label is None: image = tf.cond( tf.equal(flip_index, 1), lambda: flip_up_down_image_and_label_tf(image, label=None), lambda: tf.cond( tf.equal(flip_index, 2), lambda: flip_left_right_image_and_label_tf(image, label=None), lambda: tf.cond( tf.equal(flip_index, 3), lambda: transpose_image_and_label_tf(image, label=None), lambda: (image)))) return image image, label = tf.cond( tf.equal(flip_index, 1), lambda: flip_up_down_image_and_label_tf(image, label), lambda: tf.cond( tf.equal(flip_index, 2), lambda: flip_left_right_image_and_label_tf(image, label), lambda: tf.cond( tf.equal(flip_index, 3), lambda: transpose_image_and_label_tf( image, label), lambda: (image, label)))) return image, label
def decode_image_tf(contents, channel, image_extension): """ 利用tensorflow的函数解码图像 :param contents:需要解码的图像 :param channel:图像的通道数,灰度图为1,彩色图为3 :param image_extension:图像的格式,目前支持'bmp','jpg','png','gif' :return:图像数据 """ image_extension_lower = image_extension.lower() if image_extension_lower == 'bmp': if channel == 1: image_decode = tf.image.decode_bmp(contents, channels=0) img_shape = tf.shape(image_decode) image_decode = tf.reshape( image_decode, shape=[img_shape[0], img_shape[1], channel]) elif channel == 3: image_decode = tf.image.decode_bmp(contents, channels=channel) elif image_extension_lower == 'jpg' or image_extension_lower == 'jpeg': image_decode = tf.image.decode_jpeg(contents, channels=channel) elif image_extension_lower == 'png': image_decode = tf.image.decode_png(contents, channels=channel) elif image_extension_lower == 'gif': image_decode = tf.image.decode_gif(contents, channels=channel) else: bz_log.error('只支持bmp,jpg,jpeg,png,gif类型的图像!') raise ValueError('只支持bmp,jpg,jpeg,png,gif类型的图像!') return image_decode
def translate_image_and_label_tf_pyfunc(image, label, dx, dy): """ 使用tensorflow函数对图像进行平移 :param image: 输入图像,四维[b,h,w,c]的tensor :param label: 输入的标签,四维[b,h,w,c]的tensor或者None :param dx:水平方向平移,向右为正 :param dy:垂直方向平移,向下为正 :return:返回平移后的图像 """ def translate_image_and_label_func(img, label, dx, dy): img = np.reshape(img, newshape=[img.shape[1], img.shape[2], img.shape[3]]) label = np.reshape( label, newshape=[label.shape[1], label.shape[2], label.shape[3]]) img = img.astype(np.uint8) label = label.astype(np.uint8) affine_arr = np.float32([[1, 0, dy], [0, 1, dx]]) img = cv2.warpAffine(img, affine_arr, (img.shape[1], img.shape[0])) if label is None: return img label = cv2.warpAffine(label, affine_arr, (label.shape[1], label.shape[0])) return img, label if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if label is None: image_rotate, _ = tf.py_func(translate_image_and_label_func, [image, image, dx, dy], [image.dtype, label.dtype]) return image_rotate return tf.py_func(translate_image_and_label_func, [image, label, dx, dy], [image.dtype, label.dtype])
def random_translate_image_and_label_tf(image, label, max_dx, max_dy): """ 使用tensorflow函数对图像进行随机平移 :param image: 输入图像,四维[b,h,w,c]的tensor :param label: 输入的标签,四维[b,h,w,c]的tensor或者None :param max_dx:水平方向平移最大距离,向右为正 :param max_dy:垂直方向平移最大距离,向下为正 :return:返回平移后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if np.abs(max_dx) > image.shape[2]: raise ValueError('max_dx超过了图像的宽度!') if np.abs(max_dy) > image.shape[1]: raise ValueError('max_dy超过了图像的高度!') dx = tf.random_uniform([], minval=-max_dx, maxval=max_dx, dtype=tf.float32, seed=1) dy = tf.random_uniform([], minval=-max_dy, maxval=max_dy, dtype=tf.float32, seed=1) image_translate = tf.contrib.image.translate(image, translations=[dx, dy]) if label is None: return image_translate label_translate = tf.contrib.image.translate(label, translations=[dx, dy]) return image_translate, label_translate
def rotate_image_and_label_tf_pyfunc(image, label, angle): """ 使用tensorflow函数对图像进行随机旋转 :param image: 输入图像,四维[b,h,w,c]的tensor :param label: 输入的标签,四维[b,h,w,c]的tensor或者None :param angle: 旋转的最大角度 :return: 旋转后的图像 """ def rotate_image_and_label_func(img, label, angle): img = np.reshape(img, newshape=[img.shape[1], img.shape[2], img.shape[3]]) label = np.reshape( label, newshape=[label.shape[1], label.shape[2], label.shape[3]]) if label is None: return misc.imrotate(img, angle, 'bilinear'), None else: return misc.imrotate(img, angle, 'bilinear'), misc.imrotate( label, angle, 'nearest') if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if label is None: image_rotate, _ = tf.py_func(rotate_image_and_label_func, [image, image, angle], [image.dtype, label.dtype]) return image_rotate return tf.py_func(rotate_image_and_label_func, [image, label, angle], [image.dtype, label.dtype])
def get_all_subfolder_img_label_path_list(folder, ret_full_path=True): ''' 获取folder文件夹下所有文件夹内的img和label path_list,如train文件夹下有1,2,3,4等各个类别文件夹, 每个文件夹下是img和label文件夹,必须是img和label的命名。 :param folder: 父文件夹 :param ret_full_path:是否返回全路径 :return: ''' img_list = np.array([]) label_list = np.array([]) default_separation_line = '/' if (platform.system() == 'Windows'): default_separation_line = '\\' if folder[-1] != '\\': folder = folder + '\\' elif (platform.system() == 'Linux'): if folder[-1] != '/': folder = folder + '/' else: bz_log.error('目前只支持Windows 系统和Linux系统!') raise ValueError('目前只支持Windows 系统和Linux系统!') for subfolder in get_subfolder_path(folder, ret_full_path=True, is_recursion=False): sub_img_list, sub_label_list = get_img_label_path_list( img_path=subfolder + default_separation_line + 'img', label_path=subfolder + default_separation_line + 'label', ret_full_path=ret_full_path) img_list = np.append(img_list, sub_img_list) label_list = np.append(label_list, sub_label_list) return img_list, label_list
def make_label_func(out_path,train_folder,eval_folder,processed_train_folder,processed_eval_folder,class_num): # 进行图片,label的处理,真正喂入神经网络的数据路径 bz_log.info("生成训练对应的标签格式") generate_label_func = generate_yolo_dataset.GenerateYoloLabel() for folder in [train_folder,eval_folder]: for subfolder in os.listdir(folder): if os.path.isdir(folder+os.sep+subfolder): print(subfolder) #balanced 增强后的数据路径 sub_img_folder=folder+os.sep+subfolder+os.sep+'augmentation_img' sub_label_folder=folder+os.sep+subfolder+os.sep+'augmentation_label' #创建一个新的文件夹,用来存储计算后的标签 if 'train' in folder: img_calced_folder=processed_train_folder+os.sep+subfolder+'/img/' label_calced_folder=processed_train_folder+os.sep+subfolder+'/label/' else: img_calced_folder = processed_eval_folder + os.sep + subfolder + '/img/' label_calced_folder = processed_eval_folder + os.sep + subfolder + '/label/' if os.path.exists(label_calced_folder): shutil.rmtree(label_calced_folder) os.makedirs(label_calced_folder) if os.path.exists(img_calced_folder): shutil.rmtree(img_calced_folder) os.makedirs(img_calced_folder) for k,img_p in enumerate(os.listdir(sub_img_folder)): #对 一对img,label进行计算 img_name=img_p.split('.')[0] cur_img_file=sub_img_folder+os.sep+img_p cur_label_file=sub_label_folder+os.sep+img_name+'.npy' bz_log.info('开始处理%d,张图%s', k, img_p) print('开始处理' + str(k)+ '张图,',img_p ) bz_log.info("解析数据") #bboxes:[center_y, center_x, height, width] (img,bboxes_),cls_= parse_simple_data(cur_img_file,cur_label_file,config.img_shape[: 2]) # bboxes:[center_y, center_x, height, width]->[xmin,ymin,xmax,ymax] bboxes=np.zeros_like(bboxes_) for i,box in enumerate(bboxes_): bboxes[i][0] = box[1] - box[3] / 2. bboxes[i][1] = box[0] - box[2] / 2. bboxes[i][2] = box[1] + box[3] / 2. bboxes[i][3] = box[0] + box[2] / 2. if img.shape != config.img_shape: bz_log.error('输出大小不对%d,%d,%d',img.shape[0], img.shape[1], img.shape[2] ) raise ValueError('输出大小不对') #制作3种尺寸的标签 print(img_p) label = generate_label_func( np.concatenate((bboxes,np.expand_dims(cls_,1)),axis=-1), num_classes=class_num ) cv2.imwrite(img_calced_folder + img_p, img) np.save(label_calced_folder+img_name+'.npy',label)
def adjust_brightness_image_tf(image, delta): """ 使用tensorflow函数调整图像亮度 :param image:输入图像,四维[b,h,w,c]的tensor :param delta:增加的值 :return:调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image = tf.image.adjust_brightness(image, delta) return image
def adjust_contrast_image_tf(image, contrast_factor): """ 使用tensorflow函数调整图像对比度 :param image:输入图像,四维[b,h,w,c]的tensor :param contrast_factor:调整的倍率 :return:调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image = tf.image.adjust_contrast(image, contrast_factor) return image
def random_rescale_image_and_label_tf(image, label, min_scale=0.5, max_scale=1): """ 使用tensorflow函数对图像进行缩放 :param image: 输入图像,四维[b,h,w,c]的tensor :param label:,四维[b,h,w,c]的tensor或者None :param min_scale: 缩放最小系数 :param max_scale: 缩放最大系数 :return: 返回缩放后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if min_scale <= 0: raise ValueError('\'min_scale\' must be greater than 0.') elif max_scale <= 0: raise ValueError('\'max_scale\' must be greater than 0.') elif min_scale >= max_scale: raise ValueError('\'max_scale\' must be greater than \'min_scale\'.') image_type = image.dtype label_type = label.dtype image_shape = tf.shape(image) image_shape = tf.cast(image_shape, dtype=tf.float32) height, width = image_shape[1], image_shape[2] height_scale = tf.random_uniform([], minval=min_scale, maxval=max_scale, dtype=tf.float32, seed=1) width_scale = tf.random_uniform([], minval=min_scale, maxval=max_scale, dtype=tf.float32, seed=2) new_height = tf.to_int32(height * height_scale) new_width = tf.to_int32(width * width_scale) image = tf.image.resize_images(image, [new_height, new_width], method=tf.image.ResizeMethod.BILINEAR) image = tf.cast(image, image_type) if label is None: return image label = tf.image.resize_images( label, [new_height, new_width], method=tf.image.ResizeMethod.NEAREST_NEIGHBOR) label = tf.cast(label, label_type) return image, label
def random_brightness_image_tf(image, max_delta, seed=None): """ 使用tensorflow函数随机调整图像亮度 :param image: 输入图像,四维[b,h,w,c]的tensor :param max_delta: 调整的最大值 :param seed: 种子点 :return: 调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image = tf.image.random_brightness(image, max_delta, seed) return image
def adjust_saturation_image_tf(image, saturation_factor, name=None): """ 使用tensorflow函数调整图像饱和度 :param image:输入图像,四维[b,h,w,c]的tensor :param saturation_factor:调整的倍率 :return:调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if image.shape[-1] != 3: raise ValueError('必须传入三通道图像!') image = tf.image.adjust_saturation(image, saturation_factor, name) return image
def get_file_path(folder, exts=[], ret_full_path=False): ''' 作用: 获取指定文件夹下所有指定扩展名的文件路径 参数: folder : 指定文件夹路径 ret_full_path: 是否返回全路径,默认只返回符合条件的扩展名的文件名 exts : 扩展名列表 ''' if not (ret_full_path == True or ret_full_path == False): bz_log.error('输入参数只能是True或者False') bz_log.error(ret_full_path) raise ValueError('输入参数只能是True或者False') if not (os.path.isdir(folder)): bz_log.error('输入参数必须是目录或者文件夹') bz_log.error(folder) raise ValueError('输入参数必须是目录或者文件夹') if isinstance(exts, str): exts = [exts] result = [] for root, dirs, files in os.walk(folder): for f in files: (file_name, file_ext) = os.path.splitext(f) if (file_ext in exts) or (file_ext[1:] in exts) or (len(exts) == 0): if ret_full_path: result.append(os.path.join(root, f)) else: result.append(f) return result
def random_contrast_image_tf(image, lower, upper, seed=None): """ 使用tensorflow函数随机调整图像对比度 :param image: 输入图像,四维[b,h,w,c]的tensor :param lower: 调整的最小值 :param upper: 调整的最大值 :param seed: 种子点 :return: 调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image = tf.image.random_contrast(image, lower, upper, seed) return image
def per_image_standardization_tf(image): """ 图像标准化 :param image:输入图像,四维[b,h,w,c]的tensor :return: """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if image.shape[-1] != 3: raise ValueError('必须传入三通道图像!') img = tf.reshape(image, [image.shape[1], image.shape[2], image.shape[3]]) img = tf.image.per_image_standardization(img) return tf.reshape(img, [-1, img.shape[0], img.shape[1], img.shape[2]])
def random_saturation_image_tf(image, lower, upper, seed=None): """ 使用tensorflow函数随机调整图像饱和度 :param lower: 调整的最小值 :param upper: 调整的最大值 :param seed: 种子点 :return: 调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if image.shape[-1] != 3: raise ValueError('必须传入三通道图像!') image = tf.image.random_saturation(image, lower, upper, seed) return image
def flip_left_right_image_and_label_tf(image, label): """ 左右翻转图像和标签 :param image:输入图像,四维[b,h,w,c]的tensor :param label:输入标签,四维[b,h,w,c]的tensor或者None :return:返回翻转后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image = tf.image.flip_left_right(image) if label is None: return image label = tf.image.flip_left_right(label) return image, label
def add_random_noise(image, minval, maxval): """ 增加随机噪声 :param image: 输入图像,四维[b,h,w,c]的tensor :param minval:噪声的最小值 :param maxval:噪声的最大值 :return:添加噪声的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') noise = tf.random.uniform(tf.shape(image), minval=minval, maxval=maxval) noise = tf.cast(noise, image.dtype) image = tf.add(image, noise) return image
def random_hue_image_tf(image, max_delta, seed=None): """ 使用tensorflow函数随机调整图像色相 :param image: 输入图像,四维[b,h,w,c]的tensor :param max_delta: 调整颜色通道的最大随机值 :param seed: 种子点 :return: 调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if image.shape[-1] != 3: raise ValueError('必须传入三通道图像!') image = tf.image.random_hue(image, max_delta, seed) return image
def get_file_name(file_path, return_ext=False): """ 获取文件的文件名和后缀 :param file_path: 文件名 :param return_ext: 是否返回文件扩展名 :return: """ img_full_name = os.path.basename(file_path) if '.' not in img_full_name: bz_log.error('file_path 不是文件名!%s', file_path) raise ValueError('file_path 不是文件名!') img_name_list = img_full_name.rsplit('.', 1) if return_ext: return img_name_list[0], img_name_list[1] return img_name_list[0]
def save_detection_txt_label(detection_txt_label_path, label): _, ext = bz_path.get_file_name(detection_txt_label_path, True) if ext != 'txt': bz_log.error("路径(" + detection_txt_label_path + ")不是txt文件!") bz_log.error("错误的txt文件路径:", detection_txt_label_path) raise ValueError("路径(" + detection_txt_label_path + ")不是txt文件!") if os.path.exists(detection_txt_label_path): os.remove(detection_txt_label_path) with open(detection_txt_label_path, 'w+') as f: for one_label in label: one_label_str = functools.reduce(lambda x, y: x + y, [str(i) + '_' for i in one_label]) f.write(one_label_str[:-1] + '\n')
def adjust_hue_image_tf(image, delta): """ 使用tensorflow函数调整图像色相 :param image:输入图像,四维[b,h,w,c]的tensor :param delta:调整颜色通道的增加量 :return:调整后的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') if image.shape[-1] != 3: raise ValueError('必须传入三通道图像!') if delta < 0 or delta > 0.5: raise ValueError('delta必须为0到0.5之间的数') image = tf.image.adjust_hue(image, delta) return image
def get_preprocessing_img_and_label_path_list( base_folder, generate_data_folder='./generate_data/', max_augment_num=None, is_balance=True, mode='train', task='classification', out_file_extension_list=['jpg', 'txt']): """ 获取前处理后的img和label 列表,可以进行balance也可以不进行balance :param base_folder:数据路径,其下面包含如1,2,3,4等文件夹,1,2,3,4下包含img,label文件夹 :param generate_data_folder:生成数据路径 :param max_augment_num:均衡化后每个类别数目,如果为None则模型按类别最多的数目 :param is_balance:是否进行均衡 :param mode:模式,"只能输入train,val,test,TRAIN,VAL,TEST,Train,Val,Test" "中的一个!" :return:img,label 的list """ if not os.path.exists(base_folder): bz_log.error("路径" + base_folder + "不存在!") bz_log.error(base_folder) raise ValueError("路径" + base_folder + "不存在!") mode_lower = mode.lower() if mode_lower not in ['train', 'val', 'test']: bz_log.error("mode 只能输入train,val,test,TRAIN,VAL,TEST," "Train,Val,Test中的一个!") bz_log.error(mode_lower) raise ValueError("mode 只能输入train,val,test,TRAIN,VAL,TEST," "Train,Val,Test中的一个!") if is_balance: balance_obj = BalanceData( base_folder=base_folder, generate_data_folder=generate_data_folder, max_augment_num=max_augment_num, task=task, out_file_extension_list=out_file_extension_list) img_list, label_list, is_repeat_data_flag = balance_obj.create_data() # img_list, label_list = balance_data( # base_folder=base_folder, # generate_data_folder=generate_data_folder_new, # max_augment_num=max_augment_num,task=task) return img_list, label_list else: img_list, label_list = bz_path.get_all_subfolder_img_label_path_list( base_folder, ret_full_path=True) if mode == 'test' or mode == 'validate': return img_list, label_list shuffle_indices = np.arange(len(img_list)) np.random.shuffle(shuffle_indices) shuffle_img_list = img_list[shuffle_indices] shuffle_label_list = img_list[shuffle_indices] return shuffle_img_list, shuffle_label_list
def random_rotate_image_and_label_tf(image, label, max_angle): """ 使用tensorflow函数对图像进行随机旋转 :param image: 输入图像,四维[b,h,w,c]的tensor :param label: 输入的标签,四维[b,h,w,c]的tensor或者None :param angle: 旋转的最大角度 :return: 旋转后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') angle = tf.random_uniform([], minval=-max_angle, maxval=max_angle, dtype=tf.float32, seed=1) return rotate_image_and_label_tf(image, label, angle)
def add_gaussian_noise(image, mean, std): """ 增加高斯噪声 :param image:输入图像,四维[b,h,w,c]的tensor :param mean: 噪声均值 :param std: 噪声标准差 :return: 添加噪声的图像 """ if len(image.shape) != 4: bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') noise = tf.random_normal(shape=tf.shape(image), mean=mean, stddev=std, dtype=tf.float16) noise = tf.cast(noise, image.dtype) image = tf.add(image, noise) return image
def pack_func(img_list, label_list, generate_label_func, class_num, saved_folder, flag, file_in_one_tfrecord=50): '''把train,eval分别封装进各自的文件夹下的固定数目的子tfrecords''' num_count = 0 for cur_img_file, cur_label_file in zip(img_list, label_list): if num_count % file_in_one_tfrecord == 0: #重定向writer sub_record_num = num_count // file_in_one_tfrecord writer=tf.python_io.TFRecordWriter(saved_folder + os.sep +\ flag+str(sub_record_num)+'.tfrecords') # bboxes:[center_y, center_x, height, width] (img, bboxes_), cls_ = parse_simple_data(cur_img_file, cur_label_file, config.img_shape[:2]) # bboxes:[center_y, center_x, height, width]->[xmin,ymin,xmax,ymax] bboxes = np.zeros_like(bboxes_) for i, box in enumerate(bboxes_): bboxes[i][0] = box[1] - box[3] / 2. bboxes[i][1] = box[0] - box[2] / 2. bboxes[i][2] = box[1] + box[3] / 2. bboxes[i][3] = box[0] + box[2] / 2. if img.shape != config.img_shape: bz_log.error('输出大小不对%d,%d,%d', img.shape[0], img.shape[1], img.shape[2]) raise ValueError('输出大小不对') # 制作3种尺寸的标签,共6个矩阵需要封装 # (52,52,3,25),(26,26,3,25),(13,13,3,25),(150,4),(150,4),(150,4) label = generate_label_func(np.concatenate( (bboxes, np.expand_dims(cls_, 1)), axis=-1), num_classes=class_num) # 在这里写入tfrecords simple_example_proto = tfexample_converter.serialize_yolo_example( img, label) writer.write(simple_example_proto) num_count += 1 if num_count % file_in_one_tfrecord == 0: writer.close()
def rotate_image_and_label_tf(image, label, angle): """ 使用tensorflow函数对图像进行旋转 :param image: 输入图像,四维[b,h,w,c]的tensor :param label: 输入的标签,四维[b,h,w,c]的tensor或者None :param angle: 旋转的角度 :return: 旋转后的图像 """ if len(image.shape) != 4 or (label is not None and len(label.shape) != 4): bz_log.error('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') raise ValueError('传入的image必须是四维的tensor,label必须是四维的tensor或者None!') image_rotate = tf.contrib.image.rotate(image, angle) if label is None: return image_rotate label_rotate = tf.contrib.image.rotate(label, angle) return image_rotate, label_rotate
def get_img_label_path_list(img_path, label_path, ret_full_path=False, ext_list=([], [])): """ 获取经过排序后img和label的path_list :param img_path:图像路径 :param label_path: label路径 :param ret_full_path: 是否返回全路径 :param ext_list:img 和label的文件扩展名,需要是一个包含两个list的tuple或者list,其中的第一个list与img对应,第二个list与label对应 :return:获取经过排序后img和label的path_list """ img_file_path_list = np.sort( get_file_path(img_path, ret_full_path=ret_full_path, exts=ext_list[0])) label_file_path_list = np.sort( get_file_path(label_path, ret_full_path=ret_full_path, exts=ext_list[1])) if len(img_file_path_list) == 0 or len(label_file_path_list) == 0: bz_log.error('img_path或者label_path为空!%d%d', len(img_file_path_list), len(label_file_path_list)) raise ValueError('img_path或者label_path为空!') if len(img_file_path_list) != len(label_file_path_list): bz_log.error('img_path和label_path中文件个数不相等!%d%d', len(img_file_path_list), len(label_file_path_list)) raise ValueError('img_path和label_path中文件个数不相等!') img_file_name_list = np.array(list(map(get_file_name, img_file_path_list))) label_file_name_list = np.array( list(map(get_file_name, label_file_path_list))) img_not_equal_file_list = img_file_path_list[ img_file_name_list != label_file_name_list] label_not_equal_file_list = label_file_path_list[ img_file_name_list != label_file_name_list] if len(img_not_equal_file_list) != 0: raise ValueError(img_not_equal_file_list, '和', label_not_equal_file_list, '文件名不一致!') return img_file_path_list, label_file_path_list