整合去雾网页工具

This commit is contained in:
admin
2026-06-10 17:42:11 +08:00
commit 6db15ebc3f
101 changed files with 10167 additions and 0 deletions

57
DehazeNet/All_in_One.sh Normal file
View File

@@ -0,0 +1,57 @@
#!/bin/bash
# 原图像位置
Dir_src_pics="./img/src"
Dir_Trans_Refine="./img/Trans_Refine"
Dir_Trans_Esti="./img/Trans_Esti"
Dir_result="./img/result"
Dir_ori_src_pics="/root/Dehaze/SRC_files/src_1280_720"
mkdir -p $Dir_src_pics $Dir_Trans_Refine $Dir_Trans_Esti $Dir_result
PS3='All in one choice : '
applications=("Delete_src_pics" "Delete_generate_pics" "Copy_src_pics" "Run_program" "quit")
select fav in "${applications[@]}"; do
case $fav in
# 删除原始文件选项
"Delete_src_pics")
# 删除src文件
echo "Delete all src files in $Dir_src_pics"
rm $Dir_src_pics/*
;;
# 删除生成文件选项
"Delete_generate_pics")
# 删除dark文件
echo "Delete all src files in $Dir_Trans_Refine"
rm $Dir_Trans_Refine/*
# 删除result文件
echo "Delete all src files in $Dir_result"
rm $Dir_result/*
# 删除trans文件
echo "Delete all src files in $Dir_Trans_Esti"
rm $Dir_Trans_Esti/*
;;
# 复制待处理文件选项
"Copy_src_pics")
# 删除src文件
echo "Copy all src files in $Dir_ori_src_pics"
ln -s $Dir_ori_src_pics/* $Dir_src_pics
;;
# 运行程序
"Run_program")
source ~/miniconda/bin/activate Dehaze_DCP
python DehazeNet.py ./img
;;
# 退出选项
"quit")
echo "User requested exit"
exit
;;
# 其他选项
*) echo "invalid option $REPLY";;
esac
done

View File

@@ -0,0 +1,173 @@
name: "Dehaze_fullconv"
input: "data"
input_dim: 1
input_dim: 3
input_dim: {height_15}
input_dim: {width_15}
layer {{
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
convolution_param {{
num_output: 20
kernel_size: 5
stride: 1
pad: 0
}}
}}
layer {{
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}}
layer {{
name: "reshape1"
type: "Reshape"
bottom: "conv1"
top: "reshape1"
reshape_param {{
shape {{
dim: 0
dim: 1
dim: 20
dim: -1
}}
}}
}}
layer {{
name: "pool1"
type: "Pooling"
bottom: "reshape1"
top: "pool1"
pooling_param {{
pool: MAX
kernel_w: 1
kernel_h: 5
stride_w: 1
stride_h: 5
}}
}}
layer {{
name: "reshape2"
type: "Reshape"
bottom: "pool1"
top: "reshape2"
reshape_param {{
shape {{
dim: 0
dim: 4
dim: {height_11}
dim: {width_11}
}}
}}
}}
layer {{
name: "conv2/1x1"
type: "Convolution"
bottom: "reshape2"
top: "conv2/1x1"
convolution_param {{
num_output: 16
kernel_size: 1
stride: 1
pad: 0
}}
}}
layer {{
name: "conv2/3x3"
type: "Convolution"
bottom: "reshape2"
top: "conv2/3x3"
convolution_param {{
num_output: 16
kernel_size: 3
stride: 1
pad: 1
}}
}}
layer {{
name: "conv2/5x5"
type: "Convolution"
bottom: "reshape2"
top: "conv2/5x5"
convolution_param {{
num_output: 16
kernel_size: 5
stride: 1
pad: 2
}}
}}
layer {{
name: "conv2/7x7"
type: "Convolution"
bottom: "reshape2"
top: "conv2/7x7"
convolution_param {{
num_output: 16
kernel_size: 7
stride: 1
pad: 3
}}
}}
layer {{
name: "conv2/output"
type: "Concat"
bottom: "conv2/1x1"
bottom: "conv2/3x3"
bottom: "conv2/5x5"
bottom: "conv2/7x7"
top: "conv2/output"
concat_param
{{
axis: 1
}}
}}
layer {{
name: "relu2"
type: "ReLU"
bottom: "conv2/output"
top: "conv2/output"
}}
layer {{
name: "pool2"
type: "Pooling"
bottom: "conv2/output"
top: "pool2"
pooling_param {{
pool: MAX
kernel_size: 8
stride: 1
}}
}}
layer {{
name: "ip1-conv"
type: "Convolution"
bottom: "pool2"
top: "ip1-conv"
convolution_param {{
num_output: 1
kernel_size: 5
}}
}}
layer {{
name: "drelu1"
type: "ReLU"
bottom: "ip1-conv"
top: "ip1-conv"
}}

Binary file not shown.

View File

@@ -0,0 +1,256 @@
name: "Dehaze"
input: "data"
input_dim: 1
input_dim: 3
input_dim: 16
input_dim: 16
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
pad: 0
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "reshape1"
type: "Reshape"
bottom: "conv1"
top: "reshape1"
reshape_param {
shape {
dim: 0
dim: 1
dim: 20
dim: -1
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "reshape1"
top: "pool1"
pooling_param {
pool: MAX
kernel_w: 1
kernel_h: 5
stride_w: 1
stride_h: 5
}
}
layer {
name: "reshape2"
type: "Reshape"
bottom: "pool1"
top: "reshape2"
reshape_param {
shape {
dim: 0
dim: 4
dim: 12
dim: 12
}
}
}
layer {
name: "conv2/1x1"
type: "Convolution"
bottom: "reshape2"
top: "conv2/1x1"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 16
kernel_size: 1
stride: 1
pad: 0
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "conv2/3x3"
type: "Convolution"
bottom: "reshape2"
top: "conv2/3x3"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 16
kernel_size: 3
stride: 1
pad: 1
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "conv2/5x5"
type: "Convolution"
bottom: "reshape2"
top: "conv2/5x5"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 16
kernel_size: 5
stride: 1
pad: 2
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "conv2/7x7"
type: "Convolution"
bottom: "reshape2"
top: "conv2/7x7"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 16
kernel_size: 7
stride: 1
pad: 3
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "conv2/output"
type: "Concat"
bottom: "conv2/1x1"
bottom: "conv2/3x3"
bottom: "conv2/5x5"
bottom: "conv2/7x7"
top: "conv2/output"
concat_param
{
axis: 1
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2/output"
top: "conv2/output"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2/output"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 8
stride: 1
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "drelu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}

208
DehazeNet/DehazeNet.py Normal file
View File

@@ -0,0 +1,208 @@
import sys,os
import caffe
import numpy as np
import cv2
import math
def EditFcnProto(templateFile, height, width):
with open(templateFile, 'r') as ft:
template = ft.read()
outFile = 'DehazeNetFcn.prototxt'
with open(outFile, 'w') as fd:
fd.write(template.format(height_15=height+15, width_15=width+15,
height_11=height+11, width_11=width+11))
def TransmissionEstimate(im_path, height, width):
caffe.set_mode_cpu()
# Define a safe tile size to prevent INT_MAX overflow (approx 512x512 is safe)
SAFE_TILE_SIZE = 512
# Use tiling if the image is larger than the safe size
if height > SAFE_TILE_SIZE or width > SAFE_TILE_SIZE:
print(f"Image size ({width}x{height}) is large. Using tiling to avoid memory overflow...")
# Determine effective tile size (cannot be larger than image)
tile_h = min(height, SAFE_TILE_SIZE)
tile_w = min(width, SAFE_TILE_SIZE)
# Generate prototxt for the TILE size, not the full image size
EditFcnProto('DehazeFcnTemplate.prototxt', tile_h, tile_w)
# Load networks
net = caffe.Net('DehazeNet.prototxt', 'DehazeNet.caffemodel', caffe.TEST)
net_full_conv = caffe.Net('DehazeNetFcn.prototxt', 'DehazeNet.caffemodel', caffe.TEST)
net_full_conv.params['ip1-conv'][0].data.flat = net.params['ip1'][0].data.flat
net_full_conv.params['ip1-conv'][1].data[...] = net.params['ip1'][1].data
# Load and pad image
im = caffe.io.load_image(im_path)
npad = ((7,8), (7,8), (0,0))
im_padded = np.pad(im, npad, 'symmetric')
transmission = np.zeros((height, width))
# Setup transformer for the tile size
transformers = caffe.io.Transformer({'data': net_full_conv.blobs['data'].data.shape})
transformers.set_transpose('data', (2,0,1))
transformers.set_channel_swap('data', (2,1,0))
# Process in tiles
for h in range(0, height, tile_h):
for w in range(0, width, tile_w):
# Calculate start/end to handle edges/overlap
# If we are at the end, shift back to ensure we feed a full tile
h_start = min(h, height - tile_h)
w_start = min(w, width - tile_w)
# Extract patch from PADDED image
# Network expects input size of (Tile + 15), so we slice accordingly
patch = im_padded[h_start : h_start + tile_h + 15, w_start : w_start + tile_w + 15, :]
# Forward pass
out = net_full_conv.forward_all(data=np.array([transformers.preprocess('data', patch-0.2)]))
# Reshape output
block_trans = np.reshape(out['ip1-conv'], (tile_h, tile_w))
# Assign to result buffer
transmission[h_start : h_start + tile_h, w_start : w_start + tile_w] = block_trans
return transmission
else:
# Original logic for small images
EditFcnProto('DehazeFcnTemplate.prototxt', height, width)
net = caffe.Net('DehazeNet.prototxt', 'DehazeNet.caffemodel', caffe.TEST)
net_full_conv = caffe.Net('DehazeNetFcn.prototxt', 'DehazeNet.caffemodel', caffe.TEST)
net_full_conv.params['ip1-conv'][0].data.flat = net.params['ip1'][0].data.flat
net_full_conv.params['ip1-conv'][1].data[...] = net.params['ip1'][1].data
im = caffe.io.load_image(im_path)
npad = ((7,8), (7,8), (0,0))
im = np.pad(im, npad, 'symmetric')
transformers = caffe.io.Transformer({'data': net_full_conv.blobs['data'].data.shape})
transformers.set_transpose('data', (2,0,1))
transformers.set_channel_swap('data', (2,1,0))
out = net_full_conv.forward_all(data=np.array([transformers.preprocess('data', im-0.2)]))
transmission = np.reshape(out['ip1-conv'], (height,width))
return transmission
def DarkChannel(im,sz):
b,g,r = cv2.split(im)
dc = cv2.min(cv2.min(r,g),b)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz))
dark = cv2.erode(dc,kernel)
return dark
def AtmLight(im,dark):
[h,w] = im.shape[:2]
imsz = h*w
numpx = int(max(math.floor(imsz/1000),1))
darkvec = dark.reshape(imsz,1)
imvec = im.reshape(imsz,3)
indices = darkvec.argsort()
indices = indices[imsz-numpx::]
atmsum = np.zeros([1,3])
for ind in range(1,numpx):
atmsum = atmsum + imvec[indices[ind]]
A = atmsum / numpx
return A
def Guidedfilter(im,p,r,eps):
mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r))
mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r))
mean_Ip = cv2.boxFilter(im*p,cv2.CV_64F,(r,r))
cov_Ip = mean_Ip - mean_I*mean_p
mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r))
var_I = mean_II - mean_I*mean_I
a = cov_Ip/(var_I + eps)
b = mean_p - a*mean_I
mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r))
mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r))
q = mean_a*im + mean_b
return q
def TransmissionRefine(im,et):
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
gray = np.float64(gray)/255
r = 60
eps = 0.0001
t = Guidedfilter(gray,et,r,eps)
return t
def Recover(im,t,A,tx = 0.1):
res = np.empty(im.shape,im.dtype)
t = cv2.max(t,tx)
for ind in range(0,3):
res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind]
return res
def getFileList(dir,Filelist, ext=None):
"""
获取文件夹及其子文件夹中文件列表
输入 dir文件夹根目录
输入 ext: 扩展名
返回: 文件路径列表
"""
newDir = dir
if os.path.isfile(dir):
if ext is None:
Filelist.append(dir)
else:
if ext in dir[-3:]:
Filelist.append(dir)
elif os.path.isdir(dir):
for s in os.listdir(dir):
newDir=os.path.join(dir,s)
getFileList(newDir, Filelist, ext)
return Filelist
if __name__ == '__main__':
if not len(sys.argv) == 2:
print ('Usage: python DeHazeNet.py haze_img_path')
exit()
else:
im_path = sys.argv[1]
# 检索文件
src_img_folder = os.path.join(im_path, 'src')
imglist = getFileList(src_img_folder, [], '')
print('本次执行检索到 '+str(len(imglist))+' 张图像\n')
for img_path in imglist:
imgname= os.path.splitext(os.path.basename(img_path))[0]
src = cv2.imread(img_path)
height = src.shape[0]
width = src.shape[1]
# Note: EditFcnProto is also called inside TransmissionEstimate if tiling is used
# We call it here for initialization but it may be overwritten.
templateFile = 'DehazeFcnTemplate.prototxt'
EditFcnProto(templateFile, height, width)
print("-"*5, ' 完成EditFcnProto ',"-"*5)
I = src/255.0
dark = DarkChannel(I,15)
A = AtmLight(I,dark)
te = TransmissionEstimate(img_path, height, width)
t = TransmissionRefine(src,te)
J = Recover(I,t,A,0.1)
print("Finsh All the operation")
Trans_Esti_imgdir = os.path.join(im_path, 'Trans_Esti/')
if not os.path.exists(Trans_Esti_imgdir): os.makedirs(Trans_Esti_imgdir)
print(Trans_Esti_imgdir + imgname + "_Trans_Esti.png")
cv2.imwrite(Trans_Esti_imgdir + imgname + "_Trans_Esti.png",te*255);
Trans_Refine_imgdir = os.path.join(im_path, 'Trans_Refine/')
if not os.path.exists(Trans_Refine_imgdir): os.makedirs(Trans_Refine_imgdir)
print(Trans_Refine_imgdir + imgname + "_Trans_Refine.png")
cv2.imwrite(Trans_Refine_imgdir + imgname + "_Trans_Refine.png",t*255);
result_imgdir = os.path.join(im_path, 'result/')
if not os.path.exists(result_imgdir): os.makedirs(result_imgdir)
print(result_imgdir + imgname + "_result.png")
cv2.imwrite(result_imgdir + imgname + "_result.png",J*255);

31
DehazeNet/readme.md Normal file
View File

@@ -0,0 +1,31 @@
## Reimplement
## *DehazeNet: An End-to-End System for Single Image Haze Removal*
Bolun Cai, Xiangmin Xu, Kui Jia, Chunmei Qing, Dacheng Tao
## Requirement
> * caffe
> * opencv2
## Usage:
simply type
```shell
python DehazeNet.py image_path
```
## Demo:
![canon](img/canon.jpg)
![canon_Dehaze](img/canon_Dehaze.jpg)
![cones](img/cones.jpg)
![cones_Dehaze](img/cones_Dehaze.jpg)
## Site:
@article{cai2016dehazenet,
title={Dehazenet: An end-to-end system for single image haze removal},
author={Cai, Bolun and Xu, Xiangmin and Jia, Kui and Qing, Chunmei and Tao, Dacheng},
journal={IEEE Transactions on Image Processing},
volume={25},
number={11},
pages={5187--5198},
year={2016},
publisher={IEEE}
}