I'd like to remove shadow before image binarization using OpenCV. I've tried Otsu Method and adaptive thresholding, however for images where there are large regions of shadow, these two methods will not give good results.
Any better solutions? Thanks in advance.
]1
]2
Shadow removal is an important computer vision task aiming at the detection and successful removal of the shadow produced by an occluded light source and a photo-realistic restoration of the image contents.
Instance shadow detection is a brand new problem, aim- ing to find shadow instances paired with object instances. To approach it, we first prepare a new dataset called SOBA, named after Shadow-OBject Association, with 3,623 pairs of shadow and object instances in 1,000 photos, each with individually-labeled masks.
Since you didn't specify any language, I'll assume Python to illustrate.
A decent starting point might be taking the approach I show in this answer and expand it to work with multiple channels.
Something along the lines of
import cv2 import numpy as np img = cv2.imread('shadows.png', -1) rgb_planes = cv2.split(img) result_planes = [] result_norm_planes = [] for plane in rgb_planes: dilated_img = cv2.dilate(plane, np.ones((7,7), np.uint8)) bg_img = cv2.medianBlur(dilated_img, 21) diff_img = 255 - cv2.absdiff(plane, bg_img) norm_img = cv2.normalize(diff_img,None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1) result_planes.append(diff_img) result_norm_planes.append(norm_img) result = cv2.merge(result_planes) result_norm = cv2.merge(result_norm_planes) cv2.imwrite('shadows_out.png', result) cv2.imwrite('shadows_out_norm.png', result_norm)
The non-normalized result looks as follows:
And the normalized result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With