Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Visão computacional como sensor de movimento para SmartThings


Usando um Raspberry Pi 3 e uma PiCam, este sensor de visão computacional detecta rostos e envia dados de presença por LAN - UPNP para SmartThings.

Vou começar supondo que você tem um Raspberry Pi 3 com uma câmera funcionando e o Open CV instalado. Se você não, eu recomendo este tutorial 🙂

Criação de um manipulador de dispositivo SmartThings personalizado


No IDE SmartThings, criamos um novo manipulador de dispositivo para nosso sensor de movimento por visão computacional.

Vá para a seção “My Device Handler”, clique em “+ Create New Device Handler” no canto superior direito.

Neste caso, iremos criá-lo a partir do código. Clique na segunda guia “From Code”, cole o código em anexo “Device Handler” e clique no botão “Criar”.

Na próxima página, clique em “Publicar” para disponibilizar o dispositivo para você.

Escrevendo o aplicativo SmartThings


Semelhante ao Device Handler, iremos para a seção “My SmartApps”, clique em “+ Create New SmartApps” no canto superior direito.

Também o criaremos a partir do código. Clique na segunda guia “Do Código”, cole o código em anexo “ SmartApp” e clique em “Criar”.

Na próxima página, clique em “Publicar”.

Preparando o Raspberry Pi


Agora temos que adicionar o script python que obterá imagens da câmera, detectando faces e reportando ao SmartThings.

Primeiro d Baixar e instalar imutils e twisted

Se você ainda não instalou o pacote imutils, convém obtê-lo do GitHub ou instalá-lo por meio de:
  pip install imutils  

Para torcida:
  sudo apt-get install python-twisted-web  

Agora que tudo está pronto, vá para / home / pi e criar um diretório para armazenar o script
  câmera mkdir cameracd  

Crie o arquivo de script:
  sudo nano ssdpcamera.py  

Cole o código em anexo Camera Python Script ” e salve pressionando “control + x” e depois “y” e digite.

Teste o script digitando python ssdpcamera.py, você verá algo assim:

Descobrindo e combinando o Raspberry Pi


A partir do aplicativo móvel SmartThings, devemos ir para o Marketplace no canto inferior direito, clicar na guia “SmartApps” e, finalmente, procurar em “+ Meus aplicativos” “Visão do computador (conectar)”

Certifique-se de que o Raspberry Pi esteja ativado e o script Python em execução.

O SmartApp irá iniciar o processo de descoberta e uma vez encontrado, clique na caixa de diálogo de seleção e selecione o dispositivo e clique em “Concluído”.

Isso criará o dispositivo em sua conta e começará a receber atualizações.

Início automático


Finalmente, se você deseja executar o script python automaticamente ao ligar o Raspberry Pi, pode editar /etc/rc.local e adicionar a seguinte linha.
  (sleep 10; python /home/pi/camera/ssdpcamera.py)& 

O () faz com que ambos os comandos sejam executados em segundo plano.

