在缩放图像中查找图像
Find image in scaled Image
我必须在桌面流中查找图像。我的代码有效,但如果图像在流中调整大小,则程序无法正常工作。我该如何解决这个问题?
from PIL import ImageGrab
import numpy as np
import cv2
template = cv2.imread('piccola.png') #image to find
w, h = template.shape[:-1]
while 1:
img = ImageGrab.grab(bbox=(0,0,800,600)) #bbox specifies specific region (bbox= x,y,width,height *starts top-left)
img_np = np.array(img) #this is the array obtained from conversion
#frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(img_np, template, cv2.TM_CCOEFF_NORMED)
threshold = .85
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]): # Switch columns and rows
cv2.rectangle(img_np, pt, (pt[0] + h, pt[1] + w), (0, 0, 255), 2)
cv2.imshow("output", img_np)
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
您实际上可以从模板图像中提取特征,而不是使用 cv2.matchTemplate,即提取诸如 SIFT/ORB/KAZE/BRISK 之类的特征,并通过从抓取的图像中提取相同的特征来匹配它们。您可以为匹配条件设置一个阈值。
您可以在此处阅读有关功能描述和匹配的更多信息 - https://docs.opencv.org/3.4/d5/dde/tutorial_feature_description.html
供您理解的示例代码。
import cv2
import numpy as np
img1 = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
# ORB Detector
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# Brute Force Matching
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
#drawing the matches
matching_result = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], None, flags=2)
您可以过滤距离 > 0.7(通常阈值)的匹配项并检查匹配项的百分比。基于此,您可以决定它找到相似图像的程度。
像 SIFT 这样的方法已获得专利但性能良好。
像 ORB 这样的方法是最快的,但不是缩放不变的。
你可以试试KAZE和AKAZE这样的方法。
我必须在桌面流中查找图像。我的代码有效,但如果图像在流中调整大小,则程序无法正常工作。我该如何解决这个问题?
from PIL import ImageGrab
import numpy as np
import cv2
template = cv2.imread('piccola.png') #image to find
w, h = template.shape[:-1]
while 1:
img = ImageGrab.grab(bbox=(0,0,800,600)) #bbox specifies specific region (bbox= x,y,width,height *starts top-left)
img_np = np.array(img) #this is the array obtained from conversion
#frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(img_np, template, cv2.TM_CCOEFF_NORMED)
threshold = .85
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]): # Switch columns and rows
cv2.rectangle(img_np, pt, (pt[0] + h, pt[1] + w), (0, 0, 255), 2)
cv2.imshow("output", img_np)
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
您实际上可以从模板图像中提取特征,而不是使用 cv2.matchTemplate,即提取诸如 SIFT/ORB/KAZE/BRISK 之类的特征,并通过从抓取的图像中提取相同的特征来匹配它们。您可以为匹配条件设置一个阈值。
您可以在此处阅读有关功能描述和匹配的更多信息 - https://docs.opencv.org/3.4/d5/dde/tutorial_feature_description.html
供您理解的示例代码。
import cv2
import numpy as np
img1 = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
# ORB Detector
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# Brute Force Matching
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
#drawing the matches
matching_result = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], None, flags=2)
您可以过滤距离 > 0.7(通常阈值)的匹配项并检查匹配项的百分比。基于此,您可以决定它找到相似图像的程度。
像 SIFT 这样的方法已获得专利但性能良好。
像 ORB 这样的方法是最快的,但不是缩放不变的。
你可以试试KAZE和AKAZE这样的方法。