Exemple #1
0
def main():
    import tiltpan
    import myconfig
    from time import sleep
    import numpy as np

    print("*** myDistSensor.py main() ****")
    print("\nTesting adjustReadingInMMForError()")
    print("Polyfit Formula: Adjusted_Actual = %.5f * Reading + %.4f" % (m, b))
    print(
        "\nFor reference_reading of %.1f and reference_actual of %.1f, adjustReadingInMMForError returns %.1f"
        % (X1, Y1, adjustReadingInMMForError(X1)))
    print(
        "\nFor reference_reading of %.1f inches (in MM) and reference_actual of %.1f inches (in MM), adjustReadingInMMForError returns %.1f inches (in MM)"
        % (X2 / 25.4, Y2 / 25.4, adjustReadingInMMForError(X2) / 25.4))

    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    myconfig.setParameters(egpg)
    ds = init(egpg)
    tp = tiltpan.TiltPan(egpg)

    print("\n\nPlace Carl at known distance from wall")
    sleep(5)
    print("Taking Measurement")
    mDl = []
    for i in xrange(0, 100):
        mDl += [ds.read_mm()]
        sleep(0.1)
    measuredDistance = np.mean(mDl)
    correctedDistance = adjustReadingInMMForError(measuredDistance)
    print(
        "average of %d measured_readings: %.1f mm = adjusted_distance: %.1f mm"
        % (len(mDl), measuredDistance, correctedDistance))
Exemple #2
0
def main():
    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    myconfig.setParameters(egpg)
    tp = tiltpan.TiltPan(egpg)

    tp.tiltpan_center()
    print("tiltpan centered")
    sleep(0.2)
    tp.off()
    print("tiltpan off")
Exemple #3
0
def main():
    if Carl: runLog.logger.info("Started")
    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    if Carl:
        myconfig.setParameters(egpg)  # configure custom wheel dia and base
        tp = tiltpan.TiltPan(egpg)  # init tiltpan
        print("centering")
        tp.tiltpan_center()
        print("centered")
        sleep(0.5)
        tp.off()
        print("tiltpan.off() complete")

    try:
        #  loop
        loopSleep = 10  # second
        loopCount = 0
        keepLooping = True
        while keepLooping:
            loopCount += 1
            # orbit_in_reverse(egpg, degrees= 45, radius_cm= egpg.WHEEL_BASE_WIDTH/2.0, blocking=True)
            # exit(0)

            print("\nTranslate 1 to 4 mm")
            for dist_mm in range(1, 5, 1):  # 1, 2, 3, 4 mm
                print("\nTranslateMm({:.0f}) {:.2f} inches".format(
                    dist_mm, dist_mm / 25.4))
                translateMm(egpg, dist_mm, debug=True)  # to the left
                sleep(5)
                print("\nTranslateMm({:.0f}) {:.2f} inches".format(
                    -dist_mm, -dist_mm / 25.4))
                translateMm(egpg, -dist_mm)  # to the right
                sleep(5)

            print("\nTranslate 3, 2, 1 inches")
            for dist_10x_mm in range(762, 0, -254):  # 3, 2, 1 inch
                dist_mm = dist_10x_mm / 10.0
                print("\nTranslateMm({:.0f}) {:.0f} inches".format(
                    dist_mm, dist_mm / 25.4))
                translateMm(egpg, dist_mm, debug=True)  # to the left
                sleep(5)
                print("\nTranslateMm({:.0f}) {:.0f} inches".format(
                    -dist_mm, -dist_mm / 25.4))
                translateMm(egpg, -dist_mm)  # to the right
                sleep(5)

            keepLooping = False
            #sleep(loopSleep)
    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        if (egpg != None): egpg.stop()  # stop motors
        print("\n*** Ctrl-C detected - Finishing up")
        sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #4
0
def main():
    if Carl: runLog.logger.info("Started")
    try:
        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    except:
        strToLog = "Could not instantiate an EasyGoPiGo3"
        print(strToLog)
        if Carl: lifeLog.logger.info(strToLog)
        exit(1)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        # Do Somthing in a Loop
        loopSleep = 1  # second
        loopCount = 0
        keepLooping = False
        while keepLooping:
            loopCount += 1
            # do something
            sleep(loopSleep)

        # Do Something Once
        # load the image and convert to grayscale
        image = cv2.imread(args["image"])
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        # initialize the list of threshold methods
        methods = [("THRESH_BINARY", cv2.THRESH_BINARY),
                   ("THRESH_BINARY_INV", cv2.THRESH_BINARY_INV),
                   ("THRESH_TRUNC", cv2.THRESH_TRUNC),
                   ("THRESH_TOZERO", cv2.THRESH_TOZERO),
                   ("THRESH_TOZERO_INV", cv2.THRESH_TOZERO_INV)]

        # loop over the threshold methods
        for (threshName, threshMethod) in methods:
            # threshold the image and show it
            (T, thresh) = cv2.threshold(gray, args["threshold"], 255,
                                        threshMethod)
            cv2.imshow(threshName, thresh)
            cv2.waitKey(0)

    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        if (egpg != None): egpg.stop()  # stop motors
        print("\n*** Ctrl-C detected - Finishing up")
        sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #5
