Identify objects moving on a conveyor belt using Opencv with Python
In this tutorial we will learn how to create a simple prototype to detect objects passing on a conveyor belt.
We will use exagonal nuts as objects. I have two sizes, a small one and a bigger one. If the small nuts are detected the belt keeps moving, in case a bigger one is detected, the conveyor is going to stop automatically.
This project is done using a:
- Small conveyor belt which is turned on/off by using a relay.
- Raspberry PI.
In this article I will only describe the code only for the key parts of the project. If you want to understand all the source code, you can follow the video tutorial where I explain everything.
1. Detect Objects on the conveyor
Considering that the view from the webcam takes also elements outside of the belt, we need first to cut the area of the belt and remove everything else.
# Belt belt = frame[209: 327, 137: 280] gray_belt = cv2.cvtColor(belt, cv2.COLOR_BGR2GRAY)
Once we have the belt, it’s easy to detect the objects that are on it because the belt is green and the nuts are gray, so a simple threshold operation can easily make a distinction between the belt and the objects.
_, threshold = cv2.threshold(gray_belt, 80, 255, cv2.THRESH_BINARY)
First thing we need to find the contours. Contours are the boundaries of an object, in this case, the boundaries of the nuts.
# Detect the Nuts _, contours, _ = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: (x, y, w, h) = cv2.boundingRect(cnt)
Then we get to key part of the project where we make the actual distinction between a big and a small nut.
We can do this by calculating the area of the contour. The small nut has a area of around 250 pixels, while the big nut is above 400 pixel.
So we define the conditions, if the are is greater than 400 it’s a big nut and we make draw a red rectangle.
if the area is between 100 and 400 we make a blue rectangle.
Everything smaller than a hundred pixel can be considered as noise, so that we we discard it.
# Calculate area area = cv2.contourArea(cnt) # Distinguish small and big nuts if area > 400: # big nut cv2.rectangle(belt, (x, y), (x + w, y + h), (0, 0, 255), 2) elif 100 < area < 400: cv2.rectangle(belt, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.putText(belt, str(area), (x, y), 1, 1, (0, 255, 0))
2. Run/Stop the conveyor belt
To run/stop the conveyor we use a Relay connected to the raspberry pi.
We can consider the relay as a Switch button which can turn on/off the current for the motor which runs the conveyor.
We can turn it on/off with a simple command:
import conveyor_lib # Conveyor belt library relay = conveyor_lib.Conveyor() # Stop belt relay.turn_off() # Start belt relay.turn_on()