rain.py 1.9 KB
Newer Older
jm_12138's avatar
jm_12138 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
import cv2
import numpy as np

__all__ = ['Rain']


class Rain():
    def __init__(self, rain_cap_path, rain_intensity=1.0, haze_intensity=4.0, gamma=2.0, light_correction=0.9):
        self.rain_intensity = rain_intensity
        self.haze_intensity = haze_intensity
        self.gamma = gamma
        self.light_correction = light_correction
        self.frame_id = 1

        self.cap = cv2.VideoCapture(rain_cap_path)

    def _get_rain_layer(self):
        ret, frame = self.cap.read()
        if ret:
            rain_layer = frame
        else:  # if reach the last frame, read from the begining
            self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
            ret, frame = self.cap.read()
            rain_layer = frame

        rain_layer = cv2.cvtColor(rain_layer, cv2.COLOR_BGR2RGB) / 255.0
        rain_layer = np.array(rain_layer, dtype=np.float32)

        return rain_layer

    def _create_haze_layer(self, rain_layer):
        return 0.1*np.ones_like(rain_layer)

    def forward(self, img):
        # get input image size
        h, w, c = img.shape

        # create a rain layer
        rain_layer = self._get_rain_layer()

        rain_layer = cv2.resize(rain_layer, (w, h))
        rain_layer = cv2.blur(rain_layer, (3, 3))
        rain_layer = rain_layer * \
            (1 - cv2.boxFilter(img, -1, (int(w/10), int(h/10))))

        # create a haze layer
        haze_layer = self._create_haze_layer(rain_layer)

        # combine the rain layer and haze layer together
        rain_layer = self.rain_intensity*rain_layer + \
            self.haze_intensity*haze_layer

        # synthesize an output image (screen blend)
        img_out = 1 - (1 - rain_layer) * (1 - img)

        # gamma and light correction
        img_out = self.light_correction*(img_out**self.gamma)

        # check boundary
        img_out = np.clip(img_out, a_min=0, a_max=1.)

        return img_out