Advertisement
luiscesjr2

Camera.py

Feb 4th, 2019
3,242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.71 KB | None | 0 0
  1. from imutils.video import VideoStream
  2. import datetime
  3. import math
  4. import cv2
  5. import numpy as np
  6. import argparse
  7. import imutils
  8. import time
  9. import smtplib
  10. from email.MIMEMultipart import MIMEMultipart
  11. from email.MIMEText import MIMEText
  12. from email.MIMEBase import MIMEBase
  13. from email import encoders
  14.  
  15. #variaveis globais
  16. width = 0
  17. height = 0
  18. ContadorEntradas = 0
  19. ContadorSaidas = 0
  20. AreaContornoLimiteMin = 100  #Change these values according to your needs.
  21. ThresholdBinarizacao = 90  #Change these values according to your needs.
  22. OffsetLinhasRef = 60  #Change these values according to your needs.
  23. timeout = time.time() + 60*1  # 1 minute from now, the program will shutdown, for testing purposes or else.
  24.  
  25.  
  26. #Verifying if the object is entering the monitored zone.
  27. def TestaInterseccaoEntrada(y, CoordenadaYLinhaEntrada, CoordenadaYLinhaSaida):
  28.         DiferencaAbsoluta = abs(y - CoordenadaYLinhaEntrada)   
  29.  
  30.         if ((DiferencaAbsoluta <= 2) and (y < CoordenadaYLinhaSaida)):
  31.                 return 1
  32.         else:
  33.                 return 0
  34.  
  35. #Verifying if the object is leaving the monitored zone.
  36. def TestaInterseccaoSaida(y, CoordenadaYLinhaEntrada, CoordenadaYLinhaSaida):
  37.         DiferencaAbsoluta = abs(y - CoordenadaYLinhaSaida) 
  38.  
  39.         if ((DiferencaAbsoluta <= 2) and (y > CoordenadaYLinhaEntrada)):
  40.                 return 1
  41.         else:
  42.                 return 0
  43.  
  44. ap = argparse.ArgumentParser()
  45. ap.add_argument("-p", "--picamera", type=int, default=-1,
  46.         help="whether or not the Raspberry Pi camera should be used")
  47. args = vars(ap.parse_args())
  48.  
  49. camera = VideoStream(usePiCamera=args["picamera"] > 0).start()
  50. time.sleep(2.0)
  51.  
  52. PrimeiroFrame = None
  53.  
  54. #Making some frame reading before considering analysis, the reason is, some cameras may take longer to
  55. #get used to ambiente light conditions when they turn on, capturing consecutive frames with a lot of lighting
  56. #variation, so to not process these effects, consecutive captures are maybe outside the image processing giving the
  57. #camera some time to adapt to lighting conditions.
  58.  
  59. for i in range(0,20):
  60.     (grabbed, Frame) = camera.read(), camera.read()
  61.  
  62. while True:
  63.     #Reading first Frame and determining size.
  64.     (grabbed, Frame) = camera.read(), camera.read()
  65.     height = np.size(Frame,0)
  66.     width = np.size(Frame,1)
  67.  
  68.     #Converting Frame to Grey Scale and applying Blur Effect to highlight shapes.
  69.     FrameGray = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY)
  70.     FrameGray = cv2.GaussianBlur(FrameGray, (21, 21), 0)
  71.  
  72.     #A comparisson is made between two images, if the first frame is null, it's initialized.
  73.     if PrimeiroFrame is None:
  74.         PrimeiroFrame = FrameGray
  75.         continue
  76.  
  77.     #Absolute difference between initial frame and actual frame (Background Subtraction)
  78.     #Also makes the binarization of the frame and the subtracted background.
  79.     FrameDelta = cv2.absdiff(PrimeiroFrame, FrameGray)
  80.     FrameThresh = cv2.threshold(FrameDelta, ThresholdBinarizacao, 255, cv2.THRESH_BINARY)[1]
  81.    
  82.     #Makes the dilatation of the binarized frame to eliminate holes, white zones inside the found shapes,
  83.     #this way, detected objects will be considered a black mass, also finds the shapes after dilatation.
  84.     FrameThresh = cv2.dilate(FrameThresh, None, iterations=2)
  85.     _, cnts, _ = cv2.findContours(FrameThresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  86.  
  87.     QtdeContornos = 0
  88.  
  89.     #Drawing reference lines
  90.     CoordenadaYLinhaEntrada = (height / 2)-OffsetLinhasRef
  91.     CoordenadaYLinhaSaida = (height / 2)+OffsetLinhasRef
  92.     cv2.line(Frame, (0,CoordenadaYLinhaEntrada), (width,CoordenadaYLinhaEntrada), (255, 0, 0), 2)
  93.     cv2.line(Frame, (0,CoordenadaYLinhaSaida), (width,CoordenadaYLinhaSaida), (0, 0, 255), 2)
  94.  
  95.  
  96.     #Wiping found shapes
  97.     for c in cnts:
  98.         #Small shapes are to be ignored.
  99.         if cv2.contourArea(c) < AreaContornoLimiteMin:
  100.             continue
  101.         #For debugging purposes, counts the number of found shapes
  102.         QtdeContornos = QtdeContornos+1    
  103.        
  104.         #Gets the shapes coordinates (A rectangle that involves the object), highlighting it's shape.
  105.         (x, y, w, h) = cv2.boundingRect(c) #x e y: coordenadas do vertice superior esquerdo
  106.                                            #w e h: respectivamente largura e altura do retangulo
  107.  
  108.         cv2.rectangle(Frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
  109.        
  110.         #Determines the central point of the shape, and circles it.
  111.         CoordenadaXCentroContorno = (x+x+w)/2
  112.         CoordenadaYCentroContorno = (y+y+h)/2
  113.         PontoCentralContorno = (CoordenadaXCentroContorno,CoordenadaYCentroContorno)
  114.         cv2.circle(Frame, PontoCentralContorno, 1, (0, 0, 0), 5)
  115.        
  116.         #Tests the intersection of centers from the shapes and the reference lines. This way, it may count
  117.         #which shapes crosses the reference lines.
  118.         if (TestaInterseccaoEntrada(CoordenadaYCentroContorno,CoordenadaYLinhaEntrada,CoordenadaYLinhaSaida)):
  119.             ContadorEntradas += 1
  120.  
  121.         if (TestaInterseccaoSaida(CoordenadaYCentroContorno,CoordenadaYLinhaEntrada,CoordenadaYLinhaSaida)):  
  122.             ContadorSaidas += 1
  123.  
  124.         #If needed, uncomment these lines to show framerate.
  125.         #cv2.imshow("Frame binarizado", FrameThresh)
  126.         #cv2.waitKey(1);
  127.         #cv2.imshow("Frame com subtracao de background", FrameDelta)
  128.         #cv2.waitKey(1);
  129.  
  130.  
  131.     print "Contornos encontrados: "+str(QtdeContornos)
  132.  
  133.     #Writes on screen the number of people who enters or leaves the watched area.
  134.     cv2.putText(Frame, "Entradas: {}".format(str(ContadorEntradas)), (10, 50),
  135.                 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (250, 0, 1), 2)
  136.     cv2.putText(Frame, "Saidas: {}".format(str(ContadorSaidas)), (10, 70),
  137.                 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
  138.     cv2.imshow("Original", Frame)
  139.     key = cv2.waitKey(1) & 0xFF
  140.  
  141.     #If you want to exit the program from a keystroke, uncomment these lines and comment the next ones,
  142.     #which makes the program exit by itself after a certain ammount of time.    
  143.     # if the `q` key was pressed, break from the loop
  144.     #if key == ord("q"):
  145.         #break
  146.  
  147.     test = 0
  148.     if test == 5 or time.time() > timeout:
  149.         break
  150.     test = test - 1
  151.  
  152. # cleanup the camera and close any open windows
  153.  
  154. #Program writes the count to a file.
  155. f = open( 'contagem.txt', 'w' ) #File path and it's name with extension, to write to.
  156. f.write( 'ContadorEntradas = ' + repr(ContadorEntradas) + '\n' ) #Variables to write
  157. f.write( 'ContadorSaidas = ' + repr(ContadorSaidas) + '\n' ) #Variables to write
  158. f.close()
  159.  
  160. #The following code allows you to send the file to an email address, if not needed just delete or comment it.
  161. #Good thing there is a built in library for this already, so why not make use of it =D.
  162.  
  163. fromaddr = "xxxx" #Your Email Address
  164. toaddr = "xxxx" #Address to receive email
  165.  
  166. msg = MIMEMultipart()
  167.  
  168. msg['From'] = fromaddr
  169. msg['To'] = toaddr
  170. msg['Subject'] = "Contagem de pessoas" #Subject of the email goes here
  171.  
  172. body = "Segue em anexo" #Message to be written on the email
  173.  
  174. msg.attach(MIMEText(body, 'plain'))
  175.  
  176. filename = "contagem.txt" #File name with extension to send as an attatchment.
  177. attachment = open("/home/pi/contagem.txt", "rb") #File path
  178.  
  179. part = MIMEBase('application', 'octet-stream')
  180. part.set_payload((attachment).read())
  181. encoders.encode_base64(part)
  182. part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
  183.  
  184. msg.attach(part)
  185.  
  186. server = smtplib.SMTP('smtp.gmail.com', 587)
  187. server.starttls()
  188. server.login(fromaddr, "xxxx") #Your password goes here, substitute xxxx for it.
  189. text = msg.as_string()
  190. server.sendmail(fromaddr, toaddr, text)
  191. server.quit()
  192. cv2.destroyAllWindows()
  193. camera.stop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement