├── .github
├── FUNDING.yml
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .idea
├── .gitignore
├── bb_.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── LICENSE
├── README.md
├── __pycache__
└── user_hooks.cpython-36.pyc
├── clients
├── _config.json
└── view.py
├── config.json
├── install.sh
├── libs
├── __pycache__
│ ├── data.cpython-36.pyc
│ ├── filters.cpython-36.pyc
│ ├── hooks.cpython-36.pyc
│ ├── log.cpython-36.pyc
│ └── requests_.cpython-36.pyc
├── data.py
├── filters.py
├── hooks.py
├── log.py
└── requests_.py
├── main.py
├── models
├── MobileNetSSD_deploy.caffemodel
├── MobileNetSSD_deploy.prototxt.txt
├── haarcascade_cars3.xml
├── haarcascade_frontalface.xml
├── haarcascade_frontalface_alt.xml
├── haarcascade_frontalface_alt2.xml
├── haarcascade_frontalface_default.xml
└── hog.xml
├── resourse
└── wait.png
├── start.sh
├── templates
└── records.html
└── user_hooks.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: https://www.paypal.com/paypalme/masloffkz
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/bb_.iml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | ## How to install camera server
8 |
9 | Copy the repository to your Linux system.
10 |
11 | ```
12 | git clone https://github.com/iRTEX-MIT/OpenCV-Webcam-Recorder-and-Streamer.git
13 | ```
14 |
15 | Browse to the repository folder.
16 |
17 | ```
18 | cd OpenCV-Webcam-Recorder-and-Streamer
19 | ```
20 |
21 | Install Python libraries
22 |
23 | ```
24 | ./install.sh
25 | ```
26 |
27 | Start ```main.py``` or ```start.sh```
28 |
29 | ```
30 | python3 main.py
31 | ```
32 |
33 | or
34 |
35 | ```
36 | ./start.sh
37 | ```
38 |
39 | ## Examples
40 |
41 |
42 | ### Hooks and filters
43 | The system sends signals at every activity by hooking. You can hang your functions on these hooks.
44 | To create a hook or filter, enter the file `user_hooks.py` and create and register a function in the _user_hooks function.
45 | There are examples in `user_hooks.py` file.
46 |
47 | __Hook__ - is a function that works on some action
48 |
49 | __Filter__ - processing some action through a user-defined function
50 |
51 | __Request__ - A web request that is executed during any action
52 |
53 | ### Table of filters
54 |
55 | | Filter | Arg | Description|
56 | | ------ | ------ | ------ |
57 | |on_frame_record | frame | Processes the frame before recording |
58 | |on_frame_text | text | Processes the text before recording |
59 | |on_frame_motion_detect_record | frame | Processes the frame before recording |
60 | |on_socket_frame | base64.b64encode(frame) | Processes the frame before streaming (base64) |
61 | |on_socket_frame_encoded | frame | Processes the frame before streaming |
62 | |on_config | Configuration object | Processes the configuration file after loading |
63 | |on_reserve_videofile | Configuration object | The third priority file, which will be downloaded as a video file, if the main file is not available |
64 |
65 |
66 | ### Table of web requests
67 |
68 | | Hook | Arg | Description|
69 | | ------ | ------ | ------ |
70 | | on_face_detect | frame with face | Executing when the camera detect the face. |
71 | | on_eye_detect | frame with eye | Executing when the camera detect the eye. |
72 | | on_body_detect | frame with body | Executing when the camera detect the body. |
73 | | on_body_upper_detect | frame with body | Executing when the camera detect the upper body. |
74 | | on_body_lower_detect | frame with body | Executing when the camera detect the lower. |
75 | | on_motion_detect | frame | Executing when the camera detect movement. |
76 |
77 |
78 | ### Table of hooks
79 |
80 | | Hook | Arg | Description|
81 | | ------ | ------ | ------ |
82 | | on_face_detect | frame with face | Executing when the camera detect the face. |
83 | | on_eye_detect | frame with eye | Executing when the camera detect the eye. |
84 | | on_body_detect | frame with body | Executing when the camera detect the body. |
85 | | on_body_upper_detect | frame with body | Executing when the camera detect the upper body. |
86 | | on_body_lower_detect | frame with body | Executing when the camera detect the lower. |
87 | | on_net_*_detect | frame | Executing when the camera detect the * object. |
88 | | on_start_webserver | None | Executing when web server is ready started. |
89 | | on_wait_camera | number camera in for | Executing when system wait camera. To be inside the iteration of the cycle, not outside it. |
90 | | on_init | True | Executing when system started. |
91 | | on_release | None | Executing when OpenCV 'cap' and video record release. |
92 | | on_frame_send_to_server | JPG frame | Executing when web server send frame. |
93 | | on_motion_detect | frame | Executing when the camera detect movement. |
94 | | on_save_video | frame | Executing when the system write frame in video. To be inside the iteration of the cycle, not outside it. |
95 | | on_before_write_frame | frame | Executing when the frame is ready to be recorded, but not yet recorded. |
96 | | on_setup_cfg | Configuration object | Executing when configs ready to use. |
97 | | on_frame_start | UNIX Time | Executing when the frame began to be created |
98 | | on_videofile_created | File path | Executing when video file created. |
99 | | on_reserve_videofile_created | File path | Executing when reserve video file created. |
100 | | on_reserve_videofile_not_created | File path | Executing when reserve video file not created. |
101 | | on_exit | True | Executing when system exiting. |
102 |
103 | ## How to set up remote viewing
104 |
105 | To use the camera remotely (in the local network), you must in the configuration file in the line "web_stream": false, change false to true.
106 | Then reboot the server. In the same repository is a folder clients, it has a file ```view.py```, open it on the computer from which you want to view the camera. You will be asked to enter the IP camera (you can get it in the control panel of your router, or via ```nmap```), port (5555 by default). If all data is entered correctly, the camera will open in a new window!
107 |
108 | Either you can connect to the broadcast via a regular browser or VLC. As a streaming address, use ```http://IP-YOUR-PC:5000/video```.
109 |
110 | ### Table of server URLs
111 | | URL | Description|
112 | | ------ | ------ |
113 | | tcp://0.0.0.0:5555 | Primary video stream. You can connect to it through the tuner client in the ``clients`` folder |
114 | | http://0.0.0.0:5000/video | Secondary video stream Flask. You can connect to it from a VLC or browser. It works with only one client at a time, the second will not be able to connect if the first is watching the broadcast |
115 | | http://0.0.0.0:5000/records | Page for downloading video recordings |
116 | ---
117 | 
118 | 
119 |
--------------------------------------------------------------------------------
/__pycache__/user_hooks.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/__pycache__/user_hooks.cpython-36.pyc
--------------------------------------------------------------------------------
/clients/_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "ip": "*",
3 | "port": 5555
4 | }
--------------------------------------------------------------------------------
/clients/view.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import zmq
3 | import json
4 | import base64
5 | import numpy as np
6 |
7 | context = zmq.Context()
8 | footage_socket = context.socket(zmq.SUB)
9 |
10 | try:
11 |
12 | with open('_config.json') as config_file:
13 | cfg = json.load(config_file)
14 |
15 | footage_socket.bind('tcp://{ip}:{port}'.format(
16 | ip=str(cfg['ip']),
17 | port=str(cfg['port'])
18 | ))
19 |
20 | except:
21 |
22 | ip = input('IP your camera [* = localhost]: ')
23 | port = input('Port your camera [default: 5555]: ')
24 |
25 | footage_socket.bind('tcp://{ip}:{port}'.format(
26 | ip=str(ip),
27 | port=str(port)
28 | ))
29 |
30 | finally:
31 |
32 | footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
33 |
34 | while True:
35 | try:
36 |
37 | frame = footage_socket.recv_string()
38 | img = base64.b64decode(frame)
39 | npimg = np.fromstring(img, dtype=np.uint8)
40 |
41 | source = cv2.imdecode(npimg, 1)
42 |
43 | cv2.imshow("Stream", source)
44 | cv2.waitKey(1)
45 |
46 | except KeyboardInterrupt:
47 | cv2.destroyAllWindows()
48 | break
49 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "video": false,
3 | "stream": false,
4 | "video_zip": false,
5 | "children_frame_zip": 1,
6 | "motion_detect": false,
7 | "detect_face": false,
8 | "detect_text_labels": true,
9 | "detect_text_labels_color": [255, 255, 255],
10 | "detect_face_boxcolor": [255, 0, 0],
11 | "detect_people": false,
12 | "detect_people_boxcolor": [189, 56, 43],
13 | "detect_body": {
14 | "full": false,
15 | "upper": false,
16 | "lower": false
17 | },
18 | "detect_body_boxcolor": [251, 176, 8],
19 | "detect_eye": false,
20 | "detect_eye_boxcolor": [255, 255, 255],
21 | "detect_car": false,
22 | "detect_car_boxcolor": [255, 255, 255],
23 | "zoom_body": false,
24 | "zoom_people": false,
25 | "net_detect": {
26 | "enabled": true,
27 | "boxcolor": [255, 255, 255],
28 | "classes": ["background", "aeroplane", "bicycle", "bird", "boat",
29 | "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
30 | "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
31 | "sofa", "train", "tvmonitor"]
32 | },
33 | "show_detect_motion_on_frame": false,
34 | "show_time_on_frame": true,
35 | "time_mask": "%x %X",
36 | "show_fps_on_frame": true,
37 | "fps_mask": "FPS: {current} / {max}",
38 | "save_video_on_movies": false,
39 | "save_video": false,
40 | "pixel_update_for_detect": 200,
41 | "recorder_fps": 30,
42 | "record_file_mask": "{d}{m}{Y}_{H}{M}{S}.avi",
43 | "record_file_reserve_mask": "{d}{m}{Y}_{H}{M}{S}.avi",
44 | "text_on_frame": "My Webcam",
45 | "text_on_frame_color": [0, 0, 0],
46 | "text_on_frame_size": 0.4,
47 | "web_stream": true,
48 | "web_ip": "tcp://0.0.0.0:5555",
49 | "show_stream": true,
50 | "fourcc": "DIVX",
51 | "flask_server": true,
52 | "flask_port": 5000,
53 | "flask_ip": "0.0.0.0"
54 | }
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | sudo apt-get install libatlas-base-dev -y
2 | sudo apt-get install libjasper-dev -y
3 | sudo apt-get install libqtgui4 -y
4 | sudo apt-get install python3-pyqt5 -y
5 | sudo apt-get install libqt4-test -y
6 | sudo apt-get install libhdf5-dev -y
7 | sudo apt-get install libhdf5-serial-dev -y
8 | pip3 install opencv-python
9 | pip3 install opencv-contrib-python==4.1.0.25
10 | pip3 install numpy
11 | pip3 install flask
12 | pip3 install imutils
13 | pip3 install zmq
--------------------------------------------------------------------------------
/libs/__pycache__/data.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/libs/__pycache__/data.cpython-36.pyc
--------------------------------------------------------------------------------
/libs/__pycache__/filters.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/libs/__pycache__/filters.cpython-36.pyc
--------------------------------------------------------------------------------
/libs/__pycache__/hooks.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/libs/__pycache__/hooks.cpython-36.pyc
--------------------------------------------------------------------------------
/libs/__pycache__/log.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/libs/__pycache__/log.cpython-36.pyc
--------------------------------------------------------------------------------
/libs/__pycache__/requests_.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/libs/__pycache__/requests_.cpython-36.pyc
--------------------------------------------------------------------------------
/libs/data.py:
--------------------------------------------------------------------------------
1 | class data:
2 |
3 | def __init__(self):
4 | self._ = {}
5 |
6 | def set(self, key, data_):
7 | self._[key] = data_
8 | return data_
9 |
10 | def get(self, key):
11 | if key in self._:
12 | return self._[key]
13 | else:
14 | return False
15 |
--------------------------------------------------------------------------------
/libs/filters.py:
--------------------------------------------------------------------------------
1 | class filters:
2 |
3 | def __init__(self):
4 | self.filters = {}
5 |
6 | def set (self, name, function):
7 | if not name in self.filters:
8 | self.filters[name] = []
9 | self.filters[name].append(function)
10 | else:
11 | self.filters[name].append(function)
12 |
13 | def get (self, name):
14 | if name in self.filters:
15 | return self.filters[name]
16 |
17 | def call (self, name, argv):
18 |
19 | r = argv
20 |
21 | if (not self.get(name) == None):
22 |
23 | for _ in self.get(name):
24 | try:
25 | if callable(_):
26 | r = _(r)
27 | except: pass
28 |
29 | return r
30 |
31 | else:
32 |
33 | return argv
34 |
--------------------------------------------------------------------------------
/libs/hooks.py:
--------------------------------------------------------------------------------
1 | class hooks:
2 |
3 | def __init__(self):
4 | self.hooks = {}
5 |
6 | def set (self, name, function):
7 | if not name in self.hooks:
8 | self.hooks[name] = []
9 | self.hooks[name].append(function)
10 | else:
11 | self.hooks[name].append(function)
12 |
13 | def get (self, name):
14 | if name in self.hooks:
15 | return self.hooks[name]
16 |
17 | def call (self, name, argv):
18 |
19 | if (not self.get(name) == None):
20 |
21 | for _ in self.get(name):
22 | try:
23 | if callable(_):
24 | _(argv)
25 | except: pass
26 |
--------------------------------------------------------------------------------
/libs/log.py:
--------------------------------------------------------------------------------
1 | class log:
2 |
3 | use_file = False
4 |
5 | def info (self, status, text):
6 |
7 | print ('[{status:>2}]: {text}'.format(
8 | status=status,
9 | text=text
10 | ))
11 |
--------------------------------------------------------------------------------
/libs/requests_.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | class requests_:
4 |
5 | def __init__(self):
6 | self.requests = {}
7 | self.r = requests
8 |
9 | def set (self, name, function):
10 | if not name in self.requests:
11 | self.requests[name] = []
12 | self.requests[name].append(function)
13 | else:
14 | self.requests[name].append(function)
15 |
16 | def get (self, name):
17 | if name in self.requests:
18 | return self.requests[name]
19 |
20 | def call (self, name, argv):
21 |
22 | if (not self.get(name) == None):
23 |
24 | for _ in self.get(name):
25 | try:
26 |
27 | if (_['method'] == 'GET'):
28 | self.r.get(_['url'], auth=_['auth'], params=_['params'])
29 |
30 | elif (_['method'] == 'POST'):
31 | self.r.post(_['url'], auth=_['auth'], params=_['params'])
32 |
33 | elif (_['method'] == 'PUT'):
34 | self.r.post(_['url'], auth=_['auth'], params=_['params'])
35 |
36 | except: pass
37 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | # Software for creating a video server
2 | # for home video surveillance.
3 | #
4 | # version: 1.0.0
5 | # author: iRTEX Creative
6 |
7 | from flask import Flask, render_template, Response
8 | from imutils.object_detection import non_max_suppression
9 | from libs.hooks import hooks
10 | from libs.log import log
11 | from libs.data import data
12 | from libs.requests_ import requests_
13 | from libs.filters import filters
14 | from user_hooks import _user_hooks as uh
15 | from random import randint
16 |
17 | import imutils
18 | import datetime
19 | import numpy as np
20 | import sys
21 | import cv2
22 | import os
23 | import time
24 | import base64
25 | import zmq
26 | import json
27 | import glob
28 | import threading
29 |
30 |
31 | def main(argv):
32 |
33 | # Log
34 | Log.info('OK', 'System startup')
35 |
36 | # Setup masks
37 | class mask:
38 |
39 | def __init__(self, data):
40 | self.data = data
41 |
42 | def file(self, string):
43 |
44 | return string.format(
45 | time=(datetime.datetime.now()).strftime(cfg['time_mask']),
46 | isotme=(datetime.datetime.now()).isoformat(),
47 | count=str(len(glob.glob('{path}/*'.format(
48 | path=os.path.dirname(os.path.abspath('static/' + cfg['record_file_mask']))
49 | )))),
50 | d=(datetime.datetime.now()).strftime("%d"),
51 | m=(datetime.datetime.now()).strftime("%m"),
52 | Y=(datetime.datetime.now()).strftime("%Y"),
53 | H=(datetime.datetime.now()).strftime("%H"),
54 | M=(datetime.datetime.now()).strftime("%M"),
55 | S=(datetime.datetime.now()).strftime("%S"),
56 | )
57 |
58 | def fps(self, string):
59 |
60 | return string.format(
61 | max=str(self.data['max']),
62 | current=str(self.data['current'])
63 | )
64 |
65 | def server(self, string):
66 |
67 | return string.format(
68 | local='0.0.0.0',
69 | random_port=str(randint(49152,65535))
70 | )
71 |
72 | # Try open web server
73 | if cfg['web_stream'] == True:
74 |
75 | Log.info('WAIT', 'Try open socket server')
76 |
77 | context = zmq.Context()
78 | footage_socket = context.socket(zmq.PUB)
79 | footage_socket.connect(cfg['web_ip'])
80 |
81 | Log.info('OK', 'Socket server is started')
82 | Log.info('OK', 'Server: {ip}'.format(ip=str(mask({}).server(cfg['web_ip']))))
83 |
84 | Hooks.call('on_start_webserver', None)
85 |
86 | # Try open Flask server
87 | if cfg['flask_server'] == True:
88 |
89 | def app():
90 |
91 | app = Flask(__name__)
92 |
93 | def __stream__():
94 |
95 | global ready_frame
96 |
97 | Log.info('STREAM', 'Start stream')
98 |
99 | while True:
100 |
101 | try:
102 |
103 | ret, jpeg = cv2.imencode('.jpg', ready_frame)
104 |
105 | yield (b'--frame\r\n'
106 | b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n\r\n')
107 |
108 | except:
109 | pass
110 |
111 | @app.route('/video')
112 | def __main__():
113 | return Response(__stream__(), mimetype='multipart/x-mixed-replace; boundary=frame')
114 |
115 | @app.route('/records')
116 | def __records__():
117 | return render_template('records.html', videos=os.listdir('./static/'))
118 |
119 | if __name__ == '__main__':
120 | app.run(host=str(mask({}).server(cfg['flask_ip'])), port=int(mask({}).server(str(cfg['flask_port']))))
121 |
122 | threading.Thread(target=app).start()
123 |
124 | # Start window thread
125 | cv2.startWindowThread()
126 |
127 | # Start detector
128 | def detector():
129 | pass
130 |
131 | threading.Thread(target=detector).start()
132 |
133 | # NET
134 | if cfg['net_detect']['enabled'] == True:
135 |
136 | net = {
137 | "net": cv2.dnn.readNetFromCaffe('models/MobileNetSSD_deploy.prototxt.txt', 'models/MobileNetSSD_deploy.caffemodel'),
138 | "CLASSES": cfg['net_detect']['classes']
139 | }
140 |
141 | # Mount camera
142 | Log.info('WAIT', 'Wait camera')
143 |
144 | while (True):
145 |
146 | for i in range(0, 3):
147 |
148 | Hooks.call('on_wait_camera', i)
149 |
150 | if (cfg['stream'] == False):
151 |
152 | if (cfg['video'] == False): cap = cv2.VideoCapture(i)
153 | else: cv2.VideoCapture(cfg['video'])
154 |
155 | else: cap = cv2.VideoCapture(cfg['stream'])
156 |
157 | # Main script
158 | if cap.isOpened():
159 |
160 | Log.info('OK', 'Camera is connected')
161 |
162 | if (cfg['detect_people'] == True):
163 | hog = cv2.HOGDescriptor()
164 | hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
165 |
166 | if (cfg['fourcc'] == 'MJPG'):
167 | fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
168 |
169 | elif (cfg['fourcc'] == 'FMP4'):
170 | fourcc = cv2.VideoWriter_fourcc('F','M','P','4')
171 |
172 | elif (cfg['fourcc'] == 'MP4V'):
173 | fourcc = cv2.VideoWriter_fourcc(*'mp4v')
174 |
175 | elif (cfg['fourcc'] == 'DIVX'):
176 | fourcc = cv2.VideoWriter_fourcc(*'DIVX')
177 |
178 | elif (cfg['fourcc'] == 'iYUV'):
179 | fourcc = cv2.VideoWriter_fourcc('i', 'Y', 'U', 'V')
180 |
181 | else:
182 | fourcc = cv2.VideoWriter_fourcc(*'XVID')
183 |
184 |
185 | _video = cv2.VideoWriter(
186 | (os.path.dirname(os.path.realpath(__file__))) + '/static/' + mask({}).file(cfg['record_file_mask']),
187 | fourcc,
188 | cfg['recorder_fps'],
189 | (int(cap.get(3)), int(cap.get(4)))
190 | )
191 |
192 | if _video and os.path.isfile((os.path.dirname(os.path.realpath(__file__))) + '/static/' + mask({}).file(cfg['record_file_mask'])):
193 |
194 | Log.info('OK', 'Video file has been created')
195 | Hooks.call('on_videofile_created', (os.path.dirname(os.path.realpath(__file__))) + '/static/' + mask({}).file(cfg['record_file_mask']))
196 |
197 | else:
198 |
199 | Log.info('ERROR', 'Folder for recording video is not available! Trying to record a video in an open folder')
200 |
201 | _video = cv2.VideoWriter(
202 | mask({}).file(cfg['record_file_reserve_mask']),
203 | fourcc,
204 | cfg['recorder_fps'],
205 | (int(cap.get(3)), int(cap.get(4)))
206 | )
207 |
208 | if _video and os.path.isfile(mask({}).file(cfg['record_file_reserve_mask'])):
209 |
210 | Log.info('OK', 'Video file has been created')
211 | Hooks.call('on_reserve_videofile_created', mask({}).file(cfg['record_file_reserve_mask']))
212 |
213 | else:
214 |
215 | if (Filters.get('on_reserve_videofile')):
216 |
217 | Log.info('INFO', 'Filter found for backup file. Try to use it as a name')
218 |
219 | _video = cv2.VideoWriter(
220 | mask({}).file(Filters.call('on_reserve_videofile', cfg['record_file_reserve_mask'])),
221 | fourcc,
222 | cfg['recorder_fps'],
223 | (int(cap.get(3)), int(cap.get(4)))
224 | )
225 |
226 | if _video and os.path.isfile(mask({}).file(Filters.call('on_reserve_videofile', cfg['record_file_reserve_mask']))):
227 |
228 | Log.info('OK', 'Video file has been created')
229 | Hooks.call('on_reserve_videofile_created', mask({}).file(cfg['record_file_reserve_mask']))
230 |
231 | else:
232 |
233 | Log.info('ERROR', 'Video file was not created.')
234 | Hooks.call('on_reserve_videofile_not_created', mask({}).file(cfg['record_file_reserve_mask']))
235 |
236 | else:
237 |
238 | Log.info('ERROR', 'Video file was not created.')
239 | Hooks.call('on_reserve_videofile_not_created', mask({}).file(cfg['record_file_reserve_mask']))
240 |
241 |
242 | # Create mask object
243 | if cfg['motion_detect'] == True:
244 | _fgbg = cv2.createBackgroundSubtractorMOG2(False)
245 |
246 | # Set path
247 | cascade_path_face = cv2.data.haarcascades + 'haarcascade_frontalface_alt2.xml'
248 | cascade_path_eye = cv2.data.haarcascades + 'haarcascade_eye_tree_eyeglasses.xml'
249 | cascade_path_body = cv2.data.haarcascades + 'haarcascade_fullbody.xml'
250 | cascade_path_upper = cv2.data.haarcascades + 'haarcascade_upperbody.xml'
251 | cascade_path_lower = cv2.data.haarcascades + 'haarcascade_lowerbody.xml'
252 | cascade_path_cars = 'models/haarcascade_cars3.xml'
253 |
254 | # Init cascade
255 | face_cascade = cv2.CascadeClassifier(cascade_path_face)
256 | eye_cascade = cv2.CascadeClassifier(cascade_path_eye)
257 | body_cascade = cv2.CascadeClassifier(cascade_path_body)
258 | upper_cascade = cv2.CascadeClassifier(cascade_path_upper)
259 | lower_cascade = cv2.CascadeClassifier(cascade_path_lower)
260 | cars_cascade = cv2.CascadeClassifier(cascade_path_cars)
261 |
262 | while True:
263 |
264 | global ready_frame
265 |
266 | # Time frame start
267 | _time_frame_start = time.time()
268 | Hooks.call('on_frame_start', _time_frame_start)
269 |
270 | ret, frame = cap.read()
271 |
272 | if ret:
273 |
274 | # ZIP Frame
275 | if (not cfg['video_zip'] == False):
276 |
277 | if (cfg['video_zip'] == 'HD'):
278 | frame = cv2.resize(frame, (int(1080), int(720)), interpolation=cv2.INTER_NEAREST)
279 |
280 | elif (type(cfg['video_zip']) == type(0.1)):
281 | frame = cv2.resize(frame, (0, 0), fx=cfg['video_zip'], fy=cfg['video_zip'])
282 |
283 | else:
284 | frame = cv2.resize(frame, (int(cfg['video_zip'][0]), int(cfg['video_zip'][1])), interpolation=cv2.INTER_NEAREST)
285 |
286 | # Create children frames
287 | frame_gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
288 |
289 | (_h, _w) = frame.shape[:2]
290 |
291 |
292 | _frame_text = "{value}\n".format(value=cfg['text_on_frame'])
293 |
294 | # Get the foreground mask
295 | if cfg['motion_detect'] == True:
296 | _fgmask = _fgbg.apply(frame_gray)
297 |
298 | # Count all the non zero pixels within the mask
299 | _count = np.count_nonzero(_fgmask)
300 |
301 | if int(_count) > int(cfg['pixel_update_for_detect']):
302 |
303 | if cfg['show_detect_motion_on_frame'] == True:
304 | _frame_text += "Detect motion! Update pixels: {value}\n".format(value=str(_count))
305 |
306 | if cfg['show_time_on_frame'] == True:
307 |
308 | d = datetime.datetime.now()
309 | _frame_text += "{value}\n".format(value=d.strftime(cfg['time_mask']))
310 |
311 | if cfg['detect_body'] == True or type(cfg['detect_body']) == type({}):
312 |
313 | if (type(cfg['detect_body']) == type(True)) or (cfg['detect_body']['full'] == True): bodies = body_cascade.detectMultiScale(frame_gray, 1.3, 5)
314 | if (type(cfg['detect_body']) == type(True)) or (cfg['detect_body']['upper'] == True): upper = upper_cascade.detectMultiScale(frame_gray, 1.3, 5)
315 | if (type(cfg['detect_body']) == type(True)) or (cfg['detect_body']['lower'] == True): lower = lower_cascade.detectMultiScale(frame_gray, 1.3, 5)
316 |
317 | if (type(cfg['detect_body']) == type({}) and cfg['detect_body']['full'] == True) or (type(cfg['detect_body']) == type(True)):
318 |
319 | for (x, y, w, h) in bodies:
320 |
321 | cv2.rectangle(frame, (x, y), (x + w, y + h), cfg['detect_body_boxcolor'], 1)
322 |
323 | if cfg['detect_text_labels'] == True:
324 | cv2.putText(frame, 'Body', (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4, cfg['detect_text_labels_color'])
325 |
326 | if (cfg['zoom_body']) == True:
327 | frame = frame[y:y + h, x:x + w]
328 |
329 | Hooks.call('on_body_detect', frame[y:y + h, x:x + w])
330 | Request.call('on_body_detect', frame[y:y + h, x:x + w])
331 |
332 | if (type(cfg['detect_body']) == type({}) and cfg['detect_body']['upper'] == True) or (type(cfg['detect_body']) == type(True)):
333 |
334 | for (x, y, w, h) in upper:
335 |
336 | cv2.rectangle(frame, (x, y), (x + w, y + h), cfg['detect_body_boxcolor'], 1)
337 |
338 | if cfg['detect_text_labels'] == True:
339 | cv2.putText(frame, 'Body Upper', (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4,
340 | cfg['detect_text_labels_color'])
341 |
342 | Hooks.call('on_body_upper_detect', frame[y:y + h, x:x + w])
343 | Request.call('on_body_upper_detect', frame[y:y + h, x:x + w])
344 |
345 | if (type(cfg['detect_body']) == type({}) and cfg['detect_body']['lower'] == True) or (type(cfg['detect_body']) == type(True)):
346 |
347 | for (x, y, w, h) in lower:
348 |
349 | cv2.rectangle(frame, (x, y), (x + w, y + h), cfg['detect_body_boxcolor'], 1)
350 |
351 | if cfg['detect_text_labels'] == True:
352 | cv2.putText(frame, 'Body Lower', (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4,
353 | cfg['detect_text_labels_color'])
354 |
355 | Hooks.call('on_body_lower_detect', frame[y:y + h, x:x + w])
356 | Request.call('on_body_lower_detect', frame[y:y + h, x:x + w])
357 |
358 | if cfg['detect_people'] == True:
359 |
360 | (rects, weights) = hog.detectMultiScale(frame_gray)
361 |
362 | rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
363 | pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)
364 |
365 | for (xA, yA, xB, yB) in pick:
366 |
367 | cv2.rectangle(frame, (xA, yA), (xB, yB), cfg['detect_people_boxcolor'], 1)
368 |
369 | if cfg['detect_text_labels'] == True:
370 | cv2.putText(frame, 'Human', (xA, yA - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4, cfg['detect_text_labels_color'])
371 |
372 | if cfg['zoom_people'] == True:
373 | if len(pick) == 1:
374 | frame = frame[yA:yA + yB, xA:xA + xB]
375 |
376 | if cfg['detect_face'] == True:
377 |
378 | faces = face_cascade.detectMultiScale(frame_gray)
379 |
380 | for (x, y, w, h) in faces:
381 |
382 | cv2.rectangle(frame, (x, y), (x + w, y + h), cfg['detect_face_boxcolor'], 1)
383 |
384 | if cfg['detect_text_labels'] == True:
385 | cv2.putText(frame, 'Face', (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4,
386 | cfg['detect_text_labels_color'])
387 |
388 | Hooks.call('on_face_detect', frame[y:y + h, x:x + w])
389 | Request.call('on_face_detect', frame[y:y + h, x:x + w])
390 |
391 | if cfg['detect_eye'] == True:
392 |
393 | eye = eye_cascade.detectMultiScale(frame_gray)
394 |
395 | for (x_, y_, w_, h_) in eye:
396 |
397 | cv2.rectangle(frame, (x_, y_), (x_ + w_, y_ + h_),
398 | cfg['detect_body_boxcolor'], 1)
399 |
400 | if cfg['detect_text_labels'] == True:
401 | cv2.putText(frame, 'Eye', (x_, y_ - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4,
402 | cfg['detect_text_labels_color'])
403 |
404 | Hooks.call('on_eye_detect', frame[y_:y_ + h_, x_:x_ + w_])
405 | Request.call('on_eye_detect', frame[y_:y_ + h_, x_:x_ + w_])
406 |
407 | if cfg['detect_car'] == True:
408 |
409 | cars = cars_cascade.detectMultiScale(frame_gray)
410 |
411 | for (x, y, w, h) in cars:
412 |
413 | cv2.rectangle(frame, (x, y), (x + w, y + h), cfg['detect_car_boxcolor'], 1)
414 |
415 | if cfg['detect_text_labels'] == True:
416 | cv2.putText(frame, 'Car', (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.4, cfg['detect_text_labels_color'])
417 |
418 | Hooks.call('on_car_detect', frame[y:y + h, x:x + w])
419 | Request.call('on_car_detect', frame[y:y + h, x:x + w])
420 |
421 | if cfg['net_detect']['enabled'] == True:
422 |
423 | blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),
424 | 0.007843, (300, 300), 127.5)
425 | net['net'].setInput(blob)
426 | detections = net['net'].forward()
427 |
428 | for i in np.arange(0, detections.shape[2]):
429 | confidence = detections[0, 0, i, 2]
430 | if confidence > 0:
431 | idx = int(detections[0, 0, i, 1])
432 | box = detections[0, 0, i, 3:7] * np.array([_w, _h, _w, _h])
433 | (startX, startY, endX, endY) = box.astype("int")
434 | label = "{}: {:.2f}%".format(net['CLASSES'][idx], confidence * 100)
435 | cv2.rectangle(frame, (startX, startY), (endX, endY), cfg['net_detect']['boxcolor'], 1)
436 | y = startY - 15 if startY - 15 > 15 else startY + 15
437 | cv2.putText(frame, label, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.4, cfg['net_detect']['boxcolor'], 1)
438 |
439 | Hooks.call("on_net_{}_detect".format(net['CLASSES'][idx]), frame[startY:startY + _h, startX:startX + _w])
440 |
441 | if cfg['show_fps_on_frame'] == True:
442 |
443 | fps = 60 / (time.time() - _time_frame_start)
444 |
445 | _frame_text += "{value}\n".format(value=mask({
446 | "max": str(cap.get(cv2.CAP_PROP_FPS)),
447 | "current": str(round(fps, 1))
448 | }).fps(cfg['fps_mask']))
449 |
450 | # _frame_text += "{value}\n".format(value=)
451 |
452 | # Put text
453 | y0, dy = 13 * 2, 13 * 2
454 | for i, line in enumerate(Filters.call('on_frame_text', _frame_text).split('\n')):
455 | y = y0 + i * dy
456 | cv2.putText(frame, line, (13, y), cv2.FONT_HERSHEY_SIMPLEX, cfg['text_on_frame_size'], cfg['text_on_frame_color'])
457 |
458 | Hooks.call('on_before_write_frame', frame)
459 |
460 | # Save video
461 | if (cfg['save_video']) == True:
462 | _video.write(Filters.call('on_frame_record', frame))
463 | Hooks.call('on_save_video', frame)
464 |
465 | # Motion detect
466 | else:
467 | if (cfg['save_video_on_movies'] == True) and cfg['motion_detect'] == True:
468 | if int(_count) > int(cfg['pixel_update_for_detect']):
469 | _video.write(Filters.call('on_frame_motion_detect_record', frame))
470 | Hooks.call('on_motion_detect', frame)
471 | Hooks.call('on_save_video', frame)
472 | Request.call('on_motion_detect', frame)
473 |
474 | # Send picture to server
475 | if cfg['web_stream'] == True:
476 |
477 | encoded, buffer = cv2.imencode('.jpg', Filters.call('on_socket_frame', frame))
478 |
479 | jpg_as_text = base64.b64encode(buffer)
480 | footage_socket.send(Filters.call('on_socket_frame_encoded', jpg_as_text))
481 |
482 | Hooks.call('on_frame_send_to_server', jpg_as_text)
483 |
484 | # Setup ready frame
485 | ready_frame = frame
486 |
487 | # Show picture on PC
488 | if cfg['show_stream'] == True:
489 | cv2.imshow("Video", frame)
490 |
491 | key = cv2.waitKey(10)
492 |
493 | if key == 27:
494 | Hooks.call('on_exit', True)
495 | break
496 |
497 | else: break
498 |
499 | cv2.destroyAllWindows()
500 |
501 | cap.release()
502 | _video.release()
503 |
504 | Hooks.call('on_release', None)
505 |
506 | # Send noise to video server
507 | im = np.empty((720, 1080), np.uint8)
508 | ready_frame = cv2.randn(im, (0), (99))
509 |
510 |
511 | if __name__ == '__main__':
512 |
513 | # Create env
514 | global ready_frame
515 | ready_frame = False
516 | Hooks = hooks()
517 | Log = log()
518 | Filters = filters()
519 | Request = requests_()
520 |
521 | # Init plugins
522 | uh(cv2, Hooks, Filters)
523 |
524 | # First hook
525 | Hooks.call('on_init', True)
526 |
527 | # Set config
528 | with open('config.json') as config_file:
529 | cfg = Filters.call('on_config', json.load(config_file))
530 |
531 | Hooks.call('on_setup_cfg', cfg)
532 |
533 | main(sys.argv)
534 |
--------------------------------------------------------------------------------
/models/MobileNetSSD_deploy.caffemodel:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masloff-open-projects/OpenCV-Webcam-Recorder-and-Streamer/83d1ca246d725ae991d2a740bb9c12f262c99e28/models/MobileNetSSD_deploy.caffemodel
--------------------------------------------------------------------------------
/models/MobileNetSSD_deploy.prototxt.txt:
--------------------------------------------------------------------------------
1 | name: "MobileNet-SSD"
2 | input: "data"
3 | input_shape {
4 | dim: 1
5 | dim: 3
6 | dim: 300
7 | dim: 300
8 | }
9 | layer {
10 | name: "conv0"
11 | type: "Convolution"
12 | bottom: "data"
13 | top: "conv0"
14 | param {
15 | lr_mult: 1.0
16 | decay_mult: 1.0
17 | }
18 | param {
19 | lr_mult: 2.0
20 | decay_mult: 0.0
21 | }
22 | convolution_param {
23 | num_output: 32
24 | pad: 1
25 | kernel_size: 3
26 | stride: 2
27 | weight_filler {
28 | type: "msra"
29 | }
30 | bias_filler {
31 | type: "constant"
32 | value: 0.0
33 | }
34 | }
35 | }
36 | layer {
37 | name: "conv0/relu"
38 | type: "ReLU"
39 | bottom: "conv0"
40 | top: "conv0"
41 | }
42 | layer {
43 | name: "conv1/dw"
44 | type: "Convolution"
45 | bottom: "conv0"
46 | top: "conv1/dw"
47 | param {
48 | lr_mult: 1.0
49 | decay_mult: 1.0
50 | }
51 | param {
52 | lr_mult: 2.0
53 | decay_mult: 0.0
54 | }
55 | convolution_param {
56 | num_output: 32
57 | pad: 1
58 | kernel_size: 3
59 | group: 32
60 | engine: CAFFE
61 | weight_filler {
62 | type: "msra"
63 | }
64 | bias_filler {
65 | type: "constant"
66 | value: 0.0
67 | }
68 | }
69 | }
70 | layer {
71 | name: "conv1/dw/relu"
72 | type: "ReLU"
73 | bottom: "conv1/dw"
74 | top: "conv1/dw"
75 | }
76 | layer {
77 | name: "conv1"
78 | type: "Convolution"
79 | bottom: "conv1/dw"
80 | top: "conv1"
81 | param {
82 | lr_mult: 1.0
83 | decay_mult: 1.0
84 | }
85 | param {
86 | lr_mult: 2.0
87 | decay_mult: 0.0
88 | }
89 | convolution_param {
90 | num_output: 64
91 | kernel_size: 1
92 | weight_filler {
93 | type: "msra"
94 | }
95 | bias_filler {
96 | type: "constant"
97 | value: 0.0
98 | }
99 | }
100 | }
101 | layer {
102 | name: "conv1/relu"
103 | type: "ReLU"
104 | bottom: "conv1"
105 | top: "conv1"
106 | }
107 | layer {
108 | name: "conv2/dw"
109 | type: "Convolution"
110 | bottom: "conv1"
111 | top: "conv2/dw"
112 | param {
113 | lr_mult: 1.0
114 | decay_mult: 1.0
115 | }
116 | param {
117 | lr_mult: 2.0
118 | decay_mult: 0.0
119 | }
120 | convolution_param {
121 | num_output: 64
122 | pad: 1
123 | kernel_size: 3
124 | stride: 2
125 | group: 64
126 | engine: CAFFE
127 | weight_filler {
128 | type: "msra"
129 | }
130 | bias_filler {
131 | type: "constant"
132 | value: 0.0
133 | }
134 | }
135 | }
136 | layer {
137 | name: "conv2/dw/relu"
138 | type: "ReLU"
139 | bottom: "conv2/dw"
140 | top: "conv2/dw"
141 | }
142 | layer {
143 | name: "conv2"
144 | type: "Convolution"
145 | bottom: "conv2/dw"
146 | top: "conv2"
147 | param {
148 | lr_mult: 1.0
149 | decay_mult: 1.0
150 | }
151 | param {
152 | lr_mult: 2.0
153 | decay_mult: 0.0
154 | }
155 | convolution_param {
156 | num_output: 128
157 | kernel_size: 1
158 | weight_filler {
159 | type: "msra"
160 | }
161 | bias_filler {
162 | type: "constant"
163 | value: 0.0
164 | }
165 | }
166 | }
167 | layer {
168 | name: "conv2/relu"
169 | type: "ReLU"
170 | bottom: "conv2"
171 | top: "conv2"
172 | }
173 | layer {
174 | name: "conv3/dw"
175 | type: "Convolution"
176 | bottom: "conv2"
177 | top: "conv3/dw"
178 | param {
179 | lr_mult: 1.0
180 | decay_mult: 1.0
181 | }
182 | param {
183 | lr_mult: 2.0
184 | decay_mult: 0.0
185 | }
186 | convolution_param {
187 | num_output: 128
188 | pad: 1
189 | kernel_size: 3
190 | group: 128
191 | engine: CAFFE
192 | weight_filler {
193 | type: "msra"
194 | }
195 | bias_filler {
196 | type: "constant"
197 | value: 0.0
198 | }
199 | }
200 | }
201 | layer {
202 | name: "conv3/dw/relu"
203 | type: "ReLU"
204 | bottom: "conv3/dw"
205 | top: "conv3/dw"
206 | }
207 | layer {
208 | name: "conv3"
209 | type: "Convolution"
210 | bottom: "conv3/dw"
211 | top: "conv3"
212 | param {
213 | lr_mult: 1.0
214 | decay_mult: 1.0
215 | }
216 | param {
217 | lr_mult: 2.0
218 | decay_mult: 0.0
219 | }
220 | convolution_param {
221 | num_output: 128
222 | kernel_size: 1
223 | weight_filler {
224 | type: "msra"
225 | }
226 | bias_filler {
227 | type: "constant"
228 | value: 0.0
229 | }
230 | }
231 | }
232 | layer {
233 | name: "conv3/relu"
234 | type: "ReLU"
235 | bottom: "conv3"
236 | top: "conv3"
237 | }
238 | layer {
239 | name: "conv4/dw"
240 | type: "Convolution"
241 | bottom: "conv3"
242 | top: "conv4/dw"
243 | param {
244 | lr_mult: 1.0
245 | decay_mult: 1.0
246 | }
247 | param {
248 | lr_mult: 2.0
249 | decay_mult: 0.0
250 | }
251 | convolution_param {
252 | num_output: 128
253 | pad: 1
254 | kernel_size: 3
255 | stride: 2
256 | group: 128
257 | engine: CAFFE
258 | weight_filler {
259 | type: "msra"
260 | }
261 | bias_filler {
262 | type: "constant"
263 | value: 0.0
264 | }
265 | }
266 | }
267 | layer {
268 | name: "conv4/dw/relu"
269 | type: "ReLU"
270 | bottom: "conv4/dw"
271 | top: "conv4/dw"
272 | }
273 | layer {
274 | name: "conv4"
275 | type: "Convolution"
276 | bottom: "conv4/dw"
277 | top: "conv4"
278 | param {
279 | lr_mult: 1.0
280 | decay_mult: 1.0
281 | }
282 | param {
283 | lr_mult: 2.0
284 | decay_mult: 0.0
285 | }
286 | convolution_param {
287 | num_output: 256
288 | kernel_size: 1
289 | weight_filler {
290 | type: "msra"
291 | }
292 | bias_filler {
293 | type: "constant"
294 | value: 0.0
295 | }
296 | }
297 | }
298 | layer {
299 | name: "conv4/relu"
300 | type: "ReLU"
301 | bottom: "conv4"
302 | top: "conv4"
303 | }
304 | layer {
305 | name: "conv5/dw"
306 | type: "Convolution"
307 | bottom: "conv4"
308 | top: "conv5/dw"
309 | param {
310 | lr_mult: 1.0
311 | decay_mult: 1.0
312 | }
313 | param {
314 | lr_mult: 2.0
315 | decay_mult: 0.0
316 | }
317 | convolution_param {
318 | num_output: 256
319 | pad: 1
320 | kernel_size: 3
321 | group: 256
322 | engine: CAFFE
323 | weight_filler {
324 | type: "msra"
325 | }
326 | bias_filler {
327 | type: "constant"
328 | value: 0.0
329 | }
330 | }
331 | }
332 | layer {
333 | name: "conv5/dw/relu"
334 | type: "ReLU"
335 | bottom: "conv5/dw"
336 | top: "conv5/dw"
337 | }
338 | layer {
339 | name: "conv5"
340 | type: "Convolution"
341 | bottom: "conv5/dw"
342 | top: "conv5"
343 | param {
344 | lr_mult: 1.0
345 | decay_mult: 1.0
346 | }
347 | param {
348 | lr_mult: 2.0
349 | decay_mult: 0.0
350 | }
351 | convolution_param {
352 | num_output: 256
353 | kernel_size: 1
354 | weight_filler {
355 | type: "msra"
356 | }
357 | bias_filler {
358 | type: "constant"
359 | value: 0.0
360 | }
361 | }
362 | }
363 | layer {
364 | name: "conv5/relu"
365 | type: "ReLU"
366 | bottom: "conv5"
367 | top: "conv5"
368 | }
369 | layer {
370 | name: "conv6/dw"
371 | type: "Convolution"
372 | bottom: "conv5"
373 | top: "conv6/dw"
374 | param {
375 | lr_mult: 1.0
376 | decay_mult: 1.0
377 | }
378 | param {
379 | lr_mult: 2.0
380 | decay_mult: 0.0
381 | }
382 | convolution_param {
383 | num_output: 256
384 | pad: 1
385 | kernel_size: 3
386 | stride: 2
387 | group: 256
388 | engine: CAFFE
389 | weight_filler {
390 | type: "msra"
391 | }
392 | bias_filler {
393 | type: "constant"
394 | value: 0.0
395 | }
396 | }
397 | }
398 | layer {
399 | name: "conv6/dw/relu"
400 | type: "ReLU"
401 | bottom: "conv6/dw"
402 | top: "conv6/dw"
403 | }
404 | layer {
405 | name: "conv6"
406 | type: "Convolution"
407 | bottom: "conv6/dw"
408 | top: "conv6"
409 | param {
410 | lr_mult: 1.0
411 | decay_mult: 1.0
412 | }
413 | param {
414 | lr_mult: 2.0
415 | decay_mult: 0.0
416 | }
417 | convolution_param {
418 | num_output: 512
419 | kernel_size: 1
420 | weight_filler {
421 | type: "msra"
422 | }
423 | bias_filler {
424 | type: "constant"
425 | value: 0.0
426 | }
427 | }
428 | }
429 | layer {
430 | name: "conv6/relu"
431 | type: "ReLU"
432 | bottom: "conv6"
433 | top: "conv6"
434 | }
435 | layer {
436 | name: "conv7/dw"
437 | type: "Convolution"
438 | bottom: "conv6"
439 | top: "conv7/dw"
440 | param {
441 | lr_mult: 1.0
442 | decay_mult: 1.0
443 | }
444 | param {
445 | lr_mult: 2.0
446 | decay_mult: 0.0
447 | }
448 | convolution_param {
449 | num_output: 512
450 | pad: 1
451 | kernel_size: 3
452 | group: 512
453 | engine: CAFFE
454 | weight_filler {
455 | type: "msra"
456 | }
457 | bias_filler {
458 | type: "constant"
459 | value: 0.0
460 | }
461 | }
462 | }
463 | layer {
464 | name: "conv7/dw/relu"
465 | type: "ReLU"
466 | bottom: "conv7/dw"
467 | top: "conv7/dw"
468 | }
469 | layer {
470 | name: "conv7"
471 | type: "Convolution"
472 | bottom: "conv7/dw"
473 | top: "conv7"
474 | param {
475 | lr_mult: 1.0
476 | decay_mult: 1.0
477 | }
478 | param {
479 | lr_mult: 2.0
480 | decay_mult: 0.0
481 | }
482 | convolution_param {
483 | num_output: 512
484 | kernel_size: 1
485 | weight_filler {
486 | type: "msra"
487 | }
488 | bias_filler {
489 | type: "constant"
490 | value: 0.0
491 | }
492 | }
493 | }
494 | layer {
495 | name: "conv7/relu"
496 | type: "ReLU"
497 | bottom: "conv7"
498 | top: "conv7"
499 | }
500 | layer {
501 | name: "conv8/dw"
502 | type: "Convolution"
503 | bottom: "conv7"
504 | top: "conv8/dw"
505 | param {
506 | lr_mult: 1.0
507 | decay_mult: 1.0
508 | }
509 | param {
510 | lr_mult: 2.0
511 | decay_mult: 0.0
512 | }
513 | convolution_param {
514 | num_output: 512
515 | pad: 1
516 | kernel_size: 3
517 | group: 512
518 | engine: CAFFE
519 | weight_filler {
520 | type: "msra"
521 | }
522 | bias_filler {
523 | type: "constant"
524 | value: 0.0
525 | }
526 | }
527 | }
528 | layer {
529 | name: "conv8/dw/relu"
530 | type: "ReLU"
531 | bottom: "conv8/dw"
532 | top: "conv8/dw"
533 | }
534 | layer {
535 | name: "conv8"
536 | type: "Convolution"
537 | bottom: "conv8/dw"
538 | top: "conv8"
539 | param {
540 | lr_mult: 1.0
541 | decay_mult: 1.0
542 | }
543 | param {
544 | lr_mult: 2.0
545 | decay_mult: 0.0
546 | }
547 | convolution_param {
548 | num_output: 512
549 | kernel_size: 1
550 | weight_filler {
551 | type: "msra"
552 | }
553 | bias_filler {
554 | type: "constant"
555 | value: 0.0
556 | }
557 | }
558 | }
559 | layer {
560 | name: "conv8/relu"
561 | type: "ReLU"
562 | bottom: "conv8"
563 | top: "conv8"
564 | }
565 | layer {
566 | name: "conv9/dw"
567 | type: "Convolution"
568 | bottom: "conv8"
569 | top: "conv9/dw"
570 | param {
571 | lr_mult: 1.0
572 | decay_mult: 1.0
573 | }
574 | param {
575 | lr_mult: 2.0
576 | decay_mult: 0.0
577 | }
578 | convolution_param {
579 | num_output: 512
580 | pad: 1
581 | kernel_size: 3
582 | group: 512
583 | engine: CAFFE
584 | weight_filler {
585 | type: "msra"
586 | }
587 | bias_filler {
588 | type: "constant"
589 | value: 0.0
590 | }
591 | }
592 | }
593 | layer {
594 | name: "conv9/dw/relu"
595 | type: "ReLU"
596 | bottom: "conv9/dw"
597 | top: "conv9/dw"
598 | }
599 | layer {
600 | name: "conv9"
601 | type: "Convolution"
602 | bottom: "conv9/dw"
603 | top: "conv9"
604 | param {
605 | lr_mult: 1.0
606 | decay_mult: 1.0
607 | }
608 | param {
609 | lr_mult: 2.0
610 | decay_mult: 0.0
611 | }
612 | convolution_param {
613 | num_output: 512
614 | kernel_size: 1
615 | weight_filler {
616 | type: "msra"
617 | }
618 | bias_filler {
619 | type: "constant"
620 | value: 0.0
621 | }
622 | }
623 | }
624 | layer {
625 | name: "conv9/relu"
626 | type: "ReLU"
627 | bottom: "conv9"
628 | top: "conv9"
629 | }
630 | layer {
631 | name: "conv10/dw"
632 | type: "Convolution"
633 | bottom: "conv9"
634 | top: "conv10/dw"
635 | param {
636 | lr_mult: 1.0
637 | decay_mult: 1.0
638 | }
639 | param {
640 | lr_mult: 2.0
641 | decay_mult: 0.0
642 | }
643 | convolution_param {
644 | num_output: 512
645 | pad: 1
646 | kernel_size: 3
647 | group: 512
648 | engine: CAFFE
649 | weight_filler {
650 | type: "msra"
651 | }
652 | bias_filler {
653 | type: "constant"
654 | value: 0.0
655 | }
656 | }
657 | }
658 | layer {
659 | name: "conv10/dw/relu"
660 | type: "ReLU"
661 | bottom: "conv10/dw"
662 | top: "conv10/dw"
663 | }
664 | layer {
665 | name: "conv10"
666 | type: "Convolution"
667 | bottom: "conv10/dw"
668 | top: "conv10"
669 | param {
670 | lr_mult: 1.0
671 | decay_mult: 1.0
672 | }
673 | param {
674 | lr_mult: 2.0
675 | decay_mult: 0.0
676 | }
677 | convolution_param {
678 | num_output: 512
679 | kernel_size: 1
680 | weight_filler {
681 | type: "msra"
682 | }
683 | bias_filler {
684 | type: "constant"
685 | value: 0.0
686 | }
687 | }
688 | }
689 | layer {
690 | name: "conv10/relu"
691 | type: "ReLU"
692 | bottom: "conv10"
693 | top: "conv10"
694 | }
695 | layer {
696 | name: "conv11/dw"
697 | type: "Convolution"
698 | bottom: "conv10"
699 | top: "conv11/dw"
700 | param {
701 | lr_mult: 1.0
702 | decay_mult: 1.0
703 | }
704 | param {
705 | lr_mult: 2.0
706 | decay_mult: 0.0
707 | }
708 | convolution_param {
709 | num_output: 512
710 | pad: 1
711 | kernel_size: 3
712 | group: 512
713 | engine: CAFFE
714 | weight_filler {
715 | type: "msra"
716 | }
717 | bias_filler {
718 | type: "constant"
719 | value: 0.0
720 | }
721 | }
722 | }
723 | layer {
724 | name: "conv11/dw/relu"
725 | type: "ReLU"
726 | bottom: "conv11/dw"
727 | top: "conv11/dw"
728 | }
729 | layer {
730 | name: "conv11"
731 | type: "Convolution"
732 | bottom: "conv11/dw"
733 | top: "conv11"
734 | param {
735 | lr_mult: 1.0
736 | decay_mult: 1.0
737 | }
738 | param {
739 | lr_mult: 2.0
740 | decay_mult: 0.0
741 | }
742 | convolution_param {
743 | num_output: 512
744 | kernel_size: 1
745 | weight_filler {
746 | type: "msra"
747 | }
748 | bias_filler {
749 | type: "constant"
750 | value: 0.0
751 | }
752 | }
753 | }
754 | layer {
755 | name: "conv11/relu"
756 | type: "ReLU"
757 | bottom: "conv11"
758 | top: "conv11"
759 | }
760 | layer {
761 | name: "conv12/dw"
762 | type: "Convolution"
763 | bottom: "conv11"
764 | top: "conv12/dw"
765 | param {
766 | lr_mult: 1.0
767 | decay_mult: 1.0
768 | }
769 | param {
770 | lr_mult: 2.0
771 | decay_mult: 0.0
772 | }
773 | convolution_param {
774 | num_output: 512
775 | pad: 1
776 | kernel_size: 3
777 | stride: 2
778 | group: 512
779 | engine: CAFFE
780 | weight_filler {
781 | type: "msra"
782 | }
783 | bias_filler {
784 | type: "constant"
785 | value: 0.0
786 | }
787 | }
788 | }
789 | layer {
790 | name: "conv12/dw/relu"
791 | type: "ReLU"
792 | bottom: "conv12/dw"
793 | top: "conv12/dw"
794 | }
795 | layer {
796 | name: "conv12"
797 | type: "Convolution"
798 | bottom: "conv12/dw"
799 | top: "conv12"
800 | param {
801 | lr_mult: 1.0
802 | decay_mult: 1.0
803 | }
804 | param {
805 | lr_mult: 2.0
806 | decay_mult: 0.0
807 | }
808 | convolution_param {
809 | num_output: 1024
810 | kernel_size: 1
811 | weight_filler {
812 | type: "msra"
813 | }
814 | bias_filler {
815 | type: "constant"
816 | value: 0.0
817 | }
818 | }
819 | }
820 | layer {
821 | name: "conv12/relu"
822 | type: "ReLU"
823 | bottom: "conv12"
824 | top: "conv12"
825 | }
826 | layer {
827 | name: "conv13/dw"
828 | type: "Convolution"
829 | bottom: "conv12"
830 | top: "conv13/dw"
831 | param {
832 | lr_mult: 1.0
833 | decay_mult: 1.0
834 | }
835 | param {
836 | lr_mult: 2.0
837 | decay_mult: 0.0
838 | }
839 | convolution_param {
840 | num_output: 1024
841 | pad: 1
842 | kernel_size: 3
843 | group: 1024
844 | engine: CAFFE
845 | weight_filler {
846 | type: "msra"
847 | }
848 | bias_filler {
849 | type: "constant"
850 | value: 0.0
851 | }
852 | }
853 | }
854 | layer {
855 | name: "conv13/dw/relu"
856 | type: "ReLU"
857 | bottom: "conv13/dw"
858 | top: "conv13/dw"
859 | }
860 | layer {
861 | name: "conv13"
862 | type: "Convolution"
863 | bottom: "conv13/dw"
864 | top: "conv13"
865 | param {
866 | lr_mult: 1.0
867 | decay_mult: 1.0
868 | }
869 | param {
870 | lr_mult: 2.0
871 | decay_mult: 0.0
872 | }
873 | convolution_param {
874 | num_output: 1024
875 | kernel_size: 1
876 | weight_filler {
877 | type: "msra"
878 | }
879 | bias_filler {
880 | type: "constant"
881 | value: 0.0
882 | }
883 | }
884 | }
885 | layer {
886 | name: "conv13/relu"
887 | type: "ReLU"
888 | bottom: "conv13"
889 | top: "conv13"
890 | }
891 | layer {
892 | name: "conv14_1"
893 | type: "Convolution"
894 | bottom: "conv13"
895 | top: "conv14_1"
896 | param {
897 | lr_mult: 1.0
898 | decay_mult: 1.0
899 | }
900 | param {
901 | lr_mult: 2.0
902 | decay_mult: 0.0
903 | }
904 | convolution_param {
905 | num_output: 256
906 | kernel_size: 1
907 | weight_filler {
908 | type: "msra"
909 | }
910 | bias_filler {
911 | type: "constant"
912 | value: 0.0
913 | }
914 | }
915 | }
916 | layer {
917 | name: "conv14_1/relu"
918 | type: "ReLU"
919 | bottom: "conv14_1"
920 | top: "conv14_1"
921 | }
922 | layer {
923 | name: "conv14_2"
924 | type: "Convolution"
925 | bottom: "conv14_1"
926 | top: "conv14_2"
927 | param {
928 | lr_mult: 1.0
929 | decay_mult: 1.0
930 | }
931 | param {
932 | lr_mult: 2.0
933 | decay_mult: 0.0
934 | }
935 | convolution_param {
936 | num_output: 512
937 | pad: 1
938 | kernel_size: 3
939 | stride: 2
940 | weight_filler {
941 | type: "msra"
942 | }
943 | bias_filler {
944 | type: "constant"
945 | value: 0.0
946 | }
947 | }
948 | }
949 | layer {
950 | name: "conv14_2/relu"
951 | type: "ReLU"
952 | bottom: "conv14_2"
953 | top: "conv14_2"
954 | }
955 | layer {
956 | name: "conv15_1"
957 | type: "Convolution"
958 | bottom: "conv14_2"
959 | top: "conv15_1"
960 | param {
961 | lr_mult: 1.0
962 | decay_mult: 1.0
963 | }
964 | param {
965 | lr_mult: 2.0
966 | decay_mult: 0.0
967 | }
968 | convolution_param {
969 | num_output: 128
970 | kernel_size: 1
971 | weight_filler {
972 | type: "msra"
973 | }
974 | bias_filler {
975 | type: "constant"
976 | value: 0.0
977 | }
978 | }
979 | }
980 | layer {
981 | name: "conv15_1/relu"
982 | type: "ReLU"
983 | bottom: "conv15_1"
984 | top: "conv15_1"
985 | }
986 | layer {
987 | name: "conv15_2"
988 | type: "Convolution"
989 | bottom: "conv15_1"
990 | top: "conv15_2"
991 | param {
992 | lr_mult: 1.0
993 | decay_mult: 1.0
994 | }
995 | param {
996 | lr_mult: 2.0
997 | decay_mult: 0.0
998 | }
999 | convolution_param {
1000 | num_output: 256
1001 | pad: 1
1002 | kernel_size: 3
1003 | stride: 2
1004 | weight_filler {
1005 | type: "msra"
1006 | }
1007 | bias_filler {
1008 | type: "constant"
1009 | value: 0.0
1010 | }
1011 | }
1012 | }
1013 | layer {
1014 | name: "conv15_2/relu"
1015 | type: "ReLU"
1016 | bottom: "conv15_2"
1017 | top: "conv15_2"
1018 | }
1019 | layer {
1020 | name: "conv16_1"
1021 | type: "Convolution"
1022 | bottom: "conv15_2"
1023 | top: "conv16_1"
1024 | param {
1025 | lr_mult: 1.0
1026 | decay_mult: 1.0
1027 | }
1028 | param {
1029 | lr_mult: 2.0
1030 | decay_mult: 0.0
1031 | }
1032 | convolution_param {
1033 | num_output: 128
1034 | kernel_size: 1
1035 | weight_filler {
1036 | type: "msra"
1037 | }
1038 | bias_filler {
1039 | type: "constant"
1040 | value: 0.0
1041 | }
1042 | }
1043 | }
1044 | layer {
1045 | name: "conv16_1/relu"
1046 | type: "ReLU"
1047 | bottom: "conv16_1"
1048 | top: "conv16_1"
1049 | }
1050 | layer {
1051 | name: "conv16_2"
1052 | type: "Convolution"
1053 | bottom: "conv16_1"
1054 | top: "conv16_2"
1055 | param {
1056 | lr_mult: 1.0
1057 | decay_mult: 1.0
1058 | }
1059 | param {
1060 | lr_mult: 2.0
1061 | decay_mult: 0.0
1062 | }
1063 | convolution_param {
1064 | num_output: 256
1065 | pad: 1
1066 | kernel_size: 3
1067 | stride: 2
1068 | weight_filler {
1069 | type: "msra"
1070 | }
1071 | bias_filler {
1072 | type: "constant"
1073 | value: 0.0
1074 | }
1075 | }
1076 | }
1077 | layer {
1078 | name: "conv16_2/relu"
1079 | type: "ReLU"
1080 | bottom: "conv16_2"
1081 | top: "conv16_2"
1082 | }
1083 | layer {
1084 | name: "conv17_1"
1085 | type: "Convolution"
1086 | bottom: "conv16_2"
1087 | top: "conv17_1"
1088 | param {
1089 | lr_mult: 1.0
1090 | decay_mult: 1.0
1091 | }
1092 | param {
1093 | lr_mult: 2.0
1094 | decay_mult: 0.0
1095 | }
1096 | convolution_param {
1097 | num_output: 64
1098 | kernel_size: 1
1099 | weight_filler {
1100 | type: "msra"
1101 | }
1102 | bias_filler {
1103 | type: "constant"
1104 | value: 0.0
1105 | }
1106 | }
1107 | }
1108 | layer {
1109 | name: "conv17_1/relu"
1110 | type: "ReLU"
1111 | bottom: "conv17_1"
1112 | top: "conv17_1"
1113 | }
1114 | layer {
1115 | name: "conv17_2"
1116 | type: "Convolution"
1117 | bottom: "conv17_1"
1118 | top: "conv17_2"
1119 | param {
1120 | lr_mult: 1.0
1121 | decay_mult: 1.0
1122 | }
1123 | param {
1124 | lr_mult: 2.0
1125 | decay_mult: 0.0
1126 | }
1127 | convolution_param {
1128 | num_output: 128
1129 | pad: 1
1130 | kernel_size: 3
1131 | stride: 2
1132 | weight_filler {
1133 | type: "msra"
1134 | }
1135 | bias_filler {
1136 | type: "constant"
1137 | value: 0.0
1138 | }
1139 | }
1140 | }
1141 | layer {
1142 | name: "conv17_2/relu"
1143 | type: "ReLU"
1144 | bottom: "conv17_2"
1145 | top: "conv17_2"
1146 | }
1147 | layer {
1148 | name: "conv11_mbox_loc"
1149 | type: "Convolution"
1150 | bottom: "conv11"
1151 | top: "conv11_mbox_loc"
1152 | param {
1153 | lr_mult: 1.0
1154 | decay_mult: 1.0
1155 | }
1156 | param {
1157 | lr_mult: 2.0
1158 | decay_mult: 0.0
1159 | }
1160 | convolution_param {
1161 | num_output: 12
1162 | kernel_size: 1
1163 | weight_filler {
1164 | type: "msra"
1165 | }
1166 | bias_filler {
1167 | type: "constant"
1168 | value: 0.0
1169 | }
1170 | }
1171 | }
1172 | layer {
1173 | name: "conv11_mbox_loc_perm"
1174 | type: "Permute"
1175 | bottom: "conv11_mbox_loc"
1176 | top: "conv11_mbox_loc_perm"
1177 | permute_param {
1178 | order: 0
1179 | order: 2
1180 | order: 3
1181 | order: 1
1182 | }
1183 | }
1184 | layer {
1185 | name: "conv11_mbox_loc_flat"
1186 | type: "Flatten"
1187 | bottom: "conv11_mbox_loc_perm"
1188 | top: "conv11_mbox_loc_flat"
1189 | flatten_param {
1190 | axis: 1
1191 | }
1192 | }
1193 | layer {
1194 | name: "conv11_mbox_conf"
1195 | type: "Convolution"
1196 | bottom: "conv11"
1197 | top: "conv11_mbox_conf"
1198 | param {
1199 | lr_mult: 1.0
1200 | decay_mult: 1.0
1201 | }
1202 | param {
1203 | lr_mult: 2.0
1204 | decay_mult: 0.0
1205 | }
1206 | convolution_param {
1207 | num_output: 63
1208 | kernel_size: 1
1209 | weight_filler {
1210 | type: "msra"
1211 | }
1212 | bias_filler {
1213 | type: "constant"
1214 | value: 0.0
1215 | }
1216 | }
1217 | }
1218 | layer {
1219 | name: "conv11_mbox_conf_perm"
1220 | type: "Permute"
1221 | bottom: "conv11_mbox_conf"
1222 | top: "conv11_mbox_conf_perm"
1223 | permute_param {
1224 | order: 0
1225 | order: 2
1226 | order: 3
1227 | order: 1
1228 | }
1229 | }
1230 | layer {
1231 | name: "conv11_mbox_conf_flat"
1232 | type: "Flatten"
1233 | bottom: "conv11_mbox_conf_perm"
1234 | top: "conv11_mbox_conf_flat"
1235 | flatten_param {
1236 | axis: 1
1237 | }
1238 | }
1239 | layer {
1240 | name: "conv11_mbox_priorbox"
1241 | type: "PriorBox"
1242 | bottom: "conv11"
1243 | bottom: "data"
1244 | top: "conv11_mbox_priorbox"
1245 | prior_box_param {
1246 | min_size: 60.0
1247 | aspect_ratio: 2.0
1248 | flip: true
1249 | clip: false
1250 | variance: 0.1
1251 | variance: 0.1
1252 | variance: 0.2
1253 | variance: 0.2
1254 | offset: 0.5
1255 | }
1256 | }
1257 | layer {
1258 | name: "conv13_mbox_loc"
1259 | type: "Convolution"
1260 | bottom: "conv13"
1261 | top: "conv13_mbox_loc"
1262 | param {
1263 | lr_mult: 1.0
1264 | decay_mult: 1.0
1265 | }
1266 | param {
1267 | lr_mult: 2.0
1268 | decay_mult: 0.0
1269 | }
1270 | convolution_param {
1271 | num_output: 24
1272 | kernel_size: 1
1273 | weight_filler {
1274 | type: "msra"
1275 | }
1276 | bias_filler {
1277 | type: "constant"
1278 | value: 0.0
1279 | }
1280 | }
1281 | }
1282 | layer {
1283 | name: "conv13_mbox_loc_perm"
1284 | type: "Permute"
1285 | bottom: "conv13_mbox_loc"
1286 | top: "conv13_mbox_loc_perm"
1287 | permute_param {
1288 | order: 0
1289 | order: 2
1290 | order: 3
1291 | order: 1
1292 | }
1293 | }
1294 | layer {
1295 | name: "conv13_mbox_loc_flat"
1296 | type: "Flatten"
1297 | bottom: "conv13_mbox_loc_perm"
1298 | top: "conv13_mbox_loc_flat"
1299 | flatten_param {
1300 | axis: 1
1301 | }
1302 | }
1303 | layer {
1304 | name: "conv13_mbox_conf"
1305 | type: "Convolution"
1306 | bottom: "conv13"
1307 | top: "conv13_mbox_conf"
1308 | param {
1309 | lr_mult: 1.0
1310 | decay_mult: 1.0
1311 | }
1312 | param {
1313 | lr_mult: 2.0
1314 | decay_mult: 0.0
1315 | }
1316 | convolution_param {
1317 | num_output: 126
1318 | kernel_size: 1
1319 | weight_filler {
1320 | type: "msra"
1321 | }
1322 | bias_filler {
1323 | type: "constant"
1324 | value: 0.0
1325 | }
1326 | }
1327 | }
1328 | layer {
1329 | name: "conv13_mbox_conf_perm"
1330 | type: "Permute"
1331 | bottom: "conv13_mbox_conf"
1332 | top: "conv13_mbox_conf_perm"
1333 | permute_param {
1334 | order: 0
1335 | order: 2
1336 | order: 3
1337 | order: 1
1338 | }
1339 | }
1340 | layer {
1341 | name: "conv13_mbox_conf_flat"
1342 | type: "Flatten"
1343 | bottom: "conv13_mbox_conf_perm"
1344 | top: "conv13_mbox_conf_flat"
1345 | flatten_param {
1346 | axis: 1
1347 | }
1348 | }
1349 | layer {
1350 | name: "conv13_mbox_priorbox"
1351 | type: "PriorBox"
1352 | bottom: "conv13"
1353 | bottom: "data"
1354 | top: "conv13_mbox_priorbox"
1355 | prior_box_param {
1356 | min_size: 105.0
1357 | max_size: 150.0
1358 | aspect_ratio: 2.0
1359 | aspect_ratio: 3.0
1360 | flip: true
1361 | clip: false
1362 | variance: 0.1
1363 | variance: 0.1
1364 | variance: 0.2
1365 | variance: 0.2
1366 | offset: 0.5
1367 | }
1368 | }
1369 | layer {
1370 | name: "conv14_2_mbox_loc"
1371 | type: "Convolution"
1372 | bottom: "conv14_2"
1373 | top: "conv14_2_mbox_loc"
1374 | param {
1375 | lr_mult: 1.0
1376 | decay_mult: 1.0
1377 | }
1378 | param {
1379 | lr_mult: 2.0
1380 | decay_mult: 0.0
1381 | }
1382 | convolution_param {
1383 | num_output: 24
1384 | kernel_size: 1
1385 | weight_filler {
1386 | type: "msra"
1387 | }
1388 | bias_filler {
1389 | type: "constant"
1390 | value: 0.0
1391 | }
1392 | }
1393 | }
1394 | layer {
1395 | name: "conv14_2_mbox_loc_perm"
1396 | type: "Permute"
1397 | bottom: "conv14_2_mbox_loc"
1398 | top: "conv14_2_mbox_loc_perm"
1399 | permute_param {
1400 | order: 0
1401 | order: 2
1402 | order: 3
1403 | order: 1
1404 | }
1405 | }
1406 | layer {
1407 | name: "conv14_2_mbox_loc_flat"
1408 | type: "Flatten"
1409 | bottom: "conv14_2_mbox_loc_perm"
1410 | top: "conv14_2_mbox_loc_flat"
1411 | flatten_param {
1412 | axis: 1
1413 | }
1414 | }
1415 | layer {
1416 | name: "conv14_2_mbox_conf"
1417 | type: "Convolution"
1418 | bottom: "conv14_2"
1419 | top: "conv14_2_mbox_conf"
1420 | param {
1421 | lr_mult: 1.0
1422 | decay_mult: 1.0
1423 | }
1424 | param {
1425 | lr_mult: 2.0
1426 | decay_mult: 0.0
1427 | }
1428 | convolution_param {
1429 | num_output: 126
1430 | kernel_size: 1
1431 | weight_filler {
1432 | type: "msra"
1433 | }
1434 | bias_filler {
1435 | type: "constant"
1436 | value: 0.0
1437 | }
1438 | }
1439 | }
1440 | layer {
1441 | name: "conv14_2_mbox_conf_perm"
1442 | type: "Permute"
1443 | bottom: "conv14_2_mbox_conf"
1444 | top: "conv14_2_mbox_conf_perm"
1445 | permute_param {
1446 | order: 0
1447 | order: 2
1448 | order: 3
1449 | order: 1
1450 | }
1451 | }
1452 | layer {
1453 | name: "conv14_2_mbox_conf_flat"
1454 | type: "Flatten"
1455 | bottom: "conv14_2_mbox_conf_perm"
1456 | top: "conv14_2_mbox_conf_flat"
1457 | flatten_param {
1458 | axis: 1
1459 | }
1460 | }
1461 | layer {
1462 | name: "conv14_2_mbox_priorbox"
1463 | type: "PriorBox"
1464 | bottom: "conv14_2"
1465 | bottom: "data"
1466 | top: "conv14_2_mbox_priorbox"
1467 | prior_box_param {
1468 | min_size: 150.0
1469 | max_size: 195.0
1470 | aspect_ratio: 2.0
1471 | aspect_ratio: 3.0
1472 | flip: true
1473 | clip: false
1474 | variance: 0.1
1475 | variance: 0.1
1476 | variance: 0.2
1477 | variance: 0.2
1478 | offset: 0.5
1479 | }
1480 | }
1481 | layer {
1482 | name: "conv15_2_mbox_loc"
1483 | type: "Convolution"
1484 | bottom: "conv15_2"
1485 | top: "conv15_2_mbox_loc"
1486 | param {
1487 | lr_mult: 1.0
1488 | decay_mult: 1.0
1489 | }
1490 | param {
1491 | lr_mult: 2.0
1492 | decay_mult: 0.0
1493 | }
1494 | convolution_param {
1495 | num_output: 24
1496 | kernel_size: 1
1497 | weight_filler {
1498 | type: "msra"
1499 | }
1500 | bias_filler {
1501 | type: "constant"
1502 | value: 0.0
1503 | }
1504 | }
1505 | }
1506 | layer {
1507 | name: "conv15_2_mbox_loc_perm"
1508 | type: "Permute"
1509 | bottom: "conv15_2_mbox_loc"
1510 | top: "conv15_2_mbox_loc_perm"
1511 | permute_param {
1512 | order: 0
1513 | order: 2
1514 | order: 3
1515 | order: 1
1516 | }
1517 | }
1518 | layer {
1519 | name: "conv15_2_mbox_loc_flat"
1520 | type: "Flatten"
1521 | bottom: "conv15_2_mbox_loc_perm"
1522 | top: "conv15_2_mbox_loc_flat"
1523 | flatten_param {
1524 | axis: 1
1525 | }
1526 | }
1527 | layer {
1528 | name: "conv15_2_mbox_conf"
1529 | type: "Convolution"
1530 | bottom: "conv15_2"
1531 | top: "conv15_2_mbox_conf"
1532 | param {
1533 | lr_mult: 1.0
1534 | decay_mult: 1.0
1535 | }
1536 | param {
1537 | lr_mult: 2.0
1538 | decay_mult: 0.0
1539 | }
1540 | convolution_param {
1541 | num_output: 126
1542 | kernel_size: 1
1543 | weight_filler {
1544 | type: "msra"
1545 | }
1546 | bias_filler {
1547 | type: "constant"
1548 | value: 0.0
1549 | }
1550 | }
1551 | }
1552 | layer {
1553 | name: "conv15_2_mbox_conf_perm"
1554 | type: "Permute"
1555 | bottom: "conv15_2_mbox_conf"
1556 | top: "conv15_2_mbox_conf_perm"
1557 | permute_param {
1558 | order: 0
1559 | order: 2
1560 | order: 3
1561 | order: 1
1562 | }
1563 | }
1564 | layer {
1565 | name: "conv15_2_mbox_conf_flat"
1566 | type: "Flatten"
1567 | bottom: "conv15_2_mbox_conf_perm"
1568 | top: "conv15_2_mbox_conf_flat"
1569 | flatten_param {
1570 | axis: 1
1571 | }
1572 | }
1573 | layer {
1574 | name: "conv15_2_mbox_priorbox"
1575 | type: "PriorBox"
1576 | bottom: "conv15_2"
1577 | bottom: "data"
1578 | top: "conv15_2_mbox_priorbox"
1579 | prior_box_param {
1580 | min_size: 195.0
1581 | max_size: 240.0
1582 | aspect_ratio: 2.0
1583 | aspect_ratio: 3.0
1584 | flip: true
1585 | clip: false
1586 | variance: 0.1
1587 | variance: 0.1
1588 | variance: 0.2
1589 | variance: 0.2
1590 | offset: 0.5
1591 | }
1592 | }
1593 | layer {
1594 | name: "conv16_2_mbox_loc"
1595 | type: "Convolution"
1596 | bottom: "conv16_2"
1597 | top: "conv16_2_mbox_loc"
1598 | param {
1599 | lr_mult: 1.0
1600 | decay_mult: 1.0
1601 | }
1602 | param {
1603 | lr_mult: 2.0
1604 | decay_mult: 0.0
1605 | }
1606 | convolution_param {
1607 | num_output: 24
1608 | kernel_size: 1
1609 | weight_filler {
1610 | type: "msra"
1611 | }
1612 | bias_filler {
1613 | type: "constant"
1614 | value: 0.0
1615 | }
1616 | }
1617 | }
1618 | layer {
1619 | name: "conv16_2_mbox_loc_perm"
1620 | type: "Permute"
1621 | bottom: "conv16_2_mbox_loc"
1622 | top: "conv16_2_mbox_loc_perm"
1623 | permute_param {
1624 | order: 0
1625 | order: 2
1626 | order: 3
1627 | order: 1
1628 | }
1629 | }
1630 | layer {
1631 | name: "conv16_2_mbox_loc_flat"
1632 | type: "Flatten"
1633 | bottom: "conv16_2_mbox_loc_perm"
1634 | top: "conv16_2_mbox_loc_flat"
1635 | flatten_param {
1636 | axis: 1
1637 | }
1638 | }
1639 | layer {
1640 | name: "conv16_2_mbox_conf"
1641 | type: "Convolution"
1642 | bottom: "conv16_2"
1643 | top: "conv16_2_mbox_conf"
1644 | param {
1645 | lr_mult: 1.0
1646 | decay_mult: 1.0
1647 | }
1648 | param {
1649 | lr_mult: 2.0
1650 | decay_mult: 0.0
1651 | }
1652 | convolution_param {
1653 | num_output: 126
1654 | kernel_size: 1
1655 | weight_filler {
1656 | type: "msra"
1657 | }
1658 | bias_filler {
1659 | type: "constant"
1660 | value: 0.0
1661 | }
1662 | }
1663 | }
1664 | layer {
1665 | name: "conv16_2_mbox_conf_perm"
1666 | type: "Permute"
1667 | bottom: "conv16_2_mbox_conf"
1668 | top: "conv16_2_mbox_conf_perm"
1669 | permute_param {
1670 | order: 0
1671 | order: 2
1672 | order: 3
1673 | order: 1
1674 | }
1675 | }
1676 | layer {
1677 | name: "conv16_2_mbox_conf_flat"
1678 | type: "Flatten"
1679 | bottom: "conv16_2_mbox_conf_perm"
1680 | top: "conv16_2_mbox_conf_flat"
1681 | flatten_param {
1682 | axis: 1
1683 | }
1684 | }
1685 | layer {
1686 | name: "conv16_2_mbox_priorbox"
1687 | type: "PriorBox"
1688 | bottom: "conv16_2"
1689 | bottom: "data"
1690 | top: "conv16_2_mbox_priorbox"
1691 | prior_box_param {
1692 | min_size: 240.0
1693 | max_size: 285.0
1694 | aspect_ratio: 2.0
1695 | aspect_ratio: 3.0
1696 | flip: true
1697 | clip: false
1698 | variance: 0.1
1699 | variance: 0.1
1700 | variance: 0.2
1701 | variance: 0.2
1702 | offset: 0.5
1703 | }
1704 | }
1705 | layer {
1706 | name: "conv17_2_mbox_loc"
1707 | type: "Convolution"
1708 | bottom: "conv17_2"
1709 | top: "conv17_2_mbox_loc"
1710 | param {
1711 | lr_mult: 1.0
1712 | decay_mult: 1.0
1713 | }
1714 | param {
1715 | lr_mult: 2.0
1716 | decay_mult: 0.0
1717 | }
1718 | convolution_param {
1719 | num_output: 24
1720 | kernel_size: 1
1721 | weight_filler {
1722 | type: "msra"
1723 | }
1724 | bias_filler {
1725 | type: "constant"
1726 | value: 0.0
1727 | }
1728 | }
1729 | }
1730 | layer {
1731 | name: "conv17_2_mbox_loc_perm"
1732 | type: "Permute"
1733 | bottom: "conv17_2_mbox_loc"
1734 | top: "conv17_2_mbox_loc_perm"
1735 | permute_param {
1736 | order: 0
1737 | order: 2
1738 | order: 3
1739 | order: 1
1740 | }
1741 | }
1742 | layer {
1743 | name: "conv17_2_mbox_loc_flat"
1744 | type: "Flatten"
1745 | bottom: "conv17_2_mbox_loc_perm"
1746 | top: "conv17_2_mbox_loc_flat"
1747 | flatten_param {
1748 | axis: 1
1749 | }
1750 | }
1751 | layer {
1752 | name: "conv17_2_mbox_conf"
1753 | type: "Convolution"
1754 | bottom: "conv17_2"
1755 | top: "conv17_2_mbox_conf"
1756 | param {
1757 | lr_mult: 1.0
1758 | decay_mult: 1.0
1759 | }
1760 | param {
1761 | lr_mult: 2.0
1762 | decay_mult: 0.0
1763 | }
1764 | convolution_param {
1765 | num_output: 126
1766 | kernel_size: 1
1767 | weight_filler {
1768 | type: "msra"
1769 | }
1770 | bias_filler {
1771 | type: "constant"
1772 | value: 0.0
1773 | }
1774 | }
1775 | }
1776 | layer {
1777 | name: "conv17_2_mbox_conf_perm"
1778 | type: "Permute"
1779 | bottom: "conv17_2_mbox_conf"
1780 | top: "conv17_2_mbox_conf_perm"
1781 | permute_param {
1782 | order: 0
1783 | order: 2
1784 | order: 3
1785 | order: 1
1786 | }
1787 | }
1788 | layer {
1789 | name: "conv17_2_mbox_conf_flat"
1790 | type: "Flatten"
1791 | bottom: "conv17_2_mbox_conf_perm"
1792 | top: "conv17_2_mbox_conf_flat"
1793 | flatten_param {
1794 | axis: 1
1795 | }
1796 | }
1797 | layer {
1798 | name: "conv17_2_mbox_priorbox"
1799 | type: "PriorBox"
1800 | bottom: "conv17_2"
1801 | bottom: "data"
1802 | top: "conv17_2_mbox_priorbox"
1803 | prior_box_param {
1804 | min_size: 285.0
1805 | max_size: 300.0
1806 | aspect_ratio: 2.0
1807 | aspect_ratio: 3.0
1808 | flip: true
1809 | clip: false
1810 | variance: 0.1
1811 | variance: 0.1
1812 | variance: 0.2
1813 | variance: 0.2
1814 | offset: 0.5
1815 | }
1816 | }
1817 | layer {
1818 | name: "mbox_loc"
1819 | type: "Concat"
1820 | bottom: "conv11_mbox_loc_flat"
1821 | bottom: "conv13_mbox_loc_flat"
1822 | bottom: "conv14_2_mbox_loc_flat"
1823 | bottom: "conv15_2_mbox_loc_flat"
1824 | bottom: "conv16_2_mbox_loc_flat"
1825 | bottom: "conv17_2_mbox_loc_flat"
1826 | top: "mbox_loc"
1827 | concat_param {
1828 | axis: 1
1829 | }
1830 | }
1831 | layer {
1832 | name: "mbox_conf"
1833 | type: "Concat"
1834 | bottom: "conv11_mbox_conf_flat"
1835 | bottom: "conv13_mbox_conf_flat"
1836 | bottom: "conv14_2_mbox_conf_flat"
1837 | bottom: "conv15_2_mbox_conf_flat"
1838 | bottom: "conv16_2_mbox_conf_flat"
1839 | bottom: "conv17_2_mbox_conf_flat"
1840 | top: "mbox_conf"
1841 | concat_param {
1842 | axis: 1
1843 | }
1844 | }
1845 | layer {
1846 | name: "mbox_priorbox"
1847 | type: "Concat"
1848 | bottom: "conv11_mbox_priorbox"
1849 | bottom: "conv13_mbox_priorbox"
1850 | bottom: "conv14_2_mbox_priorbox"
1851 | bottom: "conv15_2_mbox_priorbox"
1852 | bottom: "conv16_2_mbox_priorbox"
1853 | bottom: "conv17_2_mbox_priorbox"
1854 | top: "mbox_priorbox"
1855 | concat_param {
1856 | axis: 2
1857 | }
1858 | }
1859 | layer {
1860 | name: "mbox_conf_reshape"
1861 | type: "Reshape"
1862 | bottom: "mbox_conf"
1863 | top: "mbox_conf_reshape"
1864 | reshape_param {
1865 | shape {
1866 | dim: 0
1867 | dim: -1
1868 | dim: 21
1869 | }
1870 | }
1871 | }
1872 | layer {
1873 | name: "mbox_conf_softmax"
1874 | type: "Softmax"
1875 | bottom: "mbox_conf_reshape"
1876 | top: "mbox_conf_softmax"
1877 | softmax_param {
1878 | axis: 2
1879 | }
1880 | }
1881 | layer {
1882 | name: "mbox_conf_flatten"
1883 | type: "Flatten"
1884 | bottom: "mbox_conf_softmax"
1885 | top: "mbox_conf_flatten"
1886 | flatten_param {
1887 | axis: 1
1888 | }
1889 | }
1890 | layer {
1891 | name: "detection_out"
1892 | type: "DetectionOutput"
1893 | bottom: "mbox_loc"
1894 | bottom: "mbox_conf_flatten"
1895 | bottom: "mbox_priorbox"
1896 | top: "detection_out"
1897 | include {
1898 | phase: TEST
1899 | }
1900 | detection_output_param {
1901 | num_classes: 21
1902 | share_location: true
1903 | background_label_id: 0
1904 | nms_param {
1905 | nms_threshold: 0.45
1906 | top_k: 100
1907 | }
1908 | code_type: CENTER_SIZE
1909 | keep_top_k: 100
1910 | confidence_threshold: 0.25
1911 | }
1912 | }
1913 |
--------------------------------------------------------------------------------
/models/haarcascade_cars3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |