@@ -2087,6 +2087,18 @@ def init_ui(self):
20872087 params_layout .addWidget (self .ransac_spin )
20882088 form_layout .addRow ("Params:" , params_layout )
20892089
2090+ # Visualizer controls (performance-friendly toggles)
2091+ viz_layout = QHBoxLayout ()
2092+ self .keypoints_check = QCheckBox ("Show Keypoints" )
2093+ self .keypoints_check .setChecked (False )
2094+ viz_layout .addWidget (self .keypoints_check )
2095+ viz_layout .addWidget (QLabel ("Detector" ))
2096+ self .detector_combo = QComboBox ()
2097+ self .detector_combo .addItems (["ORB" , "AKAZE" , "SIFT" ])
2098+ viz_layout .addWidget (self .detector_combo )
2099+ viz_layout .addStretch ()
2100+ form_layout .addRow ("Visualizer:" , viz_layout )
2101+
20902102 # Metrics display (move overlay metrics into GUI)
20912103 metrics_layout = QHBoxLayout ()
20922104 self .metric_inliers = QLabel ("Inliers: -" )
@@ -2289,12 +2301,31 @@ def capture_region_bgr(x: int, y: int, w: int, h: int) -> np.ndarray:
22892301 if strategy == "feature" :
22902302 # Feature-based preview: draw inlier matches and polygon
22912303 try :
2292- orb = cv2 .ORB_create (nfeatures = 1500 )
2304+ # Choose detector based on UI (ORB or AKAZE)
2305+ use_alg = self .detector_combo .currentText () if hasattr (self , 'detector_combo' ) else "ORB"
2306+ if use_alg == "AKAZE" :
2307+ detector = cv2 .AKAZE_create ()
2308+ norm = cv2 .NORM_HAMMING
2309+ elif use_alg == "SIFT" :
2310+ detector = cv2 .SIFT_create ()
2311+ norm = cv2 .NORM_L2
2312+ else :
2313+ detector = cv2 .ORB_create (nfeatures = 1500 )
2314+ norm = cv2 .NORM_HAMMING
22932315 gray_screen = cv2 .cvtColor (screenshot , cv2 .COLOR_BGR2GRAY )
22942316 gray_template = cv2 .cvtColor (template , cv2 .COLOR_BGR2GRAY )
2295- kps1 , des1 = orb .detectAndCompute (gray_template , None )
2296- kps2 , des2 = orb .detectAndCompute (gray_screen , None )
2297- bf = cv2 .BFMatcher (cv2 .NORM_HAMMING , crossCheck = False )
2317+ kps1 , des1 = detector .detectAndCompute (gray_template , None )
2318+ kps2 , des2 = detector .detectAndCompute (gray_screen , None )
2319+ # Draw scene keypoints on the preview for visual debugging (optional)
2320+ if getattr (self , 'keypoints_check' , None ) and self .keypoints_check .isChecked ():
2321+ try :
2322+ keypoint_img = cv2 .drawKeypoints (display_img , kps2 if kps2 is not None else [], None ,
2323+ color = (255 , 255 , 0 ), flags = cv2 .DRAW_MATCHES_FLAGS_DEFAULT )
2324+ if keypoint_img is not None :
2325+ display_img = keypoint_img
2326+ except Exception :
2327+ pass
2328+ bf = cv2 .BFMatcher (norm , crossCheck = False )
22982329 matches = bf .knnMatch (des1 , des2 , k = 2 ) if des1 is not None and des2 is not None else []
22992330 good = []
23002331 ratio_thresh = float (self .ratio_spin .value ())
0 commit comments