import cv2
import numpy as np
def find_and_mark_image(big_path, small_path):
# 读取图片
img_big = cv2.imread(big_path)
img_small = cv2.imread(small_path)
# 转换为灰度图
gray_big = cv2.cvtColor(img_big, cv2.COLOR_BGR2GRAY)
gray_small = cv2.cvtColor(img_small, cv2.COLOR_BGR2GRAY)
# 添加图像预处理 - 增加模糊程度
gray_big = cv2.GaussianBlur(gray_big, (5,5), 0) # 从(3,3)改为(5,5)
gray_small = cv2.GaussianBlur(gray_small, (5,5), 0)
# 增强对比度
gray_big = cv2.equalizeHist(gray_big)
gray_small = cv2.equalizeHist(gray_small)
# 创建SIFT对象 - 增加特征点数量
sift = cv2.SIFT_create(nfeatures=0, nOctaveLayers=5, contrastThreshold=0.04, edgeThreshold=10, sigma=1.6)
# 检测特征点并计算描述符
kp1, des1 = sift.detectAndCompute(gray_small, None)
kp2, des2 = sift.detectAndCompute(gray_big, None)
# 创建FLANN匹配器
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=200) # 从150增加到200
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 进行特征匹配
matches = flann.knnMatch(des1, des2, k=2)
# 筛选好的匹配点
good_matches = []
for m, n in matches:
if m.distance < 0.9 * n.distance: # 从0.85提高到0.9
good_matches.append(m)
if len(good_matches) >= 4: # 从6降低到4
# 获取匹配点的坐标
src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
# 计算变换矩阵
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 7.0) # 从6.0提高到7.0
# 获取small图像的尺寸
h, w = gray_small.shape
# 计算变换后的角点坐标
pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
# 在big图像上绘制红色矩形框
img_result = cv2.polylines(img_big, [np.int32(dst)], True, (0, 0, 255), 3)
# 保存结果
cv2.imwrite('result.jpg', img_result)
return True
return False
if __name__ == "__main__":
result = find_and_mark_image("big.jpg", "small.jpg")
if result:
print("匹配成功,结果已保存为result.jpg")
else:
print("未找到匹配区域")