import cv2 import numpy as np def non_max_suppression(boxes, overlapThresh): if len(boxes) == 0: return [] # Convert to float boxes = np.array(boxes, dtype="float") # Initialize the list of picked indexes pick = [] # Grab the coordinates of the bounding boxes x1 = boxes[:, 0] y1 = boxes[:, 1] x2 = boxes[:, 2] y2 = boxes[:, 3] # Compute the area of the bounding boxes and sort by bottom-right y-coordinate area = (x2 - x1 + 1) * (y2 - y1 + 1) idxs = np.argsort(y2) # Keep looping while some indexes still remain in the indexes list while len(idxs) > 0: # Grab the last index in the indexes list and add the index value to the list of picked indexes last = len(idxs) - 1 i = idxs[last] pick.append(i) # Find the largest (x, y) coordinates for the start of the bounding box and the smallest (x, y) # coordinates for the end of the bounding box xx1 = np.maximum(x1[i], x1[idxs[:last]]) yy1 = np.maximum(y1[i], y1[idxs[:last]]) xx2 = np.minimum(x2[i], x2[idxs[:last]]) yy2 = np.minimum(y2[i], y2[idxs[:last]]) # Compute the width and height of the bounding box w = np.maximum(0, xx2 - xx1 + 1) h = np.maximum(0, yy2 - yy1 + 1) # Compute the ratio of overlap overlap = (w * h) / area[idxs[:last]] # Delete all indexes from the index list that have overlap greater than the threshold idxs = np.delete( idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0])) ) # Return only the bounding boxes that were picked return boxes[pick].astype("int") # Load images target_image = cv2.imread("test/20240108_224218.jpg") template_image = cv2.imread("templates/dungeon/attack.png") h, w = template_image.shape[:-1] # Template matching result = cv2.matchTemplate(target_image, template_image, cv2.TM_CCOEFF_NORMED) # Define a threshold threshold = 0.9 # Adjust this threshold based on your requirements # Finding all locations where match exceeds threshold locations = np.where(result >= threshold) locations = list(zip(*locations[::-1])) # Create list of rectangles rectangles = [(*loc, loc[0] + w, loc[1] + h) for loc in locations] # Apply non-maximum suppression to remove overlaps rectangles = non_max_suppression(rectangles, 0.3) # Draw rectangles around matches for startX, startY, endX, endY in rectangles: cv2.rectangle(target_image, (startX, startY), (endX, endY), (0, 255, 0), 2) # Print the coordinates of the rectangle centerX = round(startX + (endX - startX) / 2) centerY = round(startY + (endY - startY) / 2) print(f"center coordinates: {centerX}/{centerY}") # Display the result cv2.imshow("Matched Results", target_image) cv2.waitKey(0) cv2.destroyAllWindows()