| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- 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_021855.png')
- template_image = cv2.imread('templates/end_of_log.jpg')
- w, h = 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()
|