0
def main():
    if Carl: runLog.logger.info("Started")
    try:
        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    except:
        strToLog = "Could not instantiate an EasyGoPiGo3"
        print(strToLog)
        if Carl: lifeLog.logger.info(strToLog)
        exit(1)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        # Do Somthing in a Loop
        loopSleep = 1  # second
        loopCount = 0
        keepLooping = False
        while keepLooping:
            loopCount += 1
            # do something
            sleep(loopSleep)

        # Do Something Once
        # load the image and convert to grayscale
        image = cv2.imread(args["image"])
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        blurred = cv2.GaussianBlur(image, (5, 5), 0)
        cv2.imshow("Image", image)

        thresh = cv2.adaptiveThreshold(blurred, 255,
                                       cv2.ADAPTIVE_THRESH_MEAN_C,
                                       cv2.THRESH_BINARY_INV, 11, 4)
        cv2.imshow("Mean Thresh", thresh)

        thresh = cv2.adaptiveThreshold(blurred, 255,
                                       cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                       cv2.THRESH_BINARY_INV, 15, 3)
        cv2.imshow("Mean Thresh", thresh)

    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        if (egpg != None): egpg.stop()  # stop motors
        print("\n*** Ctrl-C detected - Finishing up")
        sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #6
0
def main():
    if Carl: runLog.logger.info("Started")
    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        image = cv2.imread(args["image"])
        cv2.imshow("Original", image)
        blurred = np.hstack([
            cv2.blur(image, (3, 3)),
            cv2.blur(image, (5, 5)),
            cv2.blur(image, (7, 7))
        ])
        cv2.imshow("Averaged", blurred)

        blurred2 = np.hstack([
            cv2.GaussianBlur(image, (3, 3), 0),
            cv2.GaussianBlur(image, (5, 5), 0),
            cv2.GaussianBlur(image, (7, 7), 0)
        ])
        cv2.imshow("Gaussian", blurred2)

        blurred3 = np.hstack([
            cv2.medianBlur(image, 3),
            cv2.medianBlur(image, 5),
            cv2.medianBlur(image, 7)
        ])
        cv2.imshow("Median", blurred3)

        blurred4 = np.hstack([
            cv2.bilateralFilter(image, 5, 21, 21),
            cv2.bilateralFilter(image, 7, 31, 31),
            cv2.bilateralFilter(image, 9, 41, 41)
        ])
        cv2.imshow("Bilateral", blurred4)

        cv2.waitKey(0)

    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        if (egpg != None): egpg.stop()  # stop motors
        print("\n*** Ctrl-C detected - Finishing up")
        sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #7
0
def main():
    egpg = easygopigo3.EasyGoPiGo3(
        use_mutex=True)  # Create an instance of the EasyGoPiGo3 class
    myconfig.setParameters(egpg)

    runLog.logger.info("Starting scan360.py at {0:0.2f}v".format(egpg.volt()))
    ds = myDistSensor.init(egpg)
    tp = tiltpan.TiltPan(egpg)

    # Adjust GOPIGO3 CONSTANTS to my bot   default EasyGoPiGo3.WHEEL_DIAMETER = 66.5 mm
    # egpg.WHEEL_DIAMETER = 59.0				# empirical from systests/wheelDiaRotateTest.py
    # egpg.WHEEL_CIRCUMFERENCE = egpg.WHEEL_DIAMETER * math.pi

    dist_list_mm = []
    at_angle_list = []
    # speeds = [300, 100, 50, 30]
    speeds = [150, 50, 300]
    for spd in speeds:
        try:
            print("\nSPIN 360 AND SCAN at speed={}".format(spd))
            dist_list_mm, at_angle_list = spin_and_scan(
                egpg, ds, tp, 360,
                speed=spd)  # spin in place and take distance sensor readings
            range_list_cm = [dist / 10 for dist in dist_list_mm]
            printmaps.view360(
                range_list_cm,
                at_angle_list)  # print view (all r positive, theta 0=left
            print("Readings:{}".format(len(at_angle_list)))

        except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
            egpg.stop()  # stop motors
            runLog.logger.info("Exiting  scan360.py at {0:0.2f}v".format(
                egpg.volt()))

            print("Ctrl-C detected - Finishing up")
    egpg.stop()
