图像去雨(rainy streaks removal)#引导滤波
本文主要讲述自己所作图像去雨项目
由于雨水对光线的高反射,雨水在图像中通常被成像为明亮的条纹,进而会影响图像的视觉质量。摄影师可以调整曝光时间和景深这些参数来限制拍摄到雨线。然而,这种方法只能在很小程度上避免雨纹,并且不适用雨车载摄像头使用。因此,对于大多数采集到的雨图像来说,找到一种算法来去除图片中的雨纹是必要的。本节将采取主成分分析法对雨条纹进行特征描述和细化处理,通过中值滤波将雨线与之邻近的无雨背景层进行映射来恢复图像。
本人已做项目如下,其他代码需求也可以联系哦!资源大把! 好了废话不多说,开讲去雨项目!
1.效果展示
雨线原图
去雨后效果图
2.采用方法
下图为区域过程图片。
雨图可以表示为:I=B+R
I为雨图,B为背景层,R为雨层
2.1.去雨过程
为了得到良好的去雨图像,当务之急是要使得雨图像的低频背景层和高频线特征层分离。首先,Wan发现雨滴通常对光线有很强的反射,所以它们的像素强度明显比背景像素大,利用该理论得到了粗糙的二值图像 M,并把高频雨线成分视为 1 值,背景层视为 0 值。这种方法可以粗略提取出雨图像的高频信息,把一些无关紧要的信息进行忽略。
然而,二值图像 M 包括了高频细节信息和雨线信息,需要进一步的将高频雨线与高频细节层分离。本文采用主成分分析法,对图像 M 中的连通区域进行分析来获取细化的二值图像 Mf,如图 1©所示。所谓连通区域是指图像中具有相同的像素值,而且彼此位置相邻的前景像素点所构成的图像区域。针对二值图像 M来说,前景像素点即为图像中白色区域,通过把每个单独区域的特征进行分析可以进一步的优化二值图像。
2.2 去雨重点
进行连通区域求取之前,需要确定雨线特征,对特征进行阈值划分来达到将二值图像 M 中的高频雨线与高频细节分离的效果。一般来说,雨线在图像中的分布比较均匀且形状大体固定。因此可以将雨线进行特征描述,具体的见图 中的局部放大图,本文把图像中雨线特征描述为长为 L,宽为 W,倾斜角为 β 的红色椭圆区域。根据长宽比、长、倾斜角的定义,进一步的遍历 图中各个独立的连通区域,求取连通区域长宽比、倾斜角、长度的情况。通过得到的长、宽、倾斜角度与设定的雨线特征阈值的比较,可以判断出连通区域是否属于雨线部分,进而可以将其分离主要采用引导滤波和主成分分析 以及神经网络进行雨线的去除,将无雨图像作为目标标签进行训练。
2.3 雨特征提取
代码如下
``引导滤波
```pythonimport tensorflow as tfdef diff_x(input, r):assert input.shape.ndims == 4left = input[:, :, r:2 * r + 1]middle = input[:, :, 2 * r + 1: ] - input[:, :, :-2 * r - 1]right = input[:, :, -1: ] - input[:, :, -2 * r - 1: -r - 1]output = tf.concat([left, middle, right], axis=2)return outputdef diff_y(input, r):assert input.shape.ndims == 4left = input[:, :, :, r:2 * r + 1]middle = input[:, :, :, 2 * r + 1: ] - input[:, :, :, :-2 * r - 1]right = input[:, :, :, -1: ] - input[:, :, :, -2 * r - 1: -r - 1]output = tf.concat([left, middle, right], axis=3)return outputdef box_filter(x, r):assert x.shape.ndims == 4return diff_y(tf.cumsum(diff_x(tf.cumsum(x, axis=2), r), axis=3), r)def guided_filter(x, y, r, eps=1e-8, nhwc=False):assert x.shape.ndims == 4 and y.shape.ndims == 4# data formatif nhwc:x = tf.transpose(x, [0, 3, 1, 2])y = tf.transpose(y, [0, 3, 1, 2])# shape checkx_shape = tf.shape(x)y_shape = tf.shape(y)assets = [tf.assert_equal( x_shape[0], y_shape[0]),tf.assert_equal( x_shape[2:], y_shape[2:]),tf.assert_greater(x_shape[2:], 2 * r + 1),tf.Assert(tf.logical_or(tf.equal(x_shape[1], 1),tf.equal(x_shape[1], y_shape[1])), [x_shape, y_shape])]with tf.control_dependencies(assets):x = tf.identity(x)# NN = box_filter(tf.ones((1, 1, x_shape[2], x_shape[3]), dtype=x.dtype), r)# mean_xmean_x = box_filter(x, r) / N# mean_ymean_y = box_filter(y, r) / N# cov_xycov_xy = box_filter(x * y, r) / N - mean_x * mean_y# var_xvar_x = box_filter(x * x, r) / N - mean_x * mean_x# AA = cov_xy / (var_x + eps)# bb = mean_y - A * mean_xmean_A = box_filter(A, r) / Nmean_b = box_filter(b, r) / Noutput = mean_A * x + mean_bif nhwc:output = tf.transpose(output, [0, 2, 3, 1])return output
import os
import re
import time
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from GuidedFilter import guided_filter##################### Select GPU device ####################################
os.environ['CUDA_VISIBLE_DEVICES'] = "0"
############################################################################tf.reset_default_graph()##################### Network parameters ###################################
num_feature = 512 # number of feature maps
num_channels = 3 # number of input's channels
patch_size = 64 # patch size
learning_rate = 1e-3 # learning rate
iterations = int(2e5) # iterations
batch_size = 10 # batch size
save_model_path = "./model/" # saved model's path
model_name = 'model-iter' # saved model's name
############################################################################input_path = "./TrainData/input/" # the path of training data
gt_path = "./TrainData/label/" # the path of training label# randomly select image patches
def _parse_function(filename, label): image_string = tf.read_file(filename) image_decoded = tf.image.decode_jpeg(image_string, channels=3) rainy = tf.cast(image_decoded, tf.float32)/255.0image_string = tf.read_file(label) image_decoded = tf.image.decode_jpeg(image_string, channels=3) label = tf.cast(image_decoded, tf.float32)/255.0t = time.time()rainy = tf.random_crop(rainy, [patch_size, patch_size ,3],seed = t) # randomly select patchlabel = tf.random_crop(label, [patch_size, patch_size ,3],seed = t) return rainy, label # DerainNet
def inference(images):with tf.variable_scope('DerainNet', reuse=tf.AUTO_REUSE): base = guided_filter(images,images, 15, 1, nhwc=True) # using guided filter for obtaining base layerdetail = images - base # detail layerconv1 = tf.layers.conv2d(detail, num_feature, 16, padding="valid", activation = tf.nn.relu)conv2 = tf.layers.conv2d(conv1, num_feature, 1, padding="valid", activation = tf.nn.relu)output = tf.layers.conv2d_transpose(conv2, num_channels, 8, strides = 1, padding="valid")return output, baseif __name__ == '__main__':RainName = os.listdir(input_path)for i in range(len(RainName)):RainName[i] = input_path + RainName[i]LabelName = os.listdir(gt_path) for i in range(len(LabelName)):LabelName[i] = gt_path + LabelName[i] filename_tensor = tf.convert_to_tensor(RainName, dtype=tf.string) labels_tensor = tf.convert_to_tensor(LabelName, dtype=tf.string) dataset = tf.data.Dataset.from_tensor_slices((filename_tensor, labels_tensor))dataset = dataset.map(_parse_function) dataset = dataset.prefetch(buffer_size=batch_size * 10)dataset = dataset.batch(batch_size).repeat() iterator = dataset.make_one_shot_iterator()rainy, labels = iterator.get_next() details_label = labels - guided_filter(labels, labels, 15, 1, nhwc=True)details_label = details_label[:, 4:patch_size-4, 4:patch_size-4, :] # output size 56details_output, _ = inference(rainy)loss = tf.reduce_mean(tf.square( details_label - details_output )) # MSE lossall_vars = tf.trainable_variables() g_optim = tf.train.AdamOptimizer(learning_rate).minimize(loss, var_list = all_vars) # optimizerprint("Total parameters' number: %d" %(np.sum([np.prod(v.get_shape().as_list()) for v in all_vars]))) saver = tf.train.Saver(var_list = all_vars, max_to_keep = 5)config = tf.ConfigProto()config.gpu_options.allow_growth = Trueinit = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())with tf.Session(config=config) as sess:with tf.device('/gpu:0'): sess.run(init) tf.get_default_graph().finalize() if tf.train.get_checkpoint_state(save_model_path): # load previous trained model ckpt = tf.train.latest_checkpoint(save_model_path)saver.restore(sess, ckpt) ckpt_num = re.findall(r'(\w*[0-9]+)\w*',ckpt)start_point = int(ckpt_num[-1]) + 1 print("Load success")else: # re-training when no models foundstart_point = 0 print("re-training")check_data, check_label = sess.run([rainy, labels])print("Check patch pair:") plt.subplot(1,2,1) plt.imshow(check_data[0,:,:,:])plt.title('input') plt.subplot(1,2,2) plt.imshow(check_label[0,:,:,:])plt.title('ground truth') plt.show()start = time.time() for j in range(start_point, iterations): # iterations_,Training_Loss = sess.run([g_optim,loss]) # trainingif np.mod(j+1,100) == 0 and j != 0: # save the model every 100 iterations end = time.time()print ('%d / %d iteraions, Training Loss = %.4f, runtime = %.1f s' % (j+1, iterations, Training_Loss, (end - start))) save_path_full = os.path.join(save_model_path, model_name)saver.save(sess, save_path_full, global_step = j+1, write_meta_graph=False)start = time.time() print('Training is finished.')sess.close()
同时,在真实数据集参数对比中,本文所提算法依旧拥有良好的表现,,本文所提算法结果在 PSNR 和 SSIM 参数中均高于对比算法。
欢迎被代码困住的 被debug缠身的小伙伴交流解决,视觉相关代码,单目测距,论文撰写,(yolo,presacn,matlab,c++)皆可交流哦------------------------!
图像去雨(rainy streaks removal)#引导滤波相关推荐
- 【论文分享】联合形态学滤波和卷积稀疏编码的图像去雨
[论文分享]联合形态学滤波和卷积稀疏编码的图像去雨
- 图像去雾/图像去雨(matlab/python)
看到许多小伙伴想进行图像去雨,图像去雾的任务,由于以前进行了此类项目,所以在此书写博客进行交流. 代码获取 去雨前言 从静止图像中去除雨水是一项复杂且具有挑战性的任务.雨滴仅影响图像的很小区域,因此导 ...
- Transformer 杀疯了,图像去雨、人脸幻构、风格迁移、语义分割等通通上分
前段时间 Transformer 已席卷计算机视觉领域,并获得大量好评,如『基于Swin-Transformer』.『美团提出具有「位置编码」的Transformer,性能优于ViT和DeiT』.『L ...
- 深度学习:图像去雨网络实现Pytorch (二)一个简单实用的基准模型(PreNet)实现
本文参考文献:Progressive Image Deraining Networks: A Better and Simpler Baseline Dongwei Ren1, Wangmeng Zu ...
- [图像去雨]--Arixv-Gradual Network for Single Image De-raining
摘要: 在单幅图像去雨方面的大多数进展都遇到了一个关键的挑战,即在保留图像细节的同时去除不同尺度和形状的雨条纹.现有的单幅图像消雨方法将消雨条纹直接视为像素级回归过程.然而,他们在过度降雨(如去除无雨 ...
- 图像去雨算法(基于卷积网络)
图像去雨算法文章: https://pdfs.semanticscholar.org/bf10/3b3ea90f0d032d1d73dbb83ae41731ee006f.pdf 相应的代码和论文 ht ...
- hikey970学习-012 hikey970上移植图像去雨深度神经网络算法
摘要:本文在hikey970嵌入式设备上运行图像去雨深度神经网络算法,验证hikey970运行神经网络模型的性能与效果. 一.图像去雨简介 图像去雨处理指的是对于一张雨中的图片,去除画面中的雨 ...
- 图像去雨:超详细手把手写 pytorch 实现代码(带注释)
引导 数据集准备 训练数据集代码 测试数据集代码 网络模型代码 训练代码 测试代码 参考文献 其他 数据集准备 使用来自第一个参考文献的公开数据集Rain12600和Rain1400,下载链接.其中训 ...
- 图像去雨实例(一)之AttentiveGAN
论文阅读见:<Attentive Generative Adversarial Network for Raindrop Removal from A Single Image> 首先环境 ...
- CVPR 2021 论文大盘点-图像视频去雨篇
本文继续总结图像处理相关论文,关注一类特殊的图像修补任务--视频.图像去雨,共计 10 篇. 大家可以在: https://openaccess.thecvf.com/CVPR2021?day=all ...
最新文章
- FuzzyCMeans算法
- 线段树求矩形面积并 扫描线+离散化
- 我应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法吗?
- Bootstrap Paginator分页插件+ajax
- 突发,Log4j2 爆出远程代码执行漏洞,各大厂纷纷中招!
- Linux进程间通讯之消息队列
- 鸿蒙和宙斯谁厉害,漫威宇宙宙斯vs奥丁,到底谁更强
- 计算机等级考试绝对应用,96年4月至210年全国计算机等级考试绝对全收集.docx
- Storm之——Metric的使用
- WMB专题之ESQL
- K650D安装黑苹果
- lua入门之二table
- 我的BLOG开张了,朋友们要是高兴捧个场,要是不高兴砸鸡蛋(鸡蛋请买草鸡蛋,我不喜欢吃洋鸡蛋)
- dva 路由/导航/
- The Intriguing Obsession
- 用java画国际象棋棋盘
- 短租民宿多平台房态同步管理系统
- 高中数学怎么学好如何轻松学好高中数学
- java 手机应用开发
- win10系统如何连接宽带连接服务器,win10宽带连接在哪_win10设置宽带连接的方法...
热门文章
- Lattice Diamond 加入未默认支持flash
- OrCAD中PSpice K_Linear以及变压器的使用方法
- vue+elementUI 表格下载为excel
- mybatis获取map中的key和value
- esp32 cam 与安卓app蓝牙通讯
- 用文字描述给黑白照上色,这个免费网站火了!网友:比其他同类都好用
- 局域网oracle 速度慢,[转帖]局域网中其他用户感觉上网速度慢、网速卡
- 【Multisim仿真】LM317-337双路输出可调直流稳压电源电路
- 2017php最新版本,2017php受权验证系统2.6.8受权系统,真正完整可用,全新界面受权源码...
- CeoMax总裁WordPress模板3.8.1免受权版本