0

I want to draw the edges of tomatoes in crate. For this I'm using Canny edge detection algorithm. The problem with it is that in a crate some of the tomatoes are over the top of the other as shown in the figure bellow:

org

As one can see some of the tomatoes have more light over them than the other, due to this the result by Canny is as follows:

canny

As one can see Canny is not able to detect the edges of the tomatoes at the end of the crate where the light is low in the original image.

Does anyone have any solution to this ? (It's not possible to get uniform light on all the tomatoes, but if there is some algorithm that can do that would be really helpful.)

Here is my OpenCV code:

#include <opencv2/opencv.hpp>

using namespace cv;

Mat img, img_gray, img_value, fz, fg, I, pre, cost, vis, G, img_draw, in_que, skip, img_canny;

int main(){
    std::string filepath = "/Users/vedanshu/Desktop/IMG_5207.JPG";
    img = imread(filepath);
    cvtColor(img, img_gray, cv::COLOR_BGRA2GRAY);
    img_gray.copyTo(img_value);
    GaussianBlur(img_value, img_value, Size(3, 3), 0, 0, BORDER_DEFAULT);
    Canny(img_gray, img_canny, 50, 50);
    imwrite( "/Users/vedanshu/Desktop/test_canny.png", img_canny );
}
Vedanshu
  • 2,230
  • 23
  • 33
  • To get better contrast, you could try [CLAHE](https://stackoverflow.com/a/24341809). Also, instead of Canny, you could try a [Hough circle transform](https://docs.opencv.org/3.4.0/d4/d70/tutorial_hough_circle.html) to also detect "partial" tomatoes. This will likely fail for the non-circular tomatoes, though. – chtz Feb 08 '19 at 15:55
  • Drawing boundaries around each tomato in a container like this robustly is an impossible task. However, if you state your overall problem you are trying to solve, we can propose feasible solutions to it. – Ajay Feb 09 '19 at 18:01
  • @Ajay The overall problem is to detect defects from the normal tomatoes. As you can see in the image there are some defects in some tomatoes, I have to find those defects by anyway. – Vedanshu Feb 13 '19 at 05:10
  • In that case, delineation of the boundary may not be important for you to decide if there is a defective tomato. I would suggest you to use sliding windows with a CNN based image classifier to solve your problem. My general recommendation is to avoid segmentation in favor of a bounding box if knowing the object boundary doesn't play a significant role in your overall objective. – Ajay Feb 14 '19 at 08:08

1 Answers1

2

I am answering in python, it can be easily converted to C++. Histogram equalization and gamma function can be used to increase the contrast of image in grayscale.

img = cv2.imread('edge_tomatoes.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('original', gray)
denoise = cv2.fastNlMeansDenoising(gray,None,10,7,21)
hist = cv2.equalizeHist(denoise)
gamma = 2
invGamma = 1/gamma
table = np.array([((i / 255.0) ** invGamma) * 255
                  for i in np.arange(0, 256)]).astype("uint8")
gamm = cv2.LUT(hist, table, hist)
blur = cv2.GaussianBlur(gamm,(3,3),0)
cv2.imshow('modified', hist)
cv2.waitKey(0)
cv2.destroyAllWindows()

Contrast enhanced This image shows the difference between the original grayscale image and processed image.

mask = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
canny = cv2.Canny(mask, 40, 200)
cv2.imshow('result', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result

Vardan Agarwal
  • 2,023
  • 2
  • 15
  • 27