Exemple #8
0
def main():

    ap = argparse.ArgumentParser()
    ap.add_argument("-d",
                    "--drive",
                    default=False,
                    action='store_true',
                    help="optional scan and drive forward")
    args = vars(ap.parse_args())
    driveFlag = args['drive']

    #Make Map, GoPiGo move forward if no object within , stops makes a map and again moves forward

    PERSONAL_SPACE = 25  # cm

    # Create an instance egpg of the GoPiGo3 class.
    egpg = easygopigo3.EasyGoPiGo3(
        use_mutex=True)  # use_mutex=True for "thread-safety"
    myconfig.setParameters(egpg)

    if carl:
        runLog.logger.info("Starting servoscan.py at {0:0.2f}v".format(
            egpg.volt()))

    # Create an instance of the Distance Sensor class.
    # I2C1 and I2C2 are the two ports through which sensors can connect to the I2C bus
    # The sensor can be connected to either port to be "on the I2C bus" so no port id is needed
    # The EasyDistanceSensor will return trusted readings out to roughly 230 cm
    #                                    and returns 300 when no obstacle seen

    #ds = egpg.init_distance_sensor(port='RPI_1')   # must use HW I2C
    #servo = egpg.init_servo("SERVO1")
    ds = myDistSensor.init(egpg)
    tp = tiltpan.TiltPan(egpg)

    try:
        egpg.stop()
        while True:
            # Scan in front of GoPiGo3
            dist_l, ang_l = ds_map(ds, tp, sector=160)
            closest_object = min(dist_l)
            tp.center()

            # Print scan data on terminal
            printmaps.view180(dist_l,
                              ang_l,
                              grid_width=80,
                              units="cm",
                              ignore_over=230)

            if driveFlag:
                # Decide if can move forward
                if (closest_object < PERSONAL_SPACE
                    ):  #If any obstacle is closer than desired, stop
                    print(
                        "\n!!! FREEZE - THERE IS SOMETHING INSIDE MY PERSONAL SPACE !!!\n"
                    )
                    break

                # We have clearance to move
                dist_to_drive = (closest_object * 0.3)
                print("\n*** WE HAVE CLEARANCE TO MOVE {:.1f}cm ***".format(
                    dist_to_drive))
                sleep(5)
                egpg.drive_cm(dist_to_drive, blocking=True
                              )  # drive 1/3 of the distance to closest object
            print("\n*** PAUSING TO ENJOY THE VIEW ***")
            sleep(15)
            print("\n*** Wall Angle Scan ***")
            angleToWallNormal = wallAngleScan(ds, tp, verbose=True)
            sleep(5)
        # Continue here when object within personal space
        tp.center()
        sleep(2)
        tp.off()

    except KeyboardInterrupt:
        print("\n**** Ctrl-C detected.  Finishing Up ****")
        if carl:
            runLog.logger.info("Exiting  servoscan.py at {0:0.2f}v".format(
                egpg.volt()))
        tp.center()
        sleep(2)
        tp.off()
