Dor
Dor

Reputation: 127

OpenCV Detect scratches on fruits

For a little experiment in Python I'm doing I want to find small scratches on fruits. The scratches are very small and hard to detect by human eye.

I'm using a high resolution camera for that experiment.

Here is the defect I want to detect:

enter image description here

Original Image:

enter image description here

This is my result with very few lines of code:

enter image description here

So I found the contours of my fruit. How can I proceed to finding the scratch? The RGB Value is similar to other parts of the fruit. So how can I differentiate between A scratch, and a part of the fruit?

My code:

# Imports
import numpy as np
import cv2
import time

# Read Image & Convert
img = cv2.imread('IMG_0441.jpg')
result = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Filtering
lower = np.array([1,60,50])
upper = np.array([255,255,255])
result = cv2.inRange(result, lower, upper)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9,9))
result = cv2.dilate(result,kernel)

# Contours
im2, contours, hierarchy = cv2.findContours(result.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
result = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
if len(contours) != 0:
    for (i, c) in enumerate(contours):
        area = cv2.contourArea(c)
        if area > 100000:
            print(area)
            cv2.drawContours(img, c, -1, (255,255,0), 12)
            x,y,w,h = cv2.boundingRect(c)            
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),12)

# Stack results
result = np.vstack((result, img))
resultOrig = result.copy()

# Save image to file before resizing
cv2.imwrite(str(time.time())+'_0_result.jpg',resultOrig)

# Resize
max_dimension = float(max(result.shape))
scale = 900/max_dimension
result = cv2.resize(result, None, fx=scale, fy=scale)

# Show results
cv2.imshow('res',result)

cv2.waitKey(0)
cv2.destroyAllWindows()

Upvotes: 5

Views: 4041

Answers (3)

Bull
Bull

Reputation: 11941

I changed your image to HSL colour space. I can't see the scratch in the L channel, so the greyscale approach suggested earlier is going to be difficult. But the scratch is quite noticeable in the hue plane. The scratch is quite noticeable in the hue plane

You could use an edge detector to find the blemish in the hue channel. Here I use a difference of gaussians detector (with sizes 20 and 4).

DOG

Upvotes: 2

If you really want to use conventional computer vision techniques, you should start with edges that can be detected on the fruit. Some of the edges are caused by the bumps on the fruit, so you have to look at various features of the area around the edges to find the difference between scratches and bumps. After you look at about a hundred scratches, you should be able to come up with some rules.

But this process is going to be very tiring, and my guess is you will not have much luck. A better way to approach this problem is to train a deep neural network by manually annotating scratches on about 100 images, and letting the network find out by itself how to distinguish scratches from the rest of the fruit.

If you are a beginner to these stuff, search for PyImageSearch and LearnOpenCV. Both are very resourceful sites where you can learn quickly.

Upvotes: 1

lX-Xl
lX-Xl

Reputation: 160

personal guess is to use some algorithm to detect the grayscale change. The grayscale variation around the scratch should be bigger than the variation in other area. Sobel and Scharr Derivatives could be an option. This is a link to python-openCV about image gradient. You can first crop out the fruit with coutour application

Upvotes: 1

Related Questions