Código

 #! / usr / bin / python2.7 "" "Câmera de visão computacional para SmartThingsCopyright 2016 Juan Pablo Risso <[email protected]> Dependências:python-twisted, cv2, pyimagesearchLicensed under a Licença Apache, Versão 2.0 (a "Licença"); você não pode usar este arquivo, exceto em conformidade com a Licença. Você pode obter uma cópia da Licença em:http://www.apache.org/licenses/LICENSE-2.0A menos exigido pela lei aplicável ou acordado por escrito, o software distribuído sob a Licença é distribuído "COMO ESTÁ", SEM GARANTIAS OU CONDIÇÕES DE QUALQUER TIPO, expressas ou implícitas. Consulte a Licença para o idioma específico que rege as permissões e limitações sob a Licença. "" "import argparseimport loggingimport cv2import urllib2import imutilsfrom time import timefrom picamera.array import PiRGBArrayfrom picamera import PiCamerafrom twisted.web import server, resourcefrom twisted.internet import reactorfrom twisted.internet.defer import importar net.protocol import DatagramProtocolfrom twisted.web.client import Agentfrom twisted.web.http_headers import Headersfrom twisted.web.iweb import IBodyProducerfrom twisted.web._newclient import ResponseFailedfrom zope.interface import implementementsSSDP9.255 'dSDP9.255U_ADDR =SSDP9.255' d SSDP-55'ADDR =1900SSDPIDU_ADDR '23.255.255.255_ADDR =SSDP9.255. -9220-11e4-96fa-123b93f75cba'SEARCH_RESPONSE ='HTTP / 1.1 200 OK \ r \ nCACHE-CONTROL:max-age =30 \ r \ nEXT:\ r \ nLOCATION:% s \ r \ nSERVER:Linux, UPnP / 1.0, Pi_Garage / 1.0 \ r \ nST:% s \ r \ nUSN:uuid:% s ::% s '# inicializar a câmera e obter uma referência para a câmera raw # capturecamera =PiCamera () camera.resolution =(640 , 480) camera.framerate =32rawCapture =PiRGBArray (camera, size =(640, 480)) auxcount =0 # construir o detector facial e permitir que a câmera aqueçafd =FaceDetector ("cascades / haarcascade_frontalface_default.xml") time.sleep (0.1) def determine_ip_for_host (host):"" "Determine o endereço IP local usado para se comunicar com um host específico" "" test_sock =DatagramProtocol () test_sock_listener =reactor.lis tenUDP (0, test_sock) # pylint:disable =no-membertest_sock.transport.connect (host, 1900) my_ip =test_sock.transport.getHost (). hosttest_sock_listener.stopListening () return my_ipclass StringProducer (objeto):"" "Grava um string na memória para um pedido Twisted "" "implementa (IBodyProducer) def __init __ (self, body):self.body =bodyself.length =len (body) def startProducing (self, consumer):# pylint:disable =invalid- name "" "Começa a produzir a string fornecida para o consumidor especificado" "" consumer.write (self.body) return success (None) def pauseProducing (self):# pylint:disable =invalid-name "" "Pausa na produção - sem op "" "passdef stopProducing (self):# pylint:disable =invalid-name" "" Parar de produzir - sem op "" "passclass SSDPServer (DatagramProtocol):" "" Receber e responder a solicitações de descoberta M-SEARCH do hub SmartThings " "" def __init __ (self, interface ='', status_port =0, device_target =''):self.interface =interfaceself.device_target =device_targetself.status_port =status_portself.port =reactor.listenMulticas t (SSDP_PORT, self, listenMultiple =True) # pylint:disable =no-memberself.port.joinGroup (SSDP_ADDR, interface =interface) reactor.addSystemEventTrigger ('before', 'shutdown', self.stop) # pylint:disable =no-memberdef datagramReceived (self, data, (host, port)):try:header, _ =data.split (b '\ r \ n \ r \ n') [:2] exceto ValueError:returnlines =header.split ('\ r \ n') cmd =lines.pop (0) .split ('') linhas =[x.replace (':', ':', 1) para x nas linhas] linhas =[x para x em linhas se len (x)> 0] cabeçalhos =[x.split (':', 1) para x em linhas] cabeçalhos =dict ([(x [0] .lower (), x [1]) para x nos cabeçalhos]) logging.debug ('comando SSDP% s% s - de% s:% d com cabeçalhos% s', cmd [0], cmd [1], host, porta, cabeçalhos) search_target ='' if ' st 'nos cabeçalhos:search_target =headers [' st '] if cmd [0] ==' M-SEARCH 'e cmd [1] ==' * 'e search_target em self.device_target:logging.info ('% s recebidos % s para% s de% s:% d ', cmd [0], cmd [1], search_target, host, porta) url =' http://% s:% d / status '% (determine_ip_for_host (host) , self.status_port) response =SEARCH_R ESPONSE% (url, search_target, UUID, self.device_target) self.port.write (resposta, (host, porta)) else:logging.debug ('Comando SSDP ignorado% s% s', cmd [0], cmd [ 1]) def stop (self):"" "Saia do grupo multicast e pare de escutar" "" self.port.leaveGroup (SSDP_ADDR, interface =self.interface) self.port.stopListening () class StatusServer (resource.Resource):"" "Servidor HTTP que serve o status da câmera para o hubSmartThings" "" isLeaf =Truedef __init __ (self, device_target, subscription_list, garage_door_status):self.device_target =device_targetself.subscription_list =subscription_list.garage_door_status__ =installation_door_status. self) def render_SUBSCRIBE (self, request):# pylint:disable =invalid-name "" "Lida com solicitações de inscrição do hub ST - hub deseja ser notificado sobre atualizações de status da porta de garagem" "" headers =request.getAllHeaders () logging.debug ("ASSINAR:% s", cabeçalhos) se 'retorno de chamada' nos cabeçalhos:cb_url =cabeçalhos ['retorno de chamada'] [1:-1] se não cb_url em self.subscription_list:self.subs cription_list [cb_url] ={} # reactor.stop () logging.info ('Assinatura adicionada% s', cb_url) self.subscription_list [cb_url] ['expiration'] =time () + 24 * 3600retorno "" def render_GET ( self, request):# pylint:disable =invalid-name "" "Lida com solicitações de sondagem do hub ST" "" if request.path =='/ status':if self.garage_door_status ['last_state'] =='inativo' :cmd ='status-inactive'else:cmd =' status-active'msg =' % s   uuid:% s ::% s   '% (cmd, UUID, self.device_target) logging.info ("Solicitação de sondagem de% s para% s - retornou% s", request.getClientIP (), request.path, cmd) return msgelse:logging.info ( "Solicitação falsa recebida de% s para% s", request.getClientIP (), request.path) return "" class MonitorCamera (objeto):"" "Monitora o status da câmera, gerando notificações sempre que seu estado muda" "" def __init __ ( self, device_target, subscription_list, camera_status):# pylint:disable =too-many-argumentsself.device_target =device_targetself.subscription_list =subscription_listself.camera_stat us =camera_statuscurrent_state ='inactive'reactor.callLater (0, self.check_garage_state, current_state, auxcount) # pylint:disable =no-memberdef check_garage_state (self, current_state, auxcount):self.current_state =current_states.auxcontera rawCapture, format ="bgr", use_video_port =True) # pegue o array NumPy bruto que representa o imageframe =rawCapture.array # redimensione o quadro e converta-o para grayscaleframe =imutils.resize (frame, largura =640) grey =cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # detecta faces na imagem e clona o frame # para que possamos desenhar em itfaceRects =fd.detect (grey, scaleFactor =1.1, minNeighbors =10, minSize =(30, 30)) frameClone =frame.copy () if faceRects! =():auxcount =0 if current_state =='inactive':current_state ='active' logging.info ('Estado alterado de% s para% s', self.camera_status ['last_state '], current_state) self.camera_status [' last_state '] =current_stateself.notify_hubs () else:auxcount =auxcount + 1if auxcount ==60:current_state ='inativo' logging.info ('Estado alterado de% s para% s', self.camera_status ['last_state'], current_state) self.camera_status ['last_state'] =current_stateself.notify_hubs () # loop over as caixas delimitadoras de faces e desenhe-as para (fX, fY, fW, fH) em faceRects:cv2.rectangle (frameClone, (fX, fY), (fX + fW, fY + fH), (0, 255, 0), 2 ) # mostrar o feed de vídeo em uma nova janela GUI # cv2.imshow ("Face", videorotate) rawCapture.truncate (0) # Agendar próximo checkreactor.callLater (0, self.check_garage_state, current_state, auxcount) # pylint:disable =no-memberdef notification_hubs (self):"" "Notificar os hubs SmartThings inscritos que uma mudança de estado ocorreu" "" if self.camera_status ['last_state'] =='inactive':cmd ='status-inactive'else:cmd ='status-active'para inscrição em self.subscription_list:if self.subscription_list [inscrição] [' expiration ']> time ():logging.info ("Notificando hub% s", inscrição) msg ​​='  % s   uuid:% s ::% s   '% (cmd, UUID, self.device_target) body =StringProducer (msg) agent =Agent (reator) req =agent.request ('POST', assinatura, Cabeçalhos ({'CONTENT-LENGTH':[len (msg)]}), corpo) req.addCallback (self.handle_response ) req.addErrback (self.handle_error) def handle_response (self, response):# pylint:disable =no-self-use "" "Manipula o hub SmartThings retornando um código de status para o POST. Isso é realmente inesperado - normalmente fecha a conexão para POST / PUT sem fornecer um código de resposta. "" "if response.code ==202:logging.info (" Atualização de status aceita ") else:logging.error (" Código de resposta inesperado:% s ", response.code ) def handle_error (self, response):# pylint:disable =no-self-use "" "Manipula erros que geram a execução de NOTIFY. Não parece haver uma maneira de evitar ResponseFailed - o SmartThings Hub não gera um código de resposta apropriado para POST ou PUT, e se NOTIFY for usado, ele ignora o corpo. "" "If isinstance (response.value, ResponseFailed):logging.debug ("Resposta falhada (esperada)") else:logging.error ("Resposta inesperada:% s", resposta) def main ():"" "Função principal para lidar com o uso da linha de comando" "" arg_proc =argparse .ArgumentParser (description ='Fornece o status ativo / inativo da câmera para um hub SmartThings') arg_proc.add_argument ('- httpport', dest ='http_port', help ='número da porta HTTP', default =8080, type =int) arg_proc.add_argument ('- deviceindex', dest ='device_index', help ='Índice do dispositivo', default =1, type =int) arg_proc.add_argument ('- pollingfreq', dest ='polling_freq', help =' Número de segundos entre o estado da câmera de sondagem ', default =5, type =int) arg_proc.add_argument (' - debug ', dest =' debug ', help =' Ativar mensagens de depuração ', default =False, action =' store_true ' ) options =arg_proc.parse_args () device_target ='urn:schema s-upnp-org:dispositivo:RPi_Computer_Vision:% d '% (options.device_index) log_level =logging.INFOif options.debug:log_level =logging.DEBUGlogging.basicConfig (format ='% (asctime) -15s% (levelname) - 8s% (message) s ', level =log_level) subscription_list ={} camera_status ={' last_state ':' unknown '} logging.info (' Inicializando câmera ') # Servidor SSDP para lidar com discoverySSDPServer (status_port =options.http_port, device_target =device_target) # site HTTP para lidar com assinaturas / pollingstatus_site =server.Site (StatusServer (device_target, subscription_list, camera_status)) reactor.listenTCP (options.http_port, status_site) # pylint:disable =no-memberlogging.info ('Inicialização concluída' ) # Monitore o estado da câmera e envie notificações sobre o estado changeMonitorCamera (device_target =device_target, subscription_list =subscription_list, camera_status =camera_status) reactor.run () # pylint:disable =no-memberif __name__ =="__main __":main () Fonte:Computador Visão como sensor de movimento para SmartThings 

Processo de manufatura

  1. ST:sensor de movimento com aprendizado de máquina para rastreamento de atividade de alta precisão e com economia de bateria
  2. Sensor de movimento, alarme, gravação de vídeo em HA no Raspberry Pi
  3. Sistema de sensor de movimento infravermelho faça você mesmo para Raspberry Pi
  4. Sensor de movimento usando Raspberry Pi
  5. Contador Geiger - Tutorial do sensor de radiação para Raspberry Pi
  6. Raspberry Pi GPIO com sensor de movimento PIR:Melhor tutorial
  7. Construindo uma rede de sensores para um moinho do século 18
  8. Interface do sensor de movimento HC-SR501 PIR com Raspberry Pi
  9. Construir robôs Raspberry Pi:Melhor tutorial para iniciantes
  10. 7 aplicativos de visão computacional