Exemple #9
0
def main():
    if Carl: runLog.logger.info("Started")
    try:
        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    except:
        strToLog = "Could not instantiate an EasyGoPiGo3"
        print(strToLog)
        if Carl: lifeLog.logger.info(strToLog)
        exit(1)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        # Do Somthing in a Loop
        loopSleep = 1 # second
        loopCount = 0
        keepLooping = False
        while keepLooping:
            loopCount += 1
            # do something
            sleep(loopSleep)

        # Do Something Once
        # load the image and convert to grayscale
        image = cv2.imread(args["image"])
        # pyramid mean shift to aid thresholding 
        shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
        cv2.imshow("Input", image)

        # convert to grayscale, apply Otsu's thresholding
        gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
        # threshold() returns T,thresholded_image (T is the threshold value - same as 0 passed in)
        thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv2.imshow("Thresh", thresh)

        # compute the exact Euclidean Distance (ED Transform) from every non-zero (foreground)
        # pixel to the nearest zero (background) pixel, then find peaks (center area of objects) in this
        # distance map
        D = ndimage.distance_transform_edt(thresh)
        localMax = peak_local_max(D, indices=False, min_distance=20, labels=thresh)

        # perform connected component analysis on the local peaks,
        # using 8-connectivity, then apply Watershed algorithm
        markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]

        # watershed assumes markers are local minima (valleys), use -D to turn peaks to valleys
        labels = watershed( -D, markers, mask=thresh)
        print("[INFO] {} unique segments found".format(len(np.unique(labels)) -1))
        # (each pixel has been "labeled" with a height, all pixels with same height belong to same object)

        # loop over the unique labels, gather those pixels on a maxk
        for label in np.unique(labels):
            # if label is zero (background pixels), ignore it
            if label == 0:
                continue

            # allocate memory for the label region and draw it on the mask
            mask = np.zeros(gray.shape, dtype="uint8")
            mask[labels == label] = 255  # unmask pixels of this region

            # detect contours in the mask and grab the largest one
            cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            cnts = imutils.grab_contours(cnts)
            c = max(cnts, key=cv2.contourArea)

            # draw a circle enclosing the object
            ((x, y), r) = cv2.minEnclosingCircle(c)
            cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)
            cv2.putText(image, "#{}".format(label), (int(x) - 10, int(y)),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

        # show the output image
        cv2.imshow("Output", image)
        cv2.waitKey(0)

    except KeyboardInterrupt: # except the program gets interrupted by Ctrl+C on the keyboard.
       	    if (egpg != None): egpg.stop()           # stop motors
            print("\n*** Ctrl-C detected - Finishing up")
            sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #10
0
def main():
    if Carl: runLog.logger.info("Started")
    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    if Carl:
        myconfig.setParameters(egpg)  # configure custom wheel dia and base
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        sleep(0.5)
        tp.off()

    try:

        f = open('carl_corpus.txt', 'r', errors='ignore')
        raw = f.read()
        raw = raw.lower()  # convert everything to lowercase
        nltk.download('punkt')  # first time only
        nltk.download('wordnet')  # first time only

        sent_tokens = nltk.sent_tokenize(raw)  # convert to list of sentences
        word_tokens = nltk.word_tokenize(raw)  # convert to list of words

        print("example sent_tokens[:2]=\n", sent_tokens[:2])
        print("example word_tokens[:2]=\n", word_tokens[:2])

        # WordNet is a semantically-oriented dictionary of English included in nltk
        lemmer = nltk.stem.WordNetLemmatizer()

        def LemTokens(tokens):
            return [lemmer.lemmatize(token) for token in tokens]

        remove_punct_dict = dict(
            (ord(punct), None) for punct in string.punctuation)

        def LemNormalize(text):
            return LemTokens(
                nltk.word_tokenize(text.lower().translate(remove_punct_dict)))

        def response(user_response):
            carl_response = ''
            sent_tokens.append(user_response)

            TfidfVec = TfidfVectorizer(tokenizer=LemNormalize,
                                       stop_words='english')
            tfidf = TfidfVec.fit_transform(sent_tokens)
            vals = cosine_similarity(tfidf[-1], tfidf)
            idx = vals.argsort()[0][-2]
            flat = vals.flatten()
            flat.sort()
            req_tfidf = flat[-2]

            if (req_tfidf == 0):
                carl_response = carl_response + "I am sorry! I don't understand you"
                return carl_response
            else:
                carl_response = carl_response + sent_tokens[idx]
                return carl_response

        print(
            "\nCARL: My name is CARL.  I will answer your queries about me.  If you want to exit, type Bye!"
        )

        #  loop
        loopSleep = 1  # second
        loopCount = 0
        keepLooping = True
        while keepLooping:
            loopCount += 1

            user_response = input("\nYour Question? ")
            user_response = user_response.lower()
            if (user_response != 'bye'):
                if (user_response == 'thanks' or user_response == 'thank you'):
                    keepLooping = False
                    print("CARL: You are welcome..")
                else:
                    if (greeting(user_response) != None):
                        print("CARL: " + greeting(user_response))
                    else:
                        print("CARL: ", end="")
                        print(response(user_response))
                        sent_tokens.remove(user_response)
            else:
                keepLooping = False
                print("CARL: Bye! Take care..")

    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        if (egpg != None): egpg.stop()  # stop motors
        print("\n*** Ctrl-C detected - Finishing up")
        sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)
