1

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

2
  • Significant parts of the box (especially the top) are lighter than the shadow. Using a global threshold, you will always end up with either all the box and some shadow, or no shadow with lots of the box missing. Commented Nov 25, 2016 at 18:11
  • Please provide the input image separately ? Commented Nov 26, 2016 at 5:03

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.