1

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()
TheTeapot
  • 11
  • 1
  • 1
    Is it possible that your serial device is sending two "Testing" responses over-the-wire in short succession, causing it to fire twice in the `while True` loop? – Toastrackenigma Apr 10 '21 at 14:34
  • @Toastrackenigma I have a Arduino as the serial device, but no I just checked, I also just reviece one "Testing" and it can't send two "Testing". The function also runs twice in a python shell – TheTeapot Apr 10 '21 at 14:43

0 Answers0