# HW5 討論區 ###### tags: `AICA` [TOC] - [name=承揚] :::spoiler HW5-2(我發現其實是成功的,只是當時網路太爛跑不出來www) ```python= # -*- coding: utf-8 -*- from __future__ import unicode_literals import sys import cv2 from random import randint import json import configparser from picamera import PiCamera from flask import Flask, request, abort, make_response from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage, ImageSendMessage # initialize a Flask object app = Flask(__name__) # get config values from config.ini config = configparser.ConfigParser() config.read('config.ini') # initialize objects related to line-bot-sdk line_bot_api = LineBotApi(config.get('line-bot', 'channel_access_token'), timeout=3000) handler = WebhookHandler(config.get('line-bot', 'channel_secret')) # pre-defined JSON file path of user_id list # will be create automatically if the file is not exist or the data structure is not a list USER_LIST_FILE = './user.json' def auto_photo(): face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') print('start detection') capture = cv2.VideoCapture(0) detected = False while capture.isOpened(): status, frame = capture.read() # Read the frame gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.1, 4) # Detect the faces try: if len(faces) > 0 and not detected: detected = True print('detected !') random_num = randint(0, sys.maxsize) for (x, y, w, h) in faces: # Draw the rectangle around each face cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.putText(frame, 'Detected', (30, 60), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3, cv2.LINE_AA) cv2.imwrite('./image.jpg', frame) with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) for user_id in user_list: line_bot_api.push_message(user_id, TextSendMessage( text='face detected')) line_bot_api.push_message(user_id, ImageSendMessage( original_content_url=config.get('ngrok', 'server_name') + '/picamera/{}'.format( str(random_num)), preview_image_url=config.get('ngrok', 'server_name') + '/picamera/{}'.format( str(random_num))) ) elif len(faces) <= 0: detected = False except KeyboardInterrupt: print("KeyboardInterrupt") exit() except Exception as e: print(e) @app.route('/callback', methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @app.route('/picamera/<counter>', methods=['GET']) def picamera_image(counter): image_data = open('./image.jpg', 'rb').read() response = make_response(image_data) response.headers['Content-Type'] = 'image/jpg' return response @handler.add(MessageEvent, message=TextMessage) def message_text(event): # enroll as a user if event.message.text == 'enroll': print('got a \"enroll\" message') # append current user id into user_list file with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) user_list.append(event.source.user_id) user_list = list(set(user_list)) with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(user_list, file, ensure_ascii=False, indent=4) # reply success message line_bot_api.reply_message(event.reply_token, TextSendMessage(text='success')) auto_photo() if __name__ == '__main__': try: with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) if type(user_list) != list: raise TypeError() except: with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(list(), file, ensure_ascii=False, indent=4) finally: app.run(debug=False, port=5000) ``` ::: - [name=函庭] :::spoiler 註冊功能 + 成功把照片上傳到網頁,只差把圖片傳回來 ```python= # -*- coding: utf-8 -*- from __future__ import unicode_literals import configparser from flask import Flask, request, abort, make_response from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, ImageSendMessage, TextSendMessage from picamera import PiCamera import json import cv2 from random import randint import sys # initialize a Flask object app = Flask(__name__) # get config values from config.ini config = configparser.ConfigParser() config.read('config.ini') # initialize objects related to line-bot-sdk line_bot_api = LineBotApi(config.get('line-bot', 'channel_access_token')) handler = WebhookHandler(config.get('line-bot', 'channel_secret')) USER_LIST_FILE = './user.json' random_num = randint(0, sys.maxsize) @app.route('/callback', methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @app.route('/picamera', methods=['GET']) def picamera_image(): '''camera = PiCamera() camera.start_preview() camera.capture('./image.jpg') camera.stop_preview() camera.close()''' image_data = open('./image.jpg', 'rb').read() response = make_response(image_data) response.headers['Content-Type'] = 'image/jpg' return response @handler.add(MessageEvent, message=TextMessage) def handle_message(event): if event.message.text == 'enroll': print('got a \"enroll\" message') # append current user id into user_list file with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) user_list.append(event.source.user_id) user_list = list(set(user_list)) with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(user_list, file, ensure_ascii=False, indent=4) # reply success message line_bot_api.reply_message(event.reply_token, TextSendMessage(text='success')) cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') while (cap.isOpened()): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.1, 4) cv2.imshow('Face', frame) key = cv2.waitKey(1) if len(faces) > 0: print('face!!!!!') cv2.imwrite('./image.jpg', frame) break line_bot_api.reply_message( event.reply_token, ImageSendMessage( original_content_url='http://0579-2402-7500-a2d-8766-a769-9c2a-19a1-d827.ngrok.io/picamera', preview_image_url='http://0579-2402-7500-a2d-8766-a769-9c2a-19a1-d827.ngrok.io/picamera') ) if __name__ == '__main__': try: with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) if type(user_list) != list: raise TypeError() except: with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(list(), file, ensure_ascii=False, indent=4) finally: app.run(debug=True, port=5000) ``` ::: - 承揚+函庭 :::spoiler 能傳送空照片 ```python= # -*- coding: utf-8 -*- from __future__ import unicode_literals import configparser from flask import Flask, request, abort, make_response from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, ImageSendMessage, TextSendMessage from picamera import PiCamera import json import cv2 from random import randint import sys # initialize a Flask object app = Flask(__name__) # get config values from config.ini config = configparser.ConfigParser() config.read('config.ini') # initialize objects related to line-bot-sdk line_bot_api = LineBotApi(config.get('line-bot', 'channel_access_token')) handler = WebhookHandler(config.get('line-bot', 'channel_secret')) USER_LIST_FILE = './user.json' random_num = randint(0, sys.maxsize) @app.route('/callback', methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @app.route('/picamera', methods=['GET']) def picamera_image(): '''camera = PiCamera() camera.start_preview() camera.capture('./image.jpg') camera.stop_preview() camera.close()''' image_data = open('./image.jpg', 'rb').read() response = make_response(image_data) response.headers['Content-Type'] = 'image/jpg' return response @handler.add(MessageEvent, message=TextMessage) def handle_message(event): if event.message.text == 'enroll': print('got a \"enroll\" message') # append current user id into user_list file with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) user_list.append(event.source.user_id) user_list = list(set(user_list)) with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(user_list, file, ensure_ascii=False, indent=4) # reply success message line_bot_api.reply_message(event.reply_token, TextSendMessage(text='success')) cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') while (cap.isOpened()): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.1, 4) cv2.imshow('Face', frame) key = cv2.waitKey(1) if len(faces) > 0: print('face!!!!!') cv2.imwrite('./image.jpg', frame) break with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) for user_id in user_list: line_bot_api.push_message(user_id, ImageSendMessage( original_content_url='http://0579-2402-7500-a2d-8766-a769-9c2a-19a1-d827.ngrok.io/picamera', preview_image_url='http://0579-2402-7500-a2d-8766-a769-9c2a-19a1-d827.ngrok.io/picamera' ) ) if __name__ == '__main__': try: with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) if type(user_list) != list: raise TypeError() except: with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(list(), file, ensure_ascii=False, indent=4) finally: app.run(debug=True, port=5000) ``` ::: --- ## :sparkles: Henna + 承揚 最終成功版 :sparkles: ### 偵測到人臉之後只拍一張 ```python= # -*- coding: utf-8 -*- from __future__ import unicode_literals import configparser from flask import Flask, request, abort, make_response from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, ImageSendMessage, TextSendMessage from picamera import PiCamera import json import cv2 # initialize a Flask object app = Flask(__name__) # get config values from config.ini config = configparser.ConfigParser() config.read('config.ini') # initialize objects related to line-bot-sdk line_bot_api = LineBotApi(config.get('line-bot', 'channel_access_token')) handler = WebhookHandler(config.get('line-bot', 'channel_secret')) USER_LIST_FILE = './user.json' @app.route('/callback', methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @app.route('/picamera', methods=['GET']) def picamera_image(): image_data = open('./image.jpg', 'rb').read() response = make_response(image_data) response.headers['Content-Type'] = 'image/jpg' return response @handler.add(MessageEvent, message=TextMessage) def handle_message(event): if event.message.text == 'enroll': print('got a \"enroll\" message') # append current user id into user_list file with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) user_list.append(event.source.user_id) user_list = list(set(user_list)) with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(user_list, file, ensure_ascii=False, indent=4) # reply success message line_bot_api.reply_message(event.reply_token, TextSendMessage(text='success')) cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') while (cap.isOpened()): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.1, 4) cv2.imshow('Face', frame) key = cv2.waitKey(1) if len(faces) > 0: print('face!!!!!') for (x, y, w, h) in faces: # Draw the rectangle around each face cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.putText(frame, 'Detected', (30, 60), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3, cv2.LINE_AA) cv2.imwrite('./image.jpg', frame) break with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) for user_id in user_list: line_bot_api.push_message(user_id, TextSendMessage( text='face detected')) line_bot_api.push_message(user_id, ImageSendMessage( original_content_url=config.get('ngrok', 'server_name') + '/picamera', preview_image_url=config.get('ngrok', 'server_name') + '/picamera' ) ) if __name__ == '__main__': try: with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) if type(user_list) != list: raise TypeError() except: with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(list(), file, ensure_ascii=False, indent=4) finally: app.run(debug=True, port=5000) ``` ### 只要偵測到人臉就持續地拍 ```python= # -*- coding: utf-8 -*- from __future__ import unicode_literals import configparser from flask import Flask, request, abort, make_response from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, ImageSendMessage, TextSendMessage from picamera import PiCamera import json import cv2 # initialize a Flask object app = Flask(__name__) # get config values from config.ini config = configparser.ConfigParser() config.read('config.ini') # initialize objects related to line-bot-sdk line_bot_api = LineBotApi(config.get('line-bot', 'channel_access_token')) handler = WebhookHandler(config.get('line-bot', 'channel_secret')) USER_LIST_FILE = './user.json' @app.route('/callback', methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @app.route('/picamera', methods=['GET']) def picamera_image(): image_data = open('./image.jpg', 'rb').read() response = make_response(image_data) response.headers['Content-Type'] = 'image/jpg' return response @handler.add(MessageEvent, message=TextMessage) def handle_message(event): if event.message.text == 'enroll': print('got a \"enroll\" message') # append current user id into user_list file with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) user_list.append(event.source.user_id) user_list = list(set(user_list)) with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(user_list, file, ensure_ascii=False, indent=4) # reply success message line_bot_api.reply_message(event.reply_token, TextSendMessage(text='success')) cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') while (cap.isOpened()): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.1, 4) cv2.imshow('Face', frame) key = cv2.waitKey(1) if len(faces) > 0: print('face!!!!!') for (x, y, w, h) in faces: # Draw the rectangle around each face cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.putText(frame, 'Detected', (30, 60), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3, cv2.LINE_AA) cv2.imwrite('./image.jpg', frame) #break with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) for user_id in user_list: line_bot_api.push_message(user_id, TextSendMessage( text='face detected')) line_bot_api.push_message(user_id, ImageSendMessage( original_content_url=config.get('ngrok', 'server_name') + '/picamera', preview_image_url=config.get('ngrok', 'server_name') + '/picamera' ) ) if __name__ == '__main__': try: with open(USER_LIST_FILE, 'r', encoding='utf-8') as file: user_list = json.load(file) if type(user_list) != list: raise TypeError() except: with open(USER_LIST_FILE, 'w', encoding='utf-8') as file: json.dump(list(), file, ensure_ascii=False, indent=4) finally: app.run(debug=True, port=5000) ```