---
# System prepended metadata

title: HW5 討論區
tags: [AICA]

---

# 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)
```