Search code examples
pythonopencvimage-processingcomputer-visionimage-thresholding

OpenCV Thresholding adaptive to different lightning conditions


For a school project I am trying to write a program in Python that tracks the movement of the pupil. In order to do that I am using OpenCV. After looking up some tutorials on the internet, I noticed that almost everyone is using thresholding to achieve this, since a binary image is necessary for almost every step further down the road (e.g. HoughCircle Transofrmation, Contours). However, from my understanding thresholding is extremly light sensitive, therefore such an approach would only return good results in optimal lightning conditions. So here comes my question: Is there any alternative or better approach than just Thresholding the image? Or is my understanding of thresholding in OpenCV wrong in the first place?

Here is a example image:

example image


Solution

  • The purpose of thresholding is to segment the desired objects from the background where you can then perform additional processing (applying morphological operations) then perform contour filtering to further isolate the desired objects. Instead of applying image processing techniques on a BGR (3-channel) image or a grayscale (1-channel) image with range [0...255], thresholding allows us to obtain a binary image where every pixel is either 0 or 1 which makes distinguishing objects easier. Depending on your situation, there are many ways obtain a binary image, here are several methods:

    • cv2.Canny - Canny edge detection which uses a minVal and maxVal to determine edges

    • cv2.threshold - Simple thresholding with user selected arbitrary global threshold value

    • cv2.threshold + cv2.THRESH_OTSU - Otsu's thresholding to automatically calculate the threshold value.

    • cv2.adaptiveThreshold - Adaptive thresholding where the image has different lighting conditions in different areas. Essentially it will automatically calculate the threshold value for different regions of the image and gives better results with images with varying illumination

    • cv2.inRange - Color segmentation. The idea is to use lower and upper threshold ranges to obtain a binary image. Useful when trying to isolate a single color range