muazfaiz
muazfaiz

Reputation: 5031

OpenCV - Managing thresholds in image processing with python

I am new to image processing and I am processing the following image and applying threshold to identify edges with the following code

import cv2
import numpy as np

img = cv2.imread("box.jpg")
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
noise_removal = cv2.bilateralFilter(img_gray,9,75,75)
ret,thresh_image = cv2.threshold(noise_removal,0,255,cv2.THRESH_OTSU)

On the left is the original image. In the middle is the gray image calculated by img_gray in the code. On the right is the threshold image calculated by thresh_imgage.

My question is from image 1 and 2 we can see that there is a significant change in the gradient at the corners but in the threshold image it is also including shadow as the part of box object.

I have run the code several times by changing threshold values but did not succeed to get only the box. What am I doing wrong ? Can someone help in this ? Thanks.

enter image description here

Upvotes: 1

Views: 1457

Answers (2)

Jeru Luke
Jeru Luke

Reputation: 21233

I just came across another solution regarding selection of optimal thresholds for edge detection. My previous answer was about adaptive threshold of which you know very well.

By optimal I mean choosing a two values (lower and upper thresholds) based on the median value of the gray scale image. The following code shows you how its done:

v = np.median(gray_img)
sigma = 0.33

#---- apply optimal Canny edge detection using the computed median----
lower_thresh = int(max(0, (1.0 - sigma) * v))
upper_thresh = int(min(255, (1.0 + sigma) * v))
edge_img = cv2.Canny(gray_img, lower_thresh, upper_thresh)
cv2.imshow('Edge_of_box',edge_img)

The sigma value of 0.33 is the most optimal value in the field of data science.

Illustration: If you observe a Gaussian curve in statistics, values between 0.33 from both sides of the curve are considered in the distribution. Any value outside these points are assumed to be outliers. Since images are considered to be data, this concept is assumed here as well.

Have a look at this:

enter image description here

Now the second box which you so frequently post:

enter image description here

How can you improve this?

I always wanted to try out the following. Give it a try and do let me know:

  • First try replacing median value with mean and observe the results.
  • Change the sigma value and observe how edge detection changes.
  • Try performing the above mentioned technique for a small patch of the image. Divide the image into small patches and work your way through. (My way of saying 'Localized edge detection')

There might be better ways to detect out there which I have not come across yet. But this is a great and fun way to start.

Upvotes: 1

Jeru Luke
Jeru Luke

Reputation: 21233

You should have considered trying adaptive threshold

adp_th = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 5, 1.8)

This is what I got:

enter image description here

Now playing with the morphological operations mentioned on THIS PAGE you can obtain your desired object.

Upvotes: 2

Related Questions