Home How to remove noise after Otsu Binarization using OpenCV in Python?
 I am using a Raspberry Pi and it's Camera to perform some Image Processing algorithm. So , I am performing a background subtraction on successive frames of the captured stream and trying to find if there is any object present in the image and if yes, print out it's area . The algorithm works fine as expected but there is a problem . The thresholding function which uses cv2.THRESH_OTSU , results into a grainy image whenever there is no object present , i.e the background and the foreground images are same . However those noises/grain disappear when there is an object present in the foreground image . These are as follows - Same Background Image and Foreground Image with noise Different Background and Foreground Image without any noise As you can see ,if the images are almost same , the noise is present and if any object is introduced in the frame , then the noise vanishes . I have tried the following to remove the noise but it didn't work . Tried using only cv2.THRESH_BINARY / cv2.THRESH_BINARY_INV without Otsu binariszation. I have tried increasing the brightness/contrast/saturation of the captured image to see if the performance varies , but no change . I have tried to increase/decrease the amount of erosion/dilation preceding the Thresholding step , but this did not make any change either . This is my code - from time import sleep from picamera import PiCamera from picamera.array import PiRGBArray import cv2,os import numpy as np import threading def imageSubtract(img): bilateral_filtered_image = cv2.bilateralFilter(img, 9, 170, 170) bilateral_filtered_image = cv2.cvtColor(bilateral_filtered_image,cv2.COLOR_BGR2GRAY) return bilateral_filtered_image def imageProcessing(): camera = PiCamera() camera.resolution = (512,512) camera.awb_mode="fluorescent" camera.iso = 800 camera.contrast=33 camera.brightness=75 camera.sharpness=100 rawCapture = PiRGBArray(camera, size=(512, 512)) first_time=0 frame_buffer=0 counter=0 camera.start_preview() sleep(2) for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): if first_time==0: rawCapture.truncate(0) if frame_buffer<10: print("Frame rejected -",str(frame_buffer)) frame_buffer+=1 continue os.system("clear") refImg=frame.array refThresh=imageSubtract(refImg) first_time=1 image = frame.array cv2.imshow("Foreground", image) key = cv2.waitKey(1) rawCapture.truncate(0) newThresh=imageSubtract(image) diff=cv2.absdiff(refThresh,newThresh) kernel = np.ones((5,5),np.uint8) diff=cv2.dilate(diff,kernel,iterations = 3) cv2.imshow("Background",refImg) _, thresholded = cv2.threshold(diff, 0 , 255, cv2.THRESH_BINARY +cv2.THRESH_OTSU) _, contours, _= cv2.findContours(thresholded,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) try: c=max(contours,key=cv2.contourArea) x,y,w,h = cv2.boundingRect(c) cv2.rectangle(thresholded,(x,y),(x+w,y+h),(125,125,125),2) if cv2.contourArea(c)>500: print("Object detected with area = ",cv2.contourArea(c)) cv2.imshow("Threshold",thresholded) if key == ord('q'): camera.close() cv2.destroyAllWindows() break except Exception as e: pass if __name__ == "__main__" : imageProcessing()  Please help me to remove the noise when the background and foreground Images are same . Thank You !