人生苦短,我用Python~ 界內的Python宣傳標語,對Python而言,這是種標榜,實際上,Python確實是當下最好用的開發語言之一。html
在相繼學習了C++/C#/Java以後,接觸Python,最一開始忽然一片茫然,彷佛是進入了新世界,全部C家族的語法,在這裏都或多或少地發生了改變,方法沒有大括號,喜聞樂見的格式。定義變量不須要聲明,時間長了,竟愛上了這個簡介明瞭,高效快捷的語言,固然,也是當下開發語言界內的寵兒,不能否認,Python是當下最流行的開發語言了。web
本文擬使用Python開發語言實如今任何能連接上互聯網的地方,遠程啓動在其餘地方部署的監控系統,而且實時地進行圖像連拍,將實時圖像以郵件形式反饋到手機郵箱,達到遠程實時監控的目的。正則表達式
這篇文章將要介紹的主要內容以下:服務器
一、遠程發送監控命令微信
二、監控系統作出相應,進行圖像連拍(或者是錄製一段視頻)網絡
三、監控系統將處理結果以郵件形式發送到移動端app
遠程向某郵箱服務器發送一封郵件,監控系統循環檢測此郵箱最新接受的郵件,經過獲取並分析郵件的信息肯定是否須要執行監控功能操做。若是須要,作出響應,拍照而且將拍照結果反饋回郵件發送方。ide
一、Python語言的熟練掌握,Python版本2.7學習
二、利用Python語言,實現SMTP協議以及POP3協議。已達到發送郵件和接收郵件的功能。測試
三、正則表達式的簡單使用
四、OpenCV 圖像處理,圖像識別,跨平臺開發庫的使用
五、郵箱服務器SMTP,POP3協議的開通
一、實現Python發送接收郵件代碼,最後封裝成Email_Helper_DG類,便於後續調用,固然本文的Python_Helper_DG尚未達到更高層次的封裝,畢竟要發送圖片的,適當作了一些對本系統的適應。
郵件發送接受的Email_Helper_DG代碼以下:
1 # -*- coding: UTF-8 -*- 2 import os 3 import poplib 4 import smtplib 5 from email.mime.application import MIMEApplication 6 from email.mime.audio import MIMEAudio 7 from email.mime.image import MIMEImage 8 from email.mime.multipart import MIMEMultipart 9 from email.mime.text import MIMEText 10 from email.utils import formataddr 11 12 13 class Mail_Helper_DG: 14 my_smtp_server = 'smtp.sina.com' # smtp 郵件服務地址 15 my_pop3_server = 'pop.sina.com' # pop3 郵件服務地址 16 mail_type = 'html' # 發送的郵件的格式,HTML或者Plain 17 my_account = '******@example.com' # 發件人郵箱帳號 18 my_pwd = '******' # 發件人郵箱密碼 19 toAddressArray = ['xxxxx@example.com', ] # 收件人的郵箱,可發送給多人 20 21 def __init__(self): 22 pass 23 24 # 發送郵件 25 def SendMail(self, toAddressArray, senderName, subject, content): 26 try: 27 server = smtplib.SMTP(self.my_smtp_server, 25) # 發件人郵箱中的SMTP服務器,端口是25 28 29 try: 30 msg = MIMEText(content, self.mail_type, 'utf-8') 31 msg['From'] = formataddr([senderName, self.my_account]) # 括號裏的對應發件人郵箱暱稱、發件人郵箱帳號 32 # msg['To'] = formataddr(["FK", my_account]) # 括號裏的對應收件人郵箱暱稱、收件人郵箱帳號 33 msg['Subject'] = subject # 郵件的主題,也能夠說是標題 34 35 server.login(self.my_account, self.my_pwd) # 括號中對應的是發件人郵箱帳號、郵箱密碼 36 server.sendmail(self.my_account, toAddressArray, msg.as_string()) # 括號中對應的是發件人郵箱帳號、收件人郵箱帳號、發送郵件 37 except Exception: 38 print(Exception) 39 return False 40 finally: 41 server.quit() # 關閉鏈接 42 return True 43 except Exception: 44 print(Exception) 45 return False 46 47 # 發送郵件帶附件 48 def SendMailAttachment(self, toAddressArray, senderName, subject, content, attachment_path): 49 try: 50 server = smtplib.SMTP(self.my_smtp_server, 25) # 發件人郵箱中的SMTP服務器,端口是25 51 52 try: 53 server.login(self.my_account, self.my_pwd) # 括號中對應的是發件人郵箱帳號、郵箱密碼 54 55 msg = MIMEMultipart() # create MIMEMultipart 56 msg['From'] = formataddr([senderName, self.my_account]) # 括號裏的對應發件人郵箱暱稱、發件人郵箱帳號 57 # msg['To'] = formataddr(["FK", my_account]) # 括號裏的對應收件人郵箱暱稱、收件人郵箱帳號 58 msg['Subject'] = subject # 郵件的主題,也能夠說是標題 59 content2 = MIMEText(content, 60 _charset='utf-8') # add email content ,coding is gbk, becasue chinese exist 61 msg.attach(content2) 62 for attachment_name in os.listdir(attachment_path): 63 attachment_file = os.path.join(attachment_path, attachment_name) 64 65 with open(attachment_file, 'rb') as attachment: 66 if 'application' == 'text': 67 attachment = MIMEText(attachment.read(), _subtype='octet-stream', _charset='GB2312') 68 elif 'application' == 'image': 69 attachment = MIMEImage(attachment.read(), _subtype='octet-stream') 70 elif 'application' == 'audio': 71 attachment = MIMEAudio(attachment.read(), _subtype='octet-stream') 72 else: 73 attachment = MIMEApplication(attachment.read(), _subtype='octet-stream') 74 75 attachment.add_header('Content-Disposition', 'attachment', filename=('gbk', '', attachment_name)) 76 # make sure "attachment_name is chinese" right 77 msg.attach(attachment) 78 79 server.sendmail(self.my_account, toAddressArray, msg.as_string()) # 括號中對應的是發件人郵箱帳號、收件人郵箱帳號、發送郵件 80 except Exception: 81 print(Exception) 82 return False 83 finally: 84 server.quit() # 關閉鏈接 85 return True 86 except Exception: 87 print(Exception) 88 return 89 90 # 接收郵件 91 def ReceiveMail(self): 92 # 建立一個pop3對象,這個時候實際上已經鏈接上服務器了 93 pp = poplib.POP3(self.my_pop3_server) 94 # 設置調試模式,能夠看到與服務器的交互信息 95 pp.set_debuglevel(1) 96 # 向服務器發送用戶名 97 pp.user(self.my_account) 98 # 向服務器發送密碼 99 pp.pass_(self.my_pwd) 100 # 返回郵箱的狀態,返回2元祖(消息的數量,消息的總字節) 101 # msgCount, msgSize = pp.stat() 102 103 ret = pp.list() 104 105 mailBody = pp.retr(len(ret[1])) 106 # 釋放pp 107 pp.quit() 108 109 return mailBody
二、主要業務邏輯代碼,其中包含對POP3郵箱的實時監測,且對捕獲到的命令進行分析判斷,最後作出響應:
1 # -*- coding: UTF-8 -*- 2 import re 3 import time 4 import cv2 5 6 from Email import Mail_Helper_DG 7 8 toAddressArray = ['wd8622088@foxmail.com'] # 收件人的郵箱,可發送給多人 9 10 content = """ 11 當前攝像頭捕獲的結果: 12 """ 13 14 15 # 獲取當前時間 16 def getCurrentTime(): 17 return str(time.strftime('’%Y-%m-%d %X’', time.localtime(time.time()))) 18 19 20 # 程序啓動標識 21 print('QiXiao`s SHS Starting ...') 22 # 初始化郵件發送類 23 mail = Mail_Helper_DG() 24 25 # 聲明一個變量,來做爲一個標記判斷是否已經檢測過當前這封郵件了 26 last_receiveMailDate = '' 27 # 輸出顯示當前掃描郵箱服務器的次數 28 scan_index = 0 29 # 設置一個循環檢測郵箱的方法 30 while True: 31 time.sleep(10) # 設置檢測郵箱服務器的時間間隔 32 print(getCurrentTime() + ' : scan item >>> ' + str(scan_index)) 33 scan_index += 1 # 掃描次數累加 34 try: 35 # 經過Pop3 獲取到郵件的第一條 36 mailBody = mail.ReceiveMail() 37 38 # 解析第一條郵件,並獲得發件人,主題,日期 39 sender = re.search("X-Sender: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1) 40 subject = re.search("Subject: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1) 41 date = re.search("Date: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1) 42 43 # 判斷解析到的參數值 44 if date != last_receiveMailDate: 45 # 對發送方進行郵箱判斷,不然任何人均可以發送命令,你懂得 46 if sender == 'wd8622088@foxmail.com': 47 # 對命令進行分析 48 if subject.__contains__('qx_cmd:'): 49 cmd = subject.split(':')[1] 50 # 按cmd的命令來匹配要執行的操做: 51 # catch-camera 捕獲攝像頭的操做 52 if cmd == 'catch-camera': 53 # 載入圖像,連續捕獲數張圖片,間隔三秒 54 video = cv2.VideoCapture(0) 55 time.sleep(3) 56 ret, img = video.read() 57 cv2.imwrite('files\\shoot_001.jpg', img) 58 59 time.sleep(3) 60 ret, img = video.read() 61 cv2.imwrite('files\\shoot_002.jpg', img) 62 63 time.sleep(3) 64 ret, img = video.read() 65 cv2.imwrite('files\\shoot_003.jpg', img) 66 67 video.release() # 關閉攝像頭 68 result = mail.SendMailAttachment(toAddressArray, "QiXiao", 69 "QiXiao`s SHS (QiXiao`s Smart Home System v1.0)", content, 70 "files") 71 if result is True: 72 print(getCurrentTime() + ' : send mail success !') 73 else: 74 print(getCurrentTime() + ' : send fail #') 75 76 # 讓當前這條信息的日期賦值給標記變量,以便下次略過當前這條信息 77 last_receiveMailDate = date 78 except Exception: 79 print(getCurrentTime() + 'Error:' + Exception)
至於代碼邏輯的分析,代碼內部已有適當的註釋進行講解,這裏再也不贅述,若有任何疑問,請留言,本人進行一一回復。
首先咱們啓動咱們的服務器,讓代碼跑起來。
每隔一段時間,服務器就會自動請求一次POP3服務器,判斷是否有新的命令輸入。
而後咱們在任何地點進行郵件命令的發送:這裏以Ios自帶的Mail來進行郵件的發送(郵件客戶端無所謂,微信裏的也能夠)
咱們首先要填寫好要發送的郵箱地址,以及主題(這裏是約定好的執行命令)
填寫好後,點擊發送。
能夠看到在0:00發送了一條郵件,這就是咱們剛纔發送的郵件。而後打開收件箱,準備進行郵件的查收。
咱們能夠看到,兩分鐘後,服務端以郵件形式返回監控的結果。打開郵箱進行查看。
咱們能夠看到,攝像頭正對的部位被成功捕獲,而且反饋到咱們發送郵件的郵箱中。
經過這樣的方式,咱們能夠在全球任意位置,向郵箱發送郵件,只要存在網絡的地方,均可以實時對任意位置部署的攝像頭進行監控,實時返回監控結果。
咱們打開咱們的接收命令的郵箱查看一下咱們接受到的郵件:
沒錯,是咱們剛纔發送的郵件。
咱們程序文件目錄下保存的截取圖片:
至此,咱們的遠程監控系統已經測試完畢,可見,完美達到了預期的效果!
系統雖然功能已經實現,然還有不少不盡人意之處,將來將在第二版進行改進的有:
一、系統每隔必定時間間隔自動進行拍照,而後圖像分析是否有區別(有物體入侵),若是有當即發送郵件推送報警信息。
二、對圖片進行人臉識別,用方框圈出人連範圍,以便增長提醒。
三、系統將搭建於Raspberry Pi Linux微機系統上,而且配備攝像頭全天候進行跟蹤拍攝。
四、將來可能搭建web服務,在網站或者App上進行此功能的使用