def get_all_match(image, needle): """在image中搜索needle""" if len(needle.shape) == 3 and needle.shape[2] == 4: bgr, a = split_bgra(needle) match = cv.matchTemplate(image, bgr, cv.TM_CCORR_NORMED, mask=a) else: match = cv.matchTemplate(image, needle, cv.TM_CCORR_NORMED) # 将所有nan变为1 match = 1 - np.nan_to_num(match) best = match.min() if best < 0: logger.error( "MatchError for size {0[1]}x{0[0]}({0[2]}) in {1[1]}x{1[0]}: {2}".format( needle.shape, image.shape, best ) ) import pickle import datetime with open( "shots/MatchError@{:%Y-%m-%d_%H%M%S}.pkl".format(datetime.datetime.now()), "wb", ) as f: pickle.dump({"image": image, "needle": needle, "match": match}, f) return get_all_match_backup(image, needle) return match
def match(self, target, template): loc = [] img_rgb = cv2.imread(target) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread(template, 0) run = 1 w, h = template.shape[::-1] # print(w, h) res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) # 使用二分法查找阈值的精确值 L = 0 R = 1 while run < 20: run += 1 threshold = (R + L) / 2 if threshold < 0: print('Error') return None loc = np.where(res >= threshold) # print(len(loc[1])) if len(loc[1]) > 1: L += (R - L) / 2 elif len(loc[1]) == 1: print('目标区域起点x坐标为:%d' % loc[1][0]) break elif len(loc[1]) < 1: R -= (R - L) / 2 return loc[1][0]
def compare(self, img_list, acc=0.85, special=False): imgs = [] self.screenshot = self.adbkit.screenshots() for item in img_list: imgs.append(cv2.imread(item)) if special: cv2.rectangle(self.screenshot, (0, 0), (1280, 420), color=(0, 0, 0), thickness=-1) for img in imgs: find_height, find_width = img.shape[:2:] result = cv2.matchTemplate(self.screenshot, img, cv2.TM_CCOEFF_NORMED) reslist = cv2.minMaxLoc(result) if self.debug: cv2.rectangle( self.screenshot, reslist[3], (reslist[3][0] + find_width, reslist[3][1] + find_height), color=(0, 250, 0), thickness=2) if reslist[1] > acc: if self.debug: print("[Detect]acc rate:", round(reslist[1], 2)) pos = [reslist[3][0], reslist[3][1]] pos = [x * self.adbkit.capmuti for x in pos] return pos, find_height * self.adbkit.capmuti, find_width * self.adbkit.capmuti if special: return False, 0, 0 else: return False
def take_screenshot(self): pyautogui.screenshot(r"media/myscreenshot.jpg") template_image = cv2.imread(r"media/myscreenshot.jpg", cv2.IMREAD_UNCHANGED) result = cv2.matchTemplate(template_image, self.image, cv2.TM_CCOEFF_NORMED) self.locations = np.where(result >= self.threshold) self.locations = list(zip(*self.locations[::-1]))
def get_pay_keyboard_number_location(impath, target, fit_num): #fit_num是匹配度,如 0.95,0.85 print("start find pic") positions = {} start = time.time() img_rgb = cv2.imread(impath) teNum = "done" template = cv2.imread(target) h, w = template.shape[:-1] res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED) threshold = fit_num # 匹配度参数,1为完全匹配 loc = np.where(res >= threshold) if len(loc) > 0: # positions[teNum] = zip(*loc[::-1])[0] # python2的写法 zipped = zip(*loc[::-1]) #list[::-1] 相当于起点为最后的一个,终点为第一个,然后一次减少一个 positions[teNum] = (list(zipped))[0] else: print("Can not found pic: ") end = time.time() print(end - start) return positions[teNum]
def standby(template, acc=0.85, special=False): # 模擬器截圖 # adbkit.screenshots() # 载入图像 target_img = adbkit.screenshots() if special == True: cv2.rectangle(target_img, (0, 0), (1280, 420), color=(0, 0, 0), thickness=-1) cv2.imwrite("screencap-rect.png", target_img) find_img = cv2.imread(str(template)) find_height, find_width = find_img.shape[:2:] # 模板匹配 result = cv2.matchTemplate(target_img, find_img, cv2.TM_CCOEFF_NORMED) # min_val, max__val, min_loc, max_loc = cv2.minMaxLoc(result) reslist = cv2.minMaxLoc(result) #reslist[1] = max__val; reslist[3] = max_loc; if debug: cv2.rectangle(target_img, reslist[3], (reslist[3][0]+find_width, reslist[3][1]+find_height), color=(0, 255, 0), thickness=2) #cv2.imwrite("screencap.png", target_img) cv2.imshow("screenshots", target_img) cv2.waitKey(1) if reslist[1] > acc: if debug: print("[Detect]acc rate:", round(reslist[1], 2)) return reslist[3], find_height, find_width else: if debug: print("[Detect]acc rate:", round(reslist[1], 2)) return False
def search_frame_ir(self, frame, subject, frame_index): frame_filename = os.path.basename(frame) subject_filename = os.path.basename(subject) # from: https://stackoverflow.com/a/15147009/580651 frame_rgb = cv2.imread(frame) subject_rgb = cv2.imread(subject) # TODO: resize subject_rgb to different sizes instead of using one fixed size 32-64 pixels # TODO: remember in which crop area and with what size a first match was found - use for rest with threshold # subject_size = self.job.icon_on_screen_size sizes = range(65, 31, -2) if self.matched_subject_size > 0: sizes = range(self.matched_subject_size + 1, max(self.matched_subject_size - 11, 31), -1) def prep_subject(image, size): # subject_rgb_prep = cv2.cvtColor(subject_rgb_prep, cv2.COLOR_BGR2GRAY) # subject_rgb_prep = cv2.Canny(subject_rgb_prep, 50, 200) return cv2.resize(image, (size, size), interpolation=cv2.INTER_AREA) for subject_size in sizes: subject_rgb_prep = prep_subject(subject_rgb, subject_size) w, h = subject_rgb_prep.shape[:-1] res = cv2.matchTemplate(frame_rgb, subject_rgb_prep, cv2.TM_CCOEFF_NORMED) # filter out by threshold threshold = .8 loc = np.where(res >= threshold) matches = [] if loc[0].size > 0: # and self.last_matched_subject != subject_filename: # and frame_index != self.last_matched_frame_index + 1: for pt in zip(*loc[::-1]): # switch columns and rows matches.append({ "pos": pt, "w": w, "h": h, }) cv2.rectangle(frame_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2) match_file_name = os.path.splitext(frame_filename)[0] + '-' + os.path.splitext(subject_filename)[0] + \ os.path.splitext(frame_filename)[1] match_file = os.path.join(self.job.matches_dir, match_file_name) cv2.imwrite(match_file, frame_rgb) result = { "frame": frame_filename, "subject": subject_filename, "subject_size": subject_size, } # remember subject size to speed up the process for subsequent frames self.last_matched_subject = subject_filename self.last_matched_frame = frame_filename self.last_matched_frame_index = frame_index if self.matched_subject_size == 0 or subject_size < self.matched_subject_size: self.matched_subject_size = subject_size # print('� ' + subject_filename + '' + str(subject_size)) return result return
def check_color(sh: str, tmp: str, threshold: float = 0.8) -> bool: img = cv2.imread(sh, cv2.IMREAD_COLOR) template = cv2.imread(tmp, cv2.IMREAD_COLOR) res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) if (res >= threshold).any(): return True return False
def most_probable_location(self, pil, image, precision): img_rgb = np.array(pil) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread(image, cv2.IMREAD_GRAYSCALE) height, width = template.shape res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) # Minimum Square Difference (TM_SQDIFF) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) if max_val < precision: return None if self.click_scope: with lock: if not self.click_blocked: self.click(pos=max_loc, action="left", sluggishness=0, offset=5, height=height, width=width) self.report(image, max_loc) if self.run_until_found_one: self.block_clicks() else: self.report(image, max_loc) else: self.report(image, max_loc) return max_loc
def find_rectangle(self, screenshot_img, threshold=0.55): # run the OpenCV algorithm result = cv.matchTemplate(screenshot_img, self.metin_img, self.method) # Get the all the positions from the match result that exceed our threshold locations = np.where(result >= threshold) locations = list(zip(*locations[::-1])) #print(locations) # You'll notice a lot of overlapping rectangles get drawn. We can eliminate those redundant # locations by using groupRectangles(). # First we need to create the list of [x, y, w, h] rectangles rectangles = [] for loc in locations: rect = [int(loc[0]), int(loc[1]), self.metin_w, self.metin_h] # Add every box to the list twice in order to retain single (non-overlapping) boxes rectangles.append(rect) rectangles.append(rect) # Apply group rectangles. # The groupThreshold parameter should usually be 1. If you put it at 0 then no grouping is # done. If you put it at 2 then an object needs at least 3 overlapping rectangles to appear # in the result. I've set eps to 0.5, which is: # "Relative difference between sides of the rectangles to merge them into a group." rectangles, weights = cv.groupRectangles(rectangles, groupThreshold=1, eps=0.5) #print(rectangles) return rectangles
def image_search(target_img, pattern, precision=0.8): # preprocess image target = cv2.imread(target_img, 0) template = cv2.imread(pattern, 0) # if target_img is None: # raise FileNotFoundError('Image name {} cannot be found'.format(target_img)) # if template is None: # raise FileNotFoundError('Image name {} cannot be found'.format(template)) height, width = template.shape x_offset = width / 2 y_offset = height / 2 try: result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) print(' Image matching rate: {}'.format(max_val)) if max_val < precision: return False x, y = (max_loc[0] + x_offset, max_loc[1] + y_offset) # print(x, y) return x, y except: print( "[ImgNotFound] OpenCV couldn't find the image file in the given directory" )
def locate(target, want, show=0, msg=0): loc_pos = [] want, treshold, c_name = want[0], want[1], want[2] result = cv2.matchTemplate(target, want, cv2.TM_CCOEFF_NORMED) location = numpy.where(result >= treshold) if msg: # 显示正式寻找目标名称,调试时开启 print(c_name, 'searching... ') h, w = want.shape[:-1] # want.shape[:-1] n, ex, ey = 1, 0, 0 for pt in zip(*location[::-1]): # 其实这里经常是空的 x, y = pt[0]+int(w/2), pt[1]+int(h/2) if (x-ex)+(y-ey) < 15: # 去掉邻近重复的点 continue ex, ey = x, y cv2.circle(target, (x, y), 10, (0, 0, 255), 3) if msg: print(c_name, 'we find it !!! ,at', x, y) x, y = int(x), int(y) loc_pos.append([x, y]) if show: # 在图上显示寻找的结果,调试时开启 cv2.imshow('we get', target) cv2.waitKey(0) cv2.destroyAllWindows() return loc_pos
def is_similar(image1, image2): "Compares two images" logger.debug("First image: %s, Second image: %s", image1, image2) image1 = cv2.imread(image1) image2 = cv2.imread(image2) first_image_hist = cv2.calcHist([image1], [0], None, [256], [0, 256]) second_image_hist = cv2.calcHist([image2], [0], None, [256], [0, 256]) # img_hist_diff = cv2.compareHist( # first_image_hist, second_image_hist, # cv2.HISTCMP_BHATTACHARYYA # ) img_template_probability_match = cv2.matchTemplate( first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0] img_template_probability_match *= 100 similar = bool(img_template_probability_match >= TRESHOLD_PERCANTAGE) log_level = logging.WARNING if similar else logging.INFO logger.log(log_level, "Similarity: %s", str(img_template_probability_match)) return similar
def find_all_template(cls, source, target, threshold=0.8, mac_count=None): mask = None if len(target.shape) == 3 and target.shape[2] == 4: mask = target[:, :, 3] target = cv2.cvtColor(target, cv2.COLOR_BGRA2BGR) res = cv2.matchTemplate(source, target, cv2.TM_CCOEFF_NORMED, mask=mask) result = [] height, width = target.shape[:2] while True: _, max_val, _, tl = cv2.minMaxLoc(res) if max_val < threshold: break br = (tl[0] + width, tl[1] + height) mp = (int(tl[0] + width / 2), int(tl[1] + height / 2)) result.append({ 'pt': mp, 'rect': (tl, br), 'conf': max_val }) if mac_count is not None: if mac_count <= 0: break else: mac_count -= 1 cv2.floodFill(res, None, tl, (-1000,), max_val-threshold+0.1, 1, flags=cv2.FLOODFILL_FIXED_RANGE) return result
def _find_match_pos(self, screenshot, template, threshold=THRESHOLD) -> Tuple[int, int]: name = template source: np.ndarray if isinstance(screenshot, np.ndarray): source = screenshot else: source = cv.imread(screenshot) templatepath = "images/{}.png".format(template) if templatepath in self._imagecache: template = self._imagecache[templatepath] else: template = cv.imread(templatepath) height, width = source.shape[:2] fx = width / BASE_WIDTH fy = height / BASE_HEIGHT template = cv.resize(template, None, fx=fx, fy=fy, interpolation=cv.INTER_AREA) self._imagecache[templatepath] = template theight, twidth = template.shape[:2] ret = cv.matchTemplate(source, template, cv.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv.minMaxLoc(ret) if max_val > threshold: return (max_loc[0] + twidth / 2, max_loc[1] + theight / 2) else: return None
def tempmatch(img, tmp): # 返回相关值 if img.shape[0] >= tmp.shape[0] and img.shape[1] >= tmp.shape[1]: method = eval('cv.TM_CCOEFF') res = cv.matchTemplate(img, tmp, method) min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) return max_val else: return 0
def standby(images=get_sh((0, 0)), tmp: str = None, threshold: float = 0.85) -> bool: img = images template = cv2.imread(tmp) res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) res = cv2.minMaxLoc(res) # note改取得最相似之座標 res[0]為最小相似度的座標,res[1]為最大相似度的座標 if (res[1] >= threshold): return True return False
def gatcha(self): gatcha = [] for index in range(len(self.template)): result = cv2.matchTemplate(self.screenshot, self.template[index], cv2.TM_CCOEFF_NORMED) result = cv2.minMaxLoc(result) if result[1] > 0.9: gatcha.append(self.ark[index]) return gatcha
def _find_matches(self, img: np.ndarray, sprite: Sprite, dx: int) -> Iterable[Tuple[int, int]]: scores = matchTemplate(img, sprite.img, cv2.TM_SQDIFF, mask=sprite.mask) if self.debug: print(list(sorted(scores.flatten()))[:5], scores.mean()) return zip(*(np.where(scores <= self.threshold)))
def get_crd(imges, tmp: str, threshold: float = 0.85) -> [(int, int)]: img = imges template = cv2.imread(tmp) res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) pos = [] loc = np.where(res >= threshold) for pt in zip(*loc[::-1]): pos.append(pt) return pos
def calc_difference(hist_1, hist_2): img_hist_diff = cv2.compareHist(hist_1, hist_2, cv2.HISTCMP_BHATTACHARYYA) img_template_probability_match = cv2.matchTemplate( hist_1, hist_2, cv2.TM_CCOEFF_NORMED)[0][0] img_template_diff = 1 - img_template_probability_match # taking only 10% of histogram diff, since it's less accurate than template method commutative_image_diff = (img_hist_diff / 10) + img_template_diff logging.debug("calculated image difference %f", commutative_image_diff) return commutative_image_diff
def match(state, template): match = cv2.matchTemplate(state, template, cv2.TM_CCOEFF_NORMED) loc = np.where(match >= 0.8) # * expression unpacks lists, [::-1] gets inverting positions of y with x for point in zip(*loc[::-1]): return point return False
def imageMatch(hwnd, image): # Match screenshot with template img = getWindowImg(hwnd) img_rgb = np.array(img) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread(image, 0) template.shape[::-1] res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) # Match rate return cv2.minMaxLoc(res)[1]
def imgdiffer(temurl): # im1 = Image.open(r'D:\\explor.png') # im1.save(r'D:\\explor.png') target = cv2.imread("D:\\twenty.png") template = cv2.imread(temurl) theight, twidth = template.shape[:2] result = cv2.matchTemplate(target,template,cv2.TM_SQDIFF_NORMED) # cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) print(min_val) return min_loc[0]+twidth/2,min_loc[1]+theight/2,min_val
def match(small_pic_path, large_pic): small_pic = cv2.imread(small_pic_path) small_pic = cv2.cvtColor(small_pic, cv2.COLOR_BGR2GRAY) small_pic = cv2.Canny(small_pic, 50, 200) large_pic = cv2.cvtColor(large_pic, cv2.COLOR_BGR2GRAY) large_pic = cv2.Canny(large_pic, 50, 200) result = cv2.matchTemplate(large_pic, small_pic, cv2.TM_CCOEFF) _, max, _, max_location = cv2.minMaxLoc(result) return (max, max_location)
def match_template_wrapped(input): res = cv2.matchTemplate(input, template_image, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) if show_result: w, h = template_image.shape[::-1] top_left = min_loc if method in [ cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED ] else max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(input, top_left, bottom_right, 255, 2) cv2.imshow('Template identification', input) return max_val, max_loc
def imagesearch(image, precision=0.8): im = pyautogui.screenshot() img_rgb = np.array(im) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread(image, 0) template.shape[::-1] res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) if max_val < precision: return [300, 500] return max_loc #返回圖片座標
def match(waitmatch, example, value=10000000): img = cv2.imread(waitmatch, 0) template = cv2.imread(example, 0) res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) flag = False if min_val < int(value): top_left = min_loc w, h = template.shape[::-1] return [top_left[0] + w // 2, top_left[1] + h // 2] else: return None
def match_template_multiple_wrapped(input): res = cv2.matchTemplate(input, template_image, method) loc = np.where(res >= threshold) if method not in [ cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED ] else np.where(res <= threshold) points = zip(*loc[::-1]) pts = [(pt[0], pt[1]) for pt in points] if show_result: w, h = template_image.shape[::-1] for pt in pts: cv2.rectangle(input, pt, (pt[0] + w, pt[1] + h), 255, 2) cv2.imshow('Template identification', input) return pts
def searchBox(whole_image, list_templates): method = cv2.TM_CCORR_NORMED for i in range(len(list_templates)): result = cv2.matchTemplate(whole_image, list_templates[i], method) _, _, _, mnLoc = cv2.minMaxLoc(result) MPx, MPy = mnLoc trows, tcols = list_templates[i].shape[:2] cv2.rectangle(whole_image, (MPx, MPy), (MPx + tcols, MPy + trows), 1.0, 10) return whole_image