Which of these functions consumes the processor 100%, which one and how can this be fixed? I’m new to this, please help
def load_video(self):
filename, _ = QFileDialog.getOpenFileName(self, "Выбрать видеофайл")
if filename != "":
filename_label = os.path.basename(filename)
self.video_name_label.setText(filename_label)
self.capture = cv2.VideoCapture(filename)
# Изменить размер кадров на 640x480
self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# Добавляем переменные videoWidth и videoHeight
self.videoWidth = self.capture.get(cv2.CAP_PROP_FRAME_WIDTH)
self.videoHeight = self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
self.length = int(self.capture.get(cv2.CAP_PROP_FRAME_COUNT))
self.fps = self.capture.get(cv2.CAP_PROP_FPS)
self.total_seconds = self.length / self.fps
self.set_slider_position(0)
self.slider.setValue(0)
self.slider.setMaximum(self.length)
self.show_video_btns()
self.timer.timeout.connect(self.update_frame)
self.timer.start(int(1000 / round(self.fps)))
self.backSub = cv2.createBackgroundSubtractorMOG2()
self.zoom_level = 0
self.zoom_center = (self.videoWidth // 2, self.videoHeight // 2)
self.frames_without_dron = 0
def plot_img(self, frame, result):
color = (64, 64, 255)
txt_color = (255, 255, 255)
lw = max(round(sum(frame.shape) / 2 * 0.003), 2)
sf = lw / 4
tf = max(lw - 1, 1)
for box in result.boxes:
if int(box.cls[0]) != 1 or box.conf[0] < THRESHOLD:
continue
label = []
p1 = (int(box.xyxy[0][0]), int(box.xyxy[0][1]))
p2 = (int(box.xyxy[0][2]), int(box.xyxy[0][3]))
if self.checkNumeration.isChecked() and box.id:
label.append(str(int(box.id[0])))
if self.checkConfidience.isChecked():
conf = int(box.conf[0] * 100)
label.append(f"{conf}%")
if self.checkShowBoxes.isChecked():
cv2.rectangle(frame, p1, p2, color, thickness=2, lineType=cv2.LINE_AA)
if label:
label.insert(0, "Дрон")
label_ = " ".join(label)
text_size = cv2.getTextSize(label_, 0, fontScale=sf, thickness=tf)[0]
text_origin = p1[0], p1[1] - 4 - text_size[1] if p1[1] - text_size[1] >= 3 else p1[1] + text_size[1] + 4
cv2.rectangle(frame, p1, (p1[0] + text_size[0], text_origin[1] + text_size[1]), color, -1, cv2.LINE_AA)
cv2.putText(
frame,
label_,
text_origin,
cv2.FONT_HERSHEY_COMPLEX,
sf,
txt_color,
thickness=tf,
lineType=cv2.LINE_AA,
)
def motion_detect(self):
frame_out = self.frame.copy()
fg_mask = self.backSub.apply(self.frame)
_, mask_thresh = cv2.threshold(fg_mask, 120, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
mask_eroded = cv2.morphologyEx(mask_thresh, cv2.MORPH_OPEN, kernel)
contours, _ = cv2.findContours(
mask_eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
min_contour_area = 150
large_contours = []
for cnt in contours:
if cv2.contourArea(cnt) > min_contour_area:
large_contours.append(cnt)
if large_contours:
x_values = []
y_values = []
for cnt in large_contours:
for pt in cnt:
x_values.append(pt[0][0])
y_values.append(pt[0][1])
min_x = min(x_values)
min_y = min(y_values)
max_x = max(x_values)
max_y = max(y_values)
center_x = (min_x + max_x) / (2 * self.frame.shape[1])
center_y = (min_y + max_y) / (2 * self.frame.shape[0])
width = (max_x - min_x) / self.frame.shape[1]
height = (max_y - min_y) / self.frame.shape[0]
square = width * height
if square < 0.2:
self.motion_box = (center_x, center_y, width, height)
self.frame = cv2.rectangle(frame_out, (min_x, min_y), (max_x, max_y), (0, 0, 200), 3)
elif self.change_zoom_delay > 5:
self.motion_box = None
self.change_zoom_delay = 0
elif self.change_zoom_delay > 5:
self.motion_box = None
self.change_zoom_delay = 0
def zoom_frame(self):
if not self.zoom_level or not self.motion_box:
return
height, width = self.frame.shape[:2]
zoomed_size_w = max(1, width // (self.zoom_level + 1))
zoomed_size_h = max(1, height // (self.zoom_level + 1))
center_x, center_y, _, _ = self.motion_box
self.zoom_top_left_x = max(0, center_x - zoomed_size_w // 2)
self.zoom_top_left_y = max(0, center_y - zoomed_size_h // 2)
zoomed_frame = self.frame[
self.zoom_top_left_y: min(self.zoom_top_left_y + zoomed_size_h, height),
self.zoom_top_left_x: min(self.zoom_top_left_x + zoomed_size_w, width),
]
self.frame = cv2.resize(zoomed_frame, (width, height))
def get_center_object(self, boxes):
box = boxes[0]
x1, y1, x2, y2 = box.xyxy[0]
width = x2 - x1
height = y2 - y1
center_x = (x1 + x2) / 2
center_y = (y1 + y2) / 2
center_x /= self.frame.shape[1]
center_y /= self.frame.shape[0]
width /= self.frame.shape[1]
height /= self.frame.shape[0]
if self.zoom_level > 0:
center_x += self.zoom_top_left_x / 2
center_y += self.zoom_top_left_y / 2
if self.motion_box is not None:
center_x = 0.9 * self.motion_box[0] + 0.1 * center_x
center_y = 0.9 * self.motion_box[1] + 0.1 * center_y
if self.change_zoom_delay > 5:
self.motion_box = (center_x, center_y, width, height)
self.change_zoom_delay = 0
def track(self, imgsz=640, verbose=False, tracker="sort"):
with self.tracking_lock:
self.change_zoom_delay += 1
self.zoom_frame()
results = self.model(self.frame, imgsz=imgsz, verbose=False)
dron_boxes = [
b
for b in results[0].boxes
if int(b.cls[0]) == DRON_CLASS and float(b.conf[0]) > THRESHOLD
]
if dron_boxes:
self.motion_detected_button_show()
self.get_center_object(dron_boxes)
if self.notification_is_due:
asyncio.run(self.notification())
if self.checkSaveDataset.isChecked():
self.save_dataset_frame(self.frame, results)
# Рисуем рамки вокруг обнаруженных дронов
for box in dron_boxes:
p1, p2 = (int(box.xyxy[0][0]), int(box.xyxy[0][1])), (
int(box.xyxy[0][2]),
int(box.xyxy[0][3]),
)
cv2.rectangle(self.frame, p1, p2, (0, 255, 0), 2)
else:
self.motion_detected_button_hide()
self.motion_detect()
if self.motion_box:
if self.zoom_level < 1:
self.changeZoomLevel(1)
self.plot_img(self.frame, results[0])
return self.frame
I tried changing the video resolution – it didn’t help. I really don’t understand why there is such a waste of resources.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
New contributor
asd is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.