daily pastebin goal
31%
SHARE
TWEET

ImageRecognitionPi

a guest Oct 23rd, 2018 66 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
  1. from PIL import Image
  2. import numpy as np
  3. import time
  4. import cv2 # for the camera
  5. from gpiozero import LED
  6. import io
  7. from picamera import PiCamera
  8.  
  9. #returns all the x values for which the rgb values add up to 500 or more (white)
  10. def GetWhitesInImage(image, lineNumber):
  11.     #cv2.imwrite("Photo.jpg", image)
  12.     #rgb_im = image.convert('RGB')
  13.     #print((image[0, 0]))
  14.     rgb_im = image.RGB()
  15.     #width = rgb_im.size[0]
  16.     #r = np.zeros(width) # np.ones(rgb_im.size[0]) #create an array with the width of the image
  17.     #g = np.zeros(width)
  18.     #b = np.zeros(width)
  19.  
  20.     #rgbList = []
  21.     output = []
  22.  
  23.     #Not only select white values on the sum of the rgb, also see if the r, g and b values are somewhat the same
  24.  
  25.     #fill the array with the rgb values
  26.     for i in range(0, width):
  27.         #if i > 478:
  28.         #    print("WATCH THIS")
  29.         r, g, b = rgb_im.getpixel((i,lineNumber))
  30.         #b[i], r[i], g[i] = image[lineNumber, i]
  31.         #b, r, g = image[lineNumber, i]
  32.         #rgbList.append((int(r)+int(g)+int(b)))
  33.         #if r[i] + g[i] + b[i] > 400: r < (g + b)*0.75 and
  34.         if (int(r) + int(g) + int(b)) > whiteThreshold:
  35.             output.append(i)
  36.     return output
  37.  
  38.  
  39. #determines from the inputted array with x coords two sets of points that are the two lines
  40. def DetermineLines(whiteXCoords):
  41.     #get the average of the values
  42.     #average = np.average((whiteXCoords))
  43.     #maybe use the middle instead of the average
  44.  
  45.  
  46.     #divide the array into two arrays based on if the points lay below the average or above
  47.     left = []
  48.     right = []
  49.     for i in whiteXCoords:
  50.         #if i < average:
  51.         if i > middle: #this is flipped because the cam will mirror the image
  52.             left.append((i))
  53.         else:
  54.             right.append((i))
  55.  
  56.     if len(left) == 0:
  57.         left.append(0)
  58.     if len(right) == 0:
  59.         right.append(0)
  60.  
  61.     #calculate the spread of each of the lines
  62.     minLeft, maxLeft = np.min((left)), np.max((left))
  63.     minRight, maxRight = np.min((right)), np.max((right))
  64.  
  65.     #get the percentage of white pixels in the area
  66.     percentLeft = np.size((left))/(maxLeft - minLeft + 1)
  67.  
  68.     # if the percentage is above 0.8, it is a line, if it's lower it's not.
  69.     # so determine what value affects the percentage the most and remove it
  70.     #do this 10 times to see if the percentage improves
  71.     while maxLeft - minLeft > 30:
  72.         averageLeft = np.average((left))
  73.  
  74.         # if the percentage is higher than 0.8 break
  75.         # when on the track the percentage won't be 1 when on the track, on the metaforum floor it might be 1
  76.         #so I removed the 1 constraint
  77.         #if 1 > percentLeft > 0.8:
  78.         if percentLeft > 0.8:
  79.             break
  80.  
  81.         # if the averageLeft - minLeft > maxLeft - averageLeft, then the lowest value is further away from the average
  82.         # than the highest value. so remove that value
  83.         if averageLeft - minLeft > maxLeft - averageLeft:
  84.             left.remove(minLeft)
  85.             minLeft = np.min(left)
  86.         else:
  87.             left.remove(maxLeft)
  88.             maxLeft = np.max((left))
  89.  
  90.         # one value is removed, the min and maxes are recalculated, recalculate the average
  91.         percentLeft = np.size((left))/(maxLeft - minLeft + 1)
  92.  
  93.  
  94.  
  95.     #get the percentage of white pixels in the area
  96.     percentRight = np.size((right))/(maxRight - minRight + 1)
  97.  
  98.     # if the percentage is above 0.8, it is a line, if it's lower it's not.
  99.     # so determine what value affects the percentage the most and remove it
  100.     # do this untill the group becomes too small
  101.     while maxRight - minRight > 30:
  102.         averageRight = np.average((right))
  103.  
  104.         # if the percentage is higher than 0.8 break
  105.         if 1 > percentRight > 0.8:
  106.             break
  107.  
  108.         # if the averageLeft - minLeft > maxLeft - averageLeft, then the lowest value is further away from the average
  109.         # than the highest value. so remove that value
  110.         if averageRight - minRight > maxRight - averageRight:
  111.             right.remove(minRight)
  112.             minRight = np.min(right)
  113.         else:
  114.             right.remove(maxRight)
  115.             maxRight = np.max((right))
  116.  
  117.         # one value is removed, the min and maxes are recalculated, recalculate the average
  118.         percentRight = np.size((right)) / (maxRight - minRight + 1)
  119.  
  120.  
  121.     leftLocation = minLeft + ((maxLeft - minLeft) / 2)
  122.     rightLocation = minRight + ((maxRight - minRight) / 2)
  123.  
  124.     if percentLeft < 0.8:
  125.         leftLocation = 0
  126.  
  127.     if percentRight < 0.8:
  128.         rightLocation = 0
  129.  
  130.     #if the percentages are too low, the location 0 is outputted, so the program knows the detection went wrong
  131.     return leftLocation, rightLocation
  132.  
  133. def TakePicture():
  134.     s, img = cam.read()
  135.  
  136.     camera.capture(stream, format='jpeg')
  137.     stream.seek(0)
  138.     return Image.open(stream)
  139.     if s:
  140.         cv2.namedWindow("cam-test")#,CV_WINDOW_AUTOSIZE)
  141.         #cv2.imshow("cam-test",img)
  142.         #cv2.waitKey()
  143.         #cv2.imwrite("Photo" + ".jpg", img)
  144.         #cv2.destroyWindow("cam-test")
  145.  
  146.         return (img)
  147.     else:
  148.         print("Image not taken")
  149.         return
  150.  
  151.  
  152. imagePaths = ["Position0.png",  "Position1.png",  "Position2.png",  "Position3.png",  "Position4.png",  "Position5.png",
  153.               "Position6.png",  "Position7.png",  "Position8.png",  "Position9.png",  "Position10.png", "Position11.png",
  154.               "Position12.png", "Position13.png", "Position14.png", "Position15.png", "Position16.png", "Position17.png",
  155.               "Position18.png", "Position19.png", "Position20.png", "Position21.png", "Position22.png", "Position23.png",
  156.               "Position24.png", "Position25.png", "Position26.png", "Position27.png", "Position28.png", "Position29.png",
  157.               "Position30.png", "Position31.png", "Position32.png", "Position33.png", "Position34.png", "Position35.png",
  158.               "Position36.png", "Position37.png", "Position38.png", "Position39.png", "Position40.png", "Position41.png",
  159.               "Position42.png", "Position43.png", "Position44.png", "Position45.png", "Position46.png", "Position47.png",
  160.               "Position48.png", "Position49.png", "Position50.png", "Position51.png", "Position52.png", "White.png"]
  161.  
  162. #position 9: on the left line
  163. #position 26: is the middle
  164. #position 44: on the right line
  165.  
  166. imageOrder = [ 26,25,24,23,22,21,20,19,18,17,
  167.                16,15,14,13,12,11,10,11,12,13,
  168.                14,15,16,17,18,19,20,21,22,23,
  169.                24,25,26,27,28,29,30,31,32,33,
  170.                34,35,36,37,38,39,40,41,42,43]
  171.  
  172. # initialize the camera
  173. cam = cv2.VideoCapture(0)  # 0 -> index of camera
  174.  
  175. whiteThreshold = 550 #when capturing black/white make this 550, when capturing a track make this 400
  176. # when taking a picture with my webcam of a picture of white lines on meta's gray floor the white was extremely white, the
  177. # gray had a total rgb of 500 or so. so this has to be way higher for the program to distinct between gray and white
  178. # the track had a total of 200/300 on red, and a total of 400/500 on white, so that is a good treshold for that situation
  179.  
  180. #get one image to set the sized correctly
  181. #myImage = Image.open(imagePaths[0])
  182. myImage = TakePicture()
  183. width = int(cam.get(3))   # 3 is the width, 4 is the height
  184. middle = width/2
  185. #middle = myImage.size[0]/2
  186. deviation = width/20 #devide the image in n regions. used for the buzzing. when the regions get smaller
  187. #divide by a higher number, the later the buzzing starts
  188. regions = [middle - 4 * deviation, middle - 3 * deviation, middle - 2 * deviation, middle - 1 * deviation]
  189.  
  190. #lineToCheck = np.round(cam.get(4)/2) # 3 is the width, 4 is the height
  191. lineToCheck = int(cam.get(4)/2) # 3 is the width, 4 is the height
  192.  
  193. leftPositions = [0 for _ in range(10)] # np.zeros(10) #array that contains all the positions of the left line
  194. leftVelocity = [0 for _ in range(10)] # np.zeros(10) #array that contains all the velocities of the left line
  195. rightPositions = [0 for _ in range(10)] # np.zeros(10) #array that contains all the positions of the right line
  196. rightVelocity = [0 for _ in range(10)] # np.zeros(10) #array that contains all the velocities of the left line
  197. leftBuzzingLevel = 0 #the vibrating level of the left vibration motor, {0, 1, 2, 3}, 0 being off
  198. rightBuzzingLevel = 0 #the vibrating level of the right vibration motor, {0, 1, 2, 3}, 0 being off
  199.  
  200. leftVibrationMotor = LED(18)
  201. rightVibrationMotor = LED(19)
  202.  
  203.  
  204. #print("-------------------------------------------------------------------")
  205.  
  206. outputString = ""
  207.  
  208. print("Starting program")
  209.  
  210. stream = io.BytesIO()
  211. camera = picamera.PiCamera()
  212.  
  213. camera.start_preview()
  214. time.sleep(2)
  215.  
  216.  
  217. #for j in range(len(imageOrder)):
  218. j = 0
  219. while True:
  220.     j += 1
  221.     print("Locations: ", leftLine, " | ", rightLine)
  222.     print("predict: ", predictedLeft, " | ", predictedRight)
  223.     #print("leftMotor:  ", leftVibrationMotor, "rightMotor: ", rightVibrationMotor)
  224.     time.sleep(1)
  225.     #load image (take image)
  226.     #myImage = Image.open(imagePaths[imageOrder[j]])
  227.  
  228.     myImage = TakePicture()
  229.  
  230.     #gets all the x values for white pixels
  231.     whiteXCoordsInImage = GetWhitesInImage(myImage, lineToCheck)
  232.  
  233.  
  234.     #get the location of the left line and right line
  235.     leftLine, rightLine = DetermineLines((whiteXCoordsInImage))
  236.  
  237.     leftPositions.append(leftLine)
  238.     leftPositions.pop(0)
  239.     if rightLine == 0:
  240.         rightLine = width
  241.     rightPositions.append((width) - rightLine) #with this the right position gets translated to the left and flipped
  242.     #so for both left and right lines the thing is: the further to the right, the worse (both comming from the left)
  243.     rightPositions.pop(0)
  244.  
  245.     #here the leftPositions and rightPositions are filled with the last 10 positions
  246.     #determine the velocity (to the right or left)
  247.     if leftPositions[-1] != 0 and leftPositions[-2] != 0:
  248.         leftVelocity.append(leftPositions[-1] - leftPositions[-2])
  249.     else:
  250.         leftVelocity.append(0)
  251.     leftVelocity.pop(0)
  252.  
  253.     if rightPositions[-1] != 0 and rightPositions[-2] != 0:
  254.         rightVelocity.append(rightPositions[-1] - rightPositions[-2])
  255.     else:
  256.         rightVelocity.append(0)
  257.     rightVelocity.pop(0)
  258.  
  259.     leftVelocityAsArray = np.asarray(leftVelocity)
  260.     predictedLeft = leftPositions[-1] + np.average((leftVelocityAsArray[leftVelocityAsArray != 0]))
  261.     rightVelocityAsArray = np.asarray(rightVelocity)
  262.     predictedRight = rightPositions[-1] + np.average((rightVelocityAsArray[rightVelocityAsArray != 0]))
  263.  
  264.     #predicted is nan if every position is 0, so check for nan
  265.  
  266.     if np.isnan((predictedLeft)) or np.isnan((predictedRight)):
  267.         rightBuzzingLevel = 5
  268.         rightVibrationMotor.on()
  269.         leftBuzzingLevel = 5
  270.         leftVibrationMotor.on()
  271.         #print(j)#, " - ", imagePaths[imageOrder[j]])
  272.         #print("Left:")
  273.         #print("Locations: ", leftPositions)
  274.         #print("Velocity: ", leftVelocity[-1])
  275.  
  276.         #print()
  277.         #print("Right:")
  278.         #print("Locations: ", rightPositions)
  279.         #print("Velocity: ", rightVelocity[-1])
  280.  
  281.         #print()
  282.         #print("Buzzing Levels", leftBuzzingLevel, " | ", rightBuzzingLevel)
  283.  
  284.         #print("Location: (", leftPositions[-1], ", ", leftPositions[-2], ")")
  285.         #print("Buzzing Levels", leftBuzzingLevel, " | ", rightBuzzingLevel)
  286.         #print("-------------------------------------------------------------------")
  287.  
  288.         #now = time.time()
  289.         #outputString += "image: " + imagePaths[imageOrder[j]] + "  |  " + \
  290.         #                " Buzzing: " + str(leftBuzzingLevel) + " | " + str(rightBuzzingLevel) + "  |  " + \
  291.         #                "Time: " + str(now) + "   Detection Error" + "\n"
  292.  
  293.         continue
  294.  
  295.  
  296.     #check for each regions if the predicted lines is inside. if not set the according buzzing level
  297.     #leftBuzzingLevel = 0
  298.     #for i in range(0,len(regions)):
  299.     #    if predictedLeft < regions[i]:
  300.     #        break
  301.     #    else:
  302.     #        leftBuzzingLevel = i
  303.  
  304.     #rightBuzzingLevel = 0
  305.     #for i in range(0,len(regions)):
  306.     #    if predictedRight < regions[i]:
  307.     #        break
  308.     #    else:
  309.     #        rightBuzzingLevel = i
  310.  
  311.     #leftBuzzingLevel = 0
  312.     #for i in range(0, len(regions)):
  313.     #    if (predictedLeft < regions[i]):
  314.     #        leftBuzzingLevel = i
  315.     #    else:
  316.     #        break
  317.  
  318.     #rightBuzzingLevel = 0
  319.     #for i in range(0, len(regions)):
  320.     #    if (predictedRight < regions[i]):
  321.     #        rightBuzzingLevel = i
  322.     #    else:
  323.     #        break
  324.  
  325.     if predictedLeft > regions[1]:
  326.         leftBuzzingLevel = 1
  327.         leftVibrationMotor.on()
  328.     else:
  329.         leftBuzzingLevel = 0
  330.         leftVibrationMotor.off()
  331.     if predictedRight > regions[1]:
  332.         rightBuzzingLevel = 1
  333.         rightVibrationMotor.on()
  334.     else:
  335.         rightBuzzingLevel = 0
  336.         rightVibrationMotor.off()
  337.  
  338.     #leftBuzzingLevel = 0
  339.     #if predictedLeft > regions[3]:
  340.     #    leftBuzzingLevel = 1
  341.     #rightBuzzingLevel = 0
  342.     #if predictedRight > regions[3]:
  343.     #    rightBuzzingLevel = 1
  344.  
  345.  
  346.  
  347.     #print(j)#, " - ", imagePaths[imageOrder[j]])
  348.     #print("Left:")
  349.     #print("Locations: ", leftPositions)
  350.     leftPositionsArray = np.asarray((leftPositions))
  351.     leftVelocityArray = np.asarray((leftVelocity))
  352.     #print("Current location: ", leftLine, "  |  Average: ", np.average(leftPositionsArray[leftPositionsArray > 0]),
  353.     #      "  |  Avg velocity: ",np.average(leftVelocityArray[leftVelocityArray != 0]))
  354.     #print("Prediction: ", predictedLeft)
  355.  
  356.     #print()
  357.     #print("Right:")
  358.     #print("Locations: ", rightPositions)
  359.     rightPositionsArray = np.asarray((rightPositions))
  360.     rightVelocityArray = np.asarray((rightVelocity))
  361.     #print("Current location: ", rightLine, "  |  Average: ", np.average(rightPositionsArray[rightPositionsArray > 0]),
  362.     #      "  |  Avg velocity: ", np.average(rightVelocityArray[rightVelocityArray != 0]))
  363.     #print("Prediction: ", predictedRight)
  364.     #print()
  365.     #print("Buzzing Levels", leftBuzzingLevel, " | ", rightBuzzingLevel)
  366.  
  367.     #print("Location: (", leftPositions[-1], ", ", leftPositions[-2], ")")
  368.     #print("Buzzing Levels", leftBuzzingLevel, " | ", rightBuzzingLevel)
  369.  
  370.     now = time.time()
  371.     #outputString += "image: " + imagePaths[imageOrder[j]] + "  |  " + \
  372.     #                " Buzzing: " + str(leftBuzzingLevel) + " | " + str(rightBuzzingLevel) + "  |  " + \
  373.     #                "Time: " + str(now) + "\n"
  374.  
  375.     #print("-------------------------------------------------------------------")
  376.  
  377. with open('Data.txt', 'w') as f:
  378.     f.write(outputString)
  379.     f.close()
  380.  
  381.  
  382. camera.stop_preview()
  383. print("Klaaar")
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top