如何在视频流中每3秒获取特定帧并优化基于KNN的图像分类线程代码?
Solution: Process Video Frame Every 3 Seconds with KNN
Hey there! Let's fix your code so it only runs the KNN classification once every 3 seconds instead of on every frame. Here's what we need to adjust:
Key Issues in Your Current Code
- You're setting the frame width twice (instead of width and height) in the
ThreadCaptureconstructor. - The main loop calls
run_knn()every time a frame is available, which is way too frequent.
Modified Code with Explanations
First, let's correct the frame dimensions and add the timing logic:
import cv2 import threading import time from PIL import Image class ThreadCapture(): def __init__(self, knn): self.frame = [] self.status = False self.isStop = False self.knn = knn self.cap = cv2.VideoCapture(0) # Fix: Set width AND height correctly self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # Changed from WIDTH to HEIGHT def start(self): threading.Thread(target=self.current_frame, daemon=True, args=()).start() def stop(self): self.isStop = True def get_frame(self): return self.status, self.frame def current_frame(self): while(not self.isStop): self.status, self.frame = self.cap.read() # Assuming crop_frame() is defined elsewhere (you might need to implement this!) # self.crop_frame() self.cap.release() def run_knn(self): img_resize = cv2.resize(self.frame, (224, 224)) img = cv2.cvtColor(img_resize, cv2.COLOR_BGR2RGB) img_pil = Image.fromarray(img) return self.knn.classify(img_pil) def main(arg): # Initialize your KNN model (EagleEyes) here EagleEyes = ... # Replace with your actual model initialization stream = ThreadCapture(EagleEyes) stream.start() time.sleep(1) # Give the thread time to start capturing frames last_knn_run = time.time() # Track when we last ran KNN current_classification = "" # Store the latest result to display while(True): status, frame = stream.get_frame() if status: current_time = time.time() # Check if 3 seconds have passed since last KNN run if current_time - last_knn_run >= 3: # Run KNN on the latest frame info, res = stream.run_knn() current_classification = info print(f"Classification result: {info}") last_knn_run = current_time # Update the last run time # Always display the latest classification result cv2.putText(frame, current_classification, (10,40), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 1, cv2.LINE_AA) cv2.imshow('abc', frame) # Exit on 'q' press if cv2.waitKey(1) == ord('q'): break stream.stop() cv2.destroyAllWindows() # Run the main function (adjust args as needed) if __name__ == "__main__": main(None)
What Changed?
- Fixed Frame Dimensions: We corrected the second
CAP_PROP_FRAME_WIDTHtoCAP_PROP_FRAME_HEIGHTso your video feed uses the correct 640x480 resolution. - Timing Logic:
last_knn_runtracks the timestamp of the last KNN execution.- In each loop iteration, we check if 3 seconds have passed since the last run. If yes, we run KNN and update the result.
current_classificationstores the latest result, so we keep displaying it even when we're not running KNN.
- Cleaner Output: Added a print statement with context to make debugging easier.
Notes for You
- Make sure you've imported all required modules (
cv2,threading,time,PIL.Image). - If your
crop_frame()method isn't implemented yet, you'll need to add that to process the frame before classification. - The
time.sleep(1)at the start gives the capture thread time to initialize, which helps avoid empty frames at the beginning.
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

