Reputation: 5031
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.
Upvotes: 1
Views: 1457
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:
Now the second box which you so frequently post:
I always wanted to try out the following. Give it a try and do let me know:
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
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:
Now playing with the morphological operations mentioned on THIS PAGE you can obtain your desired object.
Upvotes: 2