@camera.ui/camera-ui-opencv 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/camera_detector.py +109 -105
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "OpenCV",
3
3
  "name": "@camera.ui/camera-ui-opencv",
4
- "version": "0.0.7",
4
+ "version": "0.0.9",
5
5
  "description": "camera.ui opencv plugin",
6
6
  "author": "seydx (https://github.com/seydx/camera.ui)",
7
7
  "main": "./src/main.py",
@@ -39,7 +39,7 @@ class CameraDetector:
39
39
 
40
40
  self.started = False
41
41
  self.closed = False
42
- self.frame_generation_task = None
42
+ self.frame_generation_task: Optional[asyncio.Task[Any]] = None
43
43
  self.executor = None
44
44
 
45
45
  self.camera_storage: CameraStorage[CameraStorageValues] = self.__create_camera_storage()
@@ -59,6 +59,7 @@ class CameraDetector:
59
59
  self.frame_generation_task = asyncio.create_task(
60
60
  self.__detect(), name=f"MotionDetection-{self.camera.name}"
61
61
  )
62
+
62
63
  background_tasks.add(self.frame_generation_task)
63
64
  self.frame_generation_task.add_done_callback(
64
65
  lambda _: background_tasks.remove(self.frame_generation_task)
@@ -90,110 +91,113 @@ class CameraDetector:
90
91
  self.start()
91
92
 
92
93
  async def __detect(self) -> None:
93
- try:
94
- first_frame = None
95
- last_frame_time = 0
96
- backSub: Optional[cv2.BackgroundSubtractorMOG2] = None
97
-
98
- async for frame in self.camera.get_frames():
99
- if self.closed:
100
- break
101
-
102
- frame_image = await frame.to_image({"format": {"to": "gray"}})
103
- image_array = np.array(frame_image["image"])
104
-
105
- now = time.time() * 1000
106
-
107
- detector_model = self.__detector_model()
108
-
109
- if detector_model == "Frame Difference":
110
- area = self.camera_storage.values["frame_difference"]["area"]
111
- reference_frame_frequency = self.camera_storage.values["frame_difference"][
112
- "reference_frame_frequency"
113
- ]
114
-
115
- if first_frame is None or (
116
- reference_frame_frequency
117
- and now - last_frame_time > (reference_frame_frequency * 1000)
118
- ):
119
- first_frame = image_array
120
- last_frame_time = now
121
- continue
122
-
123
- dets = await asyncio.get_event_loop().run_in_executor(
124
- self.executor,
125
- get_detections_fd,
126
- first_frame,
127
- image_array,
128
- area,
129
- )
130
-
131
- elif detector_model == "Background Substraction":
132
- if backSub is None:
133
- backSub = cv2.createBackgroundSubtractorMOG2(varThreshold=18, detectShadows=False)
134
-
135
- threshold = self.camera_storage.values["background_substraction"]["threshold"]
136
- area = self.camera_storage.values["background_substraction"]["area"]
137
-
138
- dets = await asyncio.get_event_loop().run_in_executor(
139
- self.executor,
140
- get_detections_bs,
141
- image_array,
142
- backSub,
143
- threshold,
144
- area,
145
- )
146
-
147
- else: # default
148
- blur = self.camera_storage.values["default"]["blur"]
149
- threshold = self.camera_storage.values["default"]["threshold"]
150
- area = self.camera_storage.values["default"]["area"]
151
- reference_frame_frequency = self.camera_storage.values["default"][
152
- "reference_frame_frequency"
153
- ]
154
-
155
- image_array = cv2.stackBlur(image_array, (blur, blur))
156
-
157
- if first_frame is None or (
158
- reference_frame_frequency
159
- and now - last_frame_time > (reference_frame_frequency * 1000)
160
- ):
161
- first_frame = image_array
162
- last_frame_time = now
163
- continue
164
-
165
- dets = await asyncio.get_event_loop().run_in_executor(
166
- self.executor,
167
- get_detections,
168
- first_frame,
169
- image_array,
170
- threshold,
171
- area,
172
- )
173
-
174
- detections: list[Detection] = []
175
-
176
- for det in dets:
177
- (x1, y1, x2, y2) = det
178
-
179
- detection: Detection = {
180
- "label": "motion",
181
- "confidence": 1,
182
- "boundingBox": (x1, y1, x2, y2),
183
- "inputWidth": frame_image["info"]["width"],
184
- "inputHeight": frame_image["info"]["height"],
185
- "origWidth": frame.metadata["origWidth"],
186
- "origHeight": frame.metadata["origHeight"],
187
- }
188
-
189
- detections.append(detection)
190
-
191
- await self.camera.update_state("motion", {"detections": detections}, frame)
192
-
193
- except asyncio.CancelledError:
194
- pass
195
- except Exception as error:
196
- self.logger.error(self.camera.name, "Error generating frames", error)
94
+ while not self.closed:
95
+ try:
96
+ first_frame = None
97
+ last_frame_time = 0
98
+ backSub: Optional[cv2.BackgroundSubtractorMOG2] = None
99
+
100
+ async for frame in self.camera.get_frames():
101
+ if self.closed:
102
+ break
103
+
104
+ frame_image = await frame.to_image({"format": {"to": "gray"}})
105
+ image_array = np.array(frame_image["image"])
106
+
107
+ now = time.time() * 1000
108
+
109
+ detector_model = self.__detector_model()
110
+
111
+ if detector_model == "Frame Difference":
112
+ area = self.camera_storage.values["frame_difference"]["area"]
113
+ reference_frame_frequency = self.camera_storage.values["frame_difference"][
114
+ "reference_frame_frequency"
115
+ ]
116
+
117
+ if first_frame is None or (
118
+ reference_frame_frequency
119
+ and now - last_frame_time > (reference_frame_frequency * 1000)
120
+ ):
121
+ first_frame = image_array
122
+ last_frame_time = now
123
+ continue
124
+
125
+ dets = await asyncio.get_event_loop().run_in_executor(
126
+ self.executor,
127
+ get_detections_fd,
128
+ first_frame,
129
+ image_array,
130
+ area,
131
+ )
132
+
133
+ elif detector_model == "Background Substraction":
134
+ if backSub is None:
135
+ backSub = cv2.createBackgroundSubtractorMOG2(varThreshold=18, detectShadows=False)
136
+
137
+ threshold = self.camera_storage.values["background_substraction"]["threshold"]
138
+ area = self.camera_storage.values["background_substraction"]["area"]
139
+
140
+ dets = await asyncio.get_event_loop().run_in_executor(
141
+ self.executor,
142
+ get_detections_bs,
143
+ image_array,
144
+ backSub,
145
+ threshold,
146
+ area,
147
+ )
148
+
149
+ else: # default
150
+ blur = self.camera_storage.values["default"]["blur"]
151
+ threshold = self.camera_storage.values["default"]["threshold"]
152
+ area = self.camera_storage.values["default"]["area"]
153
+ reference_frame_frequency = self.camera_storage.values["default"][
154
+ "reference_frame_frequency"
155
+ ]
156
+
157
+ image_array = cv2.stackBlur(image_array, (blur, blur))
158
+
159
+ if first_frame is None or (
160
+ reference_frame_frequency
161
+ and now - last_frame_time > (reference_frame_frequency * 1000)
162
+ ):
163
+ first_frame = image_array
164
+ last_frame_time = now
165
+ continue
166
+
167
+ dets = await asyncio.get_event_loop().run_in_executor(
168
+ self.executor,
169
+ get_detections,
170
+ first_frame,
171
+ image_array,
172
+ threshold,
173
+ area,
174
+ )
175
+
176
+ detections: list[Detection] = []
177
+
178
+ for det in dets:
179
+ (x1, y1, x2, y2) = det
180
+
181
+ detection: Detection = {
182
+ "label": "motion",
183
+ "confidence": 1,
184
+ "boundingBox": (x1, y1, x2, y2),
185
+ "inputWidth": frame_image["info"]["width"],
186
+ "inputHeight": frame_image["info"]["height"],
187
+ "origWidth": frame.metadata["origWidth"],
188
+ "origHeight": frame.metadata["origHeight"],
189
+ }
190
+
191
+ detections.append(detection)
192
+
193
+ await self.camera.update_state("motion", {"detections": detections}, frame)
194
+ except asyncio.CancelledError:
195
+ pass
196
+ except Exception as error:
197
+ self.logger.error(self.camera.name, "Error generating frames", error)
198
+ self.logger.log(self.camera.name, "Restarting motion detection in 5 seconds...")
199
+ await asyncio.sleep(5)
200
+ continue
197
201
 
198
202
  def __detector_model(self) -> Literal["Frame Difference", "Background Substraction", "Default"]:
199
203
  return self.camera_storage.values["motion_detector"]