I have a function called color_shape() , in the file color_shape_detection_1, that detects the color and the shape of an object which uses OpenCV to do that. In that same file I also have other functions that take a picture and check if the object is somewhere in the middle of the picture. In another file, control, that is in the same folder, I import all the functions from color_shape_detection_1. But if the function color_shape() is used in control, it runs twice. The function runs also twice when it is executed in a python shell. I tried this , also this to find a solution here on stackoverflow already but nothing helped. I just uploaded the function because the file ist long but if you need the whole file I can upload that too. I have also a a older file where the detecting is not in a function and that file only runs once.
I hope that someone can help me and thanks in advance already
The code of color_shape():
def color_shape():
#picture()
position()
while p < 1:
position()
print("Detecting...")
cutting()
font = cv2.FONT_HERSHEY_COMPLEX #Font bestimmen
img = cv2.imread("/home/pi/Final/objekt_1.jpg") #Bild für Formerkennung laden
with Image.open("/home/pi/Final/objekt_1.jpg") as im: #Bild für Farberkennung laden
px = im.load()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Bild in graustufen darstellen
edged = cv2.Canny(gray, 30, 200, L2gradient = True) #mit Canny Ecken finden
contours, hierarchy = cv2.findContours(edged, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #Kontouren finden
for cnt in contours:
epsilon = 0.01*cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True) #Approximation der Formen
M = cv2.moments(cnt)
area = cv2.contourArea(cnt)
if len(approx) == 3 and area > 200: #Ecken der Konturen werden gezählt, 3 Ecken -> Dreieck
shape_name = "Triangle"
cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2) #Kontur ins Bild zeichnen
print(area)
cx = int(M["m10"] / M["m00"]) #Mittelpunkt der Form finden, um Beschriftung
cy = int(M["m01"] / M["m00"]) #richtig zu positionieren
cv2.putText(img, shape_name, (cx-50, cy), font, 1, (0, 0, 0), 1)
color = px[cx, cy] #Farbe in der Mitte der Form entnehmen in RGB
print(color)
if all(x < y for x,y in zip(red_lower, color)) and all(x < y for x,y in zip(color, red_upper)):
cv2.putText(img, "red", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "a"
if all(x < y for x,y in zip(green_lower, color)) and all(x < y for x,y in zip(color, green_upper)):
cv2.putText(img, "green", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "b"
if all(x < y for x,y in zip(blue_lower, color)) and all(x < y for x,y in zip(color, blue_upper)):
cv2.putText(img, "blue", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "c"
elif len(approx) == 4 and area > 200: #4 Ecken -> Rechteck/Quadrat
shape_name = "Rec"
cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2) #Kontur ins Bild zeichnen
print(area)
cx = int(M["m10"] / M["m00"]) #Mittelpunkt der From finden, um Beschriftung
cy = int(M["m01"] / M["m00"]) #richtig zu positionieren
cv2.putText(img, shape_name, (cx-25, cy), font, 1, (0, 0, 0), 1)
color = px[cx, cy] #Pixel in der mitte der Form einlesen
print(color) #RGB des Pixels schreiben
if all(x < y for x,y in zip(red_lower, color)) and all(x < y for x,y in zip(color, red_upper)):
cv2.putText(img, "red", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "d"
if all(x < y for x,y in zip(green_lower, color)) and all(x < y for x,y in zip(color, green_upper)):
cv2.putText(img, "green", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "e"
if all(x < y for x,y in zip(blue_lower, color)) and all(x < y for x,y in zip(color, blue_upper)):
cv2.putText(img, "blue", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "f"
elif 12 < len(approx) < 200 and area > 200: #viele Ecken -> Kreis
shape_name = "Circle"
cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2) #Kontur ins Bild zeichnen
print(area)
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.putText(img, shape_name, (cx-50, cy), font, 1, (0, 0, 0), 1)
color = px[cx, cy]
print("Color detected:", color)
if all(x < y for x,y in zip(red_lower, color)) and all(x < y for x,y in zip(color, red_upper)):
cv2.putText(img, "red", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "g"
if all(x < y for x,y in zip(green_lower, color)) and all(x < y for x,y in zip(color, green_upper)):
cv2.putText(img, "green", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "h"
if all(x < y for x,y in zip(blue_lower, color)) and all(x < y for x,y in zip(color, blue_upper)):
cv2.putText(img, "blue", (cx-50, cy+25), font, 1, (0, 0, 0), 1)
name = "i"
#cv2.imshow("bw", edged)
cv2.imshow("shapes", img) #Fenster mit den eingezeichneten Formen zeigen
cv2.waitKey(10000)
sleep(5) #nach ca. 10 Sekunden Fenster schließen
cv2.destroyAllWindows()
b = bytes(name, "utf-8")
print(name) #Ardu schreiben Objekt+Farbe
print(shape_name)
ser.write(b)
and in the control file:
import time
import serial
from color_shape_detection_1 import*
ser = serial.Serial(
port="/dev/ttyAMA0", #Port für die serielen Übertragung
baudrate = 9600,
parity = serial.PARITY_NONE, #Seriele Übertragung festlegen
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 1
)
try:
while True:
response = ser.readline()
print(response)
if response == b'Testing\r\n':
print("Going active!")
color_shape()
except KeyboardInterrupt:
print("Bye")
ser.close()