-
Notifications
You must be signed in to change notification settings - Fork 3
How it works
protruser edited this page Dec 16, 2024
·
2 revisions
This document provides an overview of how the two Python scripts work together for edge detection and template matching using OpenCV.
The project combines edge detection techniques and template matching to identify specific patterns (e.g., a currency note) in a video stream. It uses:
- Edge Detection: Canny, Sobel, or Laplacian methods for preprocessing.
- Template Matching: ORB (Oriented FAST and Rotated BRIEF) to find and match key points between a template image and a live video stream.
The EdgeDetection class provides an interface to switch between different edge detection algorithms.
class EdgeDetection:
def __init__(self, method='canny'):
self.method = method- Default edge detection method is
canny.
def set_method(self, method):
self.method = method- Updates the current edge detection method dynamically during runtime.
- Canny
def canny_edge_detection(self, gray_frame):
edges = cv2.Canny(gray_frame, 50, 150)
return edges- Sobel
def sobel_edge_detection(self, gray_frame):
grad_x = cv2.Sobel(gray_frame, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(gray_frame, cv2.CV_64F, 0, 1, ksize=3)
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
edges = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
return edges- Laplacian
def laplacian_edge_detection(self, gray_frame):
edges = cv2.Laplacian(gray_frame, cv2.CV_64F)
edges = cv2.convertScaleAbs(edges)
return edges- Read frames from the webcam.
- Convert the frame to grayscale.
- Apply edge detection using the selected method.
edges = edge_detector.detect_edges(gray)
cv2.imshow('Edges', edges)Users can dynamically switch between edge detection methods with keyboard inputs:
- Press
c: Switch to Canny. - Press
s: Switch to Sobel. - Press
l: Switch to Laplacian.
The TemplateMatcher class detects specific objects in a live video stream by matching keypoints in a template image and the video stream using ORB.
class TemplateMatcher:
def __init__(self, template_path, edge_method='canny', popUpActive=False, camera_index=0):- Loads a grayscale template image.
- Initializes the edge detection method and ORB parameters.
- Configures the camera source.
def match_found(self):
app = QApplication(sys.argv)
self.popup = SimplePopup("Match to Currency was found.")
self.popup.show()- Displays a popup notification when a match is found (requires PyQt6).
def process_frame(self, frame, orb):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = self.edge_detection.detect_edges(gray)- Applies the edge detection method to the video stream before keypoint matching.
- Highlights detected edges in red.
matches = self.bf.knnMatch(self.des_template, des_frame, k=2)
good_matches = [m for m, n in matches if len(matches) > 1 and m.distance < 0.75 * n.distance]- Finds matches between template and frame descriptors using a brute-force matcher.
- Filters good matches based on distance ratio (Lowe's ratio test).
if len(good_matches) > 150:
src_pts = np.float32([self.kp_template[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([kp_frame[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
h, w = self.template.shape
pts = np.float32([[0, 0], [0, h], [w, h], [w, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
frame = cv2.polylines(frame, [np.int32(dst)], True, (0, 255, 0), 3, cv2.LINE_AA)- Uses homography to map the detected object in the video stream and draws a green bounding box around it.
def find_best_parameters(self):
nfeatures_list = [500, 1000, 1500]
scaleFactor_list = [1.1, 1.2, 1.3]
nlevels_list = [8, 10, 12]
...
for nfeatures in nfeatures_list:
for scaleFactor in scaleFactor_list:
...
orb = cv2.ORB_create(nfeatures=nfeatures, scaleFactor=scaleFactor, ...)
self.kp_template, self.des_template = orb.detectAndCompute(self.template, None)- Iteratively tests different ORB parameters to find the configuration with the highest number of good matches.
- Saves the best parameters to a JSON file.
def load_and_use_parameters(self):
with open(r'best_orb_params.json', 'r') as f:
params = json.load(f)
orb = cv2.ORB_create(nfeatures=params['nfeatures'], scaleFactor=params['scaleFactor'], ...)- Loads the best ORB parameters from the JSON file for consistent detection.
-
Edge Detection Modes:
-
Canny: Pressc. -
Sobel: Presss. -
Laplacian: Pressl.
-
-
Exit Application:
- Press
qto quit.
- Press
-
Initialization:
-
EdgeDetectionclass preprocesses video frames using edge detection. -
TemplateMatchersets up ORB and matches the template against the video stream.
-
-
Runtime Matching:
- Frames are captured, processed for edges, and keypoints are extracted.
- ORB matches keypoints between the template and the frame.
- If sufficient matches are found, a bounding box is drawn around the detected object.
-
Dynamic Tuning:
- Find optimal ORB parameters using
find_best_parameters. - Save and reuse the parameters for consistent results.
- Find optimal ORB parameters using
- OpenCV (
cv2) - NumPy (
numpy) - PyQt6 (for popups)
- Find Best ORB Parameters
python template_matcher.py find- Run with Optimal Parameters
python template_matcher.py use