Exemple #11
0
def main():

    runLog.logger.info("Starting GCO.py")
    egpg = easygopigo3.EasyGoPiGo3(
        use_mutex=True)  # Create an instance of the EasyGoPiGo3 class
    # Adjust GOPIGO3 CONSTANTS to my bot   default EasyGoPiGo3.WHEEL_DIAMETER = 66.5 mm
    myconfig.setParameters(egpg)
    ds = myDistSensor.init(egpg)
    tp = tiltpan.TiltPan(egpg)

    tp.tiltpan_center()

    dist_list_mm = []
    at_angle_list = []
    scan360speed = 150
    safe_distance = 20.32  # cm  8 inches wheels to wall/object
    ds_to_wheels = 7  # cm    distance sensor is 2.75 inches in front of wheels
    try:
        #  spin360 taking distance measurement
        print("\n360 degree scan  at speed={}".format(scan360speed))
        dist_list_mm, at_angle_list = scan360.spin_and_scan(
            egpg, ds, tp, 360,
            speed=scan360speed)  # spin taking distance readings
        range_list_cm = [dist / 10 for dist in dist_list_mm]
        printmaps.view360(
            range_list_cm,
            at_angle_list)  # print view (all r positive, theta 0=left
        print("Readings:{}".format(len(at_angle_list)))

        sleep(3)

        #  spin to face closest object
        dist_to_target, scan_angle_to_target = closest_obj(
            range_list_cm, at_angle_list)
        angle_to_target = scan_angle_to_target - 90  # adjust for 0=left
        print("\nClosest object is {:.1f} cm at {:.0f} degrees".format(
            dist_to_target, angle_to_target))

        sleep(3)

        print("\nTurning {:.0f} at {} dps to face closest object".format(
            angle_to_target, egpg.get_speed()))
        egpg.turn_degrees(angle_to_target)

        sleep(3)

        #  travel to point where wheels are 10 inches from object (will back up if too close)
        dist_to_guard_spot = dist_to_target + ds_to_wheels - safe_distance
        print("\nMoving {:.0f} cm to guard spot".format(dist_to_guard_spot))
        egpg.drive_cm(dist_to_guard_spot)

        sleep(3)

        #  perform a 160 degree scan with obj in the center
        #  spin 180 to face away from object
        print("\nTurning 180 to guard direction")
        egpg.turn_degrees(180)

        sleep(3)

        #  loop
        #  perform a quick 160 degree scan
        #  if something gets closer, wag head and announce "I saw that."
        while True:
            dist_l, angl_l = servoscan.ds_map(ds, tp, num_of_readings=72)
            printmaps.view180(dist_l,
                              angl_l,
                              grid_width=80,
                              units="cm",
                              ignore_over=230)
            #  turn  distance sensor (eyes) to face closest object
            dist_to_closest, scan_angle_to_closest = closest_obj(
                dist_l, angl_l)
            angle_to_closest = scan_angle_to_closest  # - 90   # adjust for 0=left
            print("\nClosest object is {:.1f} cm at {:.0f} degrees".format(
                dist_to_closest, angle_to_closest))
            print("\nPointing {:.0f} to face closest object".format(
                angle_to_closest))
            tp.pan(angle_to_closest)
            sleep(2)
            status.printStatus(egpg, ds)
            sleep(30)
            tp.tiltpan_center()


#            status.batterySafetyCheck()

    except KeyboardInterrupt:  # except the program gets interrupted by Ctrl+C on the keyboard.
        egpg.stop()  # stop motors
        runLog.logger.info("Exiting GCO.py")
        print("Ctrl-C detected - Finishing up")
    egpg.stop()
Exemple #12
0
def main():
    if Carl: runLog.logger.info("Started")
    try:
        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    except:
        strToLog = "Could not instantiate an EasyGoPiGo3"
        print(strToLog)
        if Carl: lifeLog.logger.info(strToLog)
        exit(1)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        # Do Somthing in a Loop
        loopSleep = 1 # second
        loopCount = 0
        keepLooping = False
        while keepLooping:
            loopCount += 1
            # do something
            sleep(loopSleep)

        # Do Something Once
        # load the image and apply pyramid mean shift filtering
        # to assist the thresholding that follows
        image = cv2.imread(args["image"])
        shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
        stack = np.hstack([image,shifted])
        cv2.imshow("Image and Shifted", stack)

        # convert the mean shift image to grayscale
        gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
        # apply Otsu thresholding
        thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv2.imshow("Thresh", thresh)

        # find contours in the thresholded image
        cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)
        print("[INFO] {} unique contours found".format(len(cnts)))

        # loop over the contours
        for (i, c) in enumerate(cnts):
            # draw the contour
            ((x, y), _) = cv2.minEnclosingCircle(c)
            cv2.putText(image, "#{}".format(i + 1), (int(x) - 10, int(y)),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
            cv2.drawContours(image, [c], -1, (0, 255, 0), 2)

        # show the result
        cv2.imshow("shifted, thresholded, contours",image)





        cv2.waitKey(0)

    except KeyboardInterrupt: # except the program gets interrupted by Ctrl+C on the keyboard.
       	    if (egpg != None): egpg.stop()           # stop motors
            print("\n*** Ctrl-C detected - Finishing up")
            sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)