Hi everyone!
First off sorry if this kind of question comes out a lot, this is my first post on this forum and I'm new. Anyway, I'm combining Python OpenCV with an Arduino-controlled arm for an agriculture project. For context, the ESP32 Camera will be checking for seeds in a hole and transferring that data to the Arduino-controlled robot arm to move in XYZ coordinates.
I'm currently working on using the ESP32 Camera to detect the number of seeds in a hole using Python OpenCV.
These are my 2 problems :
- How do I transfer the output data "counting" from Python to Arduino? don't understand what function to use to transfer the "counting" data to Arduino.
These are the guides I was referring to, and they only transfer strings.
- Is it possible to run Python and Arduino at the same time? If not, how do I automate Python and Arduino to run and close automatically?
I'm fairly new to Python and not much of an expert in Arduino so I need help with this.
Any new guides, forums, explanations, and code would be greatly appreciated.
Thank you!
#Declaring libraries
import cv2
import numpy as np
import matplotlib.pyplot as plt
import serial
#Get the image
image = cv2.imread(r"C:\Users\edu\Desktop\Personal Project\Python Projects\OpenCV Datasets\Testing_10Light\6cm.jpg")
#Increase brightness and contrast of the image
brightness = 3
contrast = 2.4
image2 = cv2.addWeighted(image, contrast, np.zeros(image.shape, image.dtype), 0, brightness)
#Sharpening image
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharpened_image = cv2.filter2D(image2, -1, kernel)
#Make the image B&W
gray = cv2.cvtColor(sharpened_image, cv2.COLOR_BGR2GRAY)
#Apply blur to get rid of noise
blur = cv2.GaussianBlur(gray, (11, 11), 0)
#Detect the edges of the object
canny = cv2.Canny(blur, 30, 150, 3)
#Connect the edges and fill in the gaps of unfinished edges
dilated = cv2.dilate(canny, (1, 1), iterations=0)
#Find the contours in the image
(cnt, hierarchy) = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
cv2.drawContours(rgb, cnt, -1, (0, 255, 0), 2)
counting = len(cnt)
#Send the output to Arduino
ser = serial.Serial('COM6', 9600) #Arduino PORT at 9600 baud rate
ser.write(str(counting).encode())
print("number of seeds : ", counting)
#Display
plt.imshow(sharpened_image)
plt.show()
plt.imshow(rgb)
plt.show()
ser.close() # Close the serial port
This is the original code combining ESP32 Camera with Arduino which I haven't connected yet, but here is just a reference.
import cv2
import numpy as np
import urllib.request
import matplotlib.pyplot as plt
import serial
URL = 'http://194.18.15.175'
cap = cv2.VideoCapture(URL + ":81/stream")
while True:
success, img = cap.read()
#Sharpening image
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharp_img = cv2.filter2D(img, -1, kernel)
# Convert to grayscale
gray_img = cv2.cvtColor(sharp_img, cv2.COLOR_BGR2GRAY)
#Apply blur to get rid of noise
blur = cv2.GaussianBlur(gray_img, (11, 11), 0)
#Detect the edges of the object
canny = cv2.Canny(blur, 30, 150, 3)
#Connect the edges and fill in the gaps of unfinished edges
dilated = cv2.dilate(canny, (1, 1), iterations=0)
#Find the contours in the image
(cnt, hierarchy) = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.drawContours(rgb, cnt, -1, (0, 255, 0), 2)
#len = return number of items
#cnt = count number of items
counting = len(cnt)
print("number of seeds : ", counting)
#Send the output to Arduino
ser = serial.Serial('COM6', 9600) #Arduino PORT
ser.write(str(counting).encode())
#Display live feed showing contours of seeds
cv2.imshow("CAM", dilated)
cv2.waitKey(1)
cap.release()
cv2.destroyAllWindows()
Simple Arduino(COM6) code to light up PIN13
const int ledPin13 = 10;
void setup() {
pinMode(ledPin13, OUTPUT); // Set pin as output
Serial.begin(9600); // Begin serial communication at 9600 bps
}
void loop()
{
if (Serial.available() > 0) { // If data is available to read
int seedCount = Serial.parseInt(); // Read the incoming data as integer
if (seedCount > 3)
{ // If seed count is greater than 3
Serial.print("TOO MUCH");
digitalWrite(ledPin13, HIGH); // Turn the LED on
delay(5000);
}
else if (seedCount == 3)
{
digitalWrite(ledPin13, LOW); // Turn the LED off
Serial.print("GOOD");
}
else
{
Serial.print("ERROR");
}
}
}