用cv2,numpy,matplotlib做一个找茬游戏辅助,要求加载两幅图片,并将两张图片对齐,用背景减法做差找出不同并框出
时间: 2023-11-26 18:05:39 浏览: 99
好的,让我们一步步来完成这个找茬游戏的辅助程序。
首先,我们需要安装必要的库,即cv2、numpy和matplotlib。可以使用以下命令在终端或命令提示符中安装:
```
pip install opencv-python numpy matplotlib
```
接着,我们需要加载两张图片并将它们对齐。我们可以使用cv2中的SIFT算法来检测关键点和描述符,并使用FLANN匹配器来找到两张图片之间的对应点。然后,我们可以使用cv2中的findHomography函数来计算变换矩阵,并将其中一张图片转换为另一张图片的视角。以下是实现代码:
```python
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 加载两张图片
img1 = cv2.imread('image1.jpg', 0)
img2 = cv2.imread('image2.jpg', 0)
# 初始化SIFT检测器
sift = cv2.xfeatures2d.SIFT_create()
# 检测关键点和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 创建FLANN匹配器
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
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.7 * n.distance:
good_matches.append(m)
# 获取匹配点的坐标
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, 5.0)
# 使用变换矩阵将第一张图片转换为第二张图片的视角
aligned_img1 = cv2.warpPerspective(img1, M, (img2.shape[1], img2.shape[0]))
```
现在,我们已经将两张图片对齐了。接下来,我们可以使用背景减法来找出不同之处并框出。
我们可以使用cv2中的absdiff函数来计算两张图片的差异,并使用cv2中的threshold函数将像素值小于某个阈值的像素设置为0。然后,我们可以使用cv2中的findContours函数来找到图像中的轮廓,并使用cv2中的boundingRect函数来获取每个轮廓的边界框。最后,我们可以使用matplotlib中的plot函数来显示结果。以下是实现代码:
```python
# 计算两张图片的差异
diff_img = cv2.absdiff(aligned_img1, img2)
# 应用阈值
ret, thresh = cv2.threshold(diff_img, 50, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 获取边界框并绘制矩形
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(img2, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示结果
plt.subplot(121), plt.imshow(aligned_img1, cmap='gray'), plt.title('Image 1')
plt.subplot(122), plt.imshow(img2, cmap='gray'), plt.title('Image 2')
plt.show()
```
好了,我们已经完成了找茬游戏的辅助程序。完整代码如下:
```python
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 加载两张图片
img1 = cv2.imread('image1.jpg', 0)
img2 = cv2.imread('image2.jpg', 0)
# 初始化SIFT检测器
sift = cv2.xfeatures2d.SIFT_create()
# 检测关键点和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 创建FLANN匹配器
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
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.7 * n.distance:
good_matches.append(m)
# 获取匹配点的坐标
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, 5.0)
# 使用变换矩阵将第一张图片转换为第二张图片的视角
aligned_img1 = cv2.warpPerspective(img1, M, (img2.shape[1], img2.shape[0]))
# 计算两张图片的差异
diff_img = cv2.absdiff(aligned_img1, img2)
# 应用阈值
ret, thresh = cv2.threshold(diff_img, 50, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 获取边界框并绘制矩形
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(img2, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示结果
plt.subplot(121), plt.imshow(aligned_img1, cmap='gray'), plt.title('Image 1')
plt.subplot(122), plt.imshow(img2, cmap='gray'), plt.title('Image 2')
plt.show()
```
阅读全文