|
- """
- /**
- * Copyright 2020 Zhejiang Lab. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * =============================================================
- */
- """
-
- import cv2
- import numpy as np
- import math
- para = {}
-
- def ACE(img, ratio=4, radius=300):
- """The implementation of ACE"""
- global para
- para_mat = para.get(radius)
- if para_mat is not None:
- pass
- else:
- size = radius * 2 + 1
- para_mat = np.zeros((size, size))
- for h in range(-radius, radius + 1):
- for w in range(-radius, radius + 1):
- if not h and not w:
- continue
- para_mat[radius + h, radius + w] = 1.0 / \
- math.sqrt(h ** 2 + w ** 2)
- para_mat /= para_mat.sum()
- para[radius] = para_mat
- h, w = img.shape[:2]
- p_h, p_w = [0] * radius + list(range(h)) + [h - 1] * radius,\
- [0] * radius + list(range(w)) + [w - 1] * radius
- temp = img[np.ix_(p_h, p_w)]
- res = np.zeros(img.shape)
- for i in range(radius * 2 + 1):
- for j in range(radius * 2 + 1):
- if para_mat[i][j] == 0:
- continue
- res += (para_mat[i][j] *
- np.clip((img - temp[i:i + h, j:j + w]) * ratio, -1, 1))
- return res
-
- def ACE_channel(img, ratio, radius):
- """The implementation of ACE through individual channel"""
- h, w = img.shape[:2]
- if min(h, w) <= 2:
- return np.zeros(img.shape) + 0.5
- down_ori = cv2.pyrDown(img, ((w + 1) // 2, (h + 1) // 2))
- temp = ACE_channel(down_ori, ratio, radius)
- up_temp = cv2.resize(temp, (w, h))
- up_ori = cv2.resize(down_ori, (w, h))
- re = up_temp + ACE(img, ratio, radius) - ACE(up_ori, ratio, radius)
- return re
-
- def ACE_color(img, ratio=4, radius=3):
- """Enhance the image through RGB channels"""
- re = np.zeros(img.shape)
- for c in range(3):
- re[:, :, c] = reprocessImage(ACE_channel(img[:, :, c], ratio, radius))
- return re
-
- def reprocessImage(img):
- """Reprocess and map the image to [0,1]"""
- ht = np.histogram(img, 2000)
- d = np.cumsum(ht[0]) / float(img.size)
- try:
- left = next(x for x in range(len(d)) if d[x] >= 0.005)
- except:
- left = 1999
- try:
- right = next(y for y in range(len(d)-1,0,-1) if d[y] <= 0.995)
- except:
- right = 1
- return np.clip((img - ht[1][left]) / (ht[1][right] - ht[1][left]), 0, 1)
|