0-1.安装前需先卸载pip或conda安装的opencv与opencv_contrib:
pip uninstall opencv-contrib-python
pip uninstall opencv-python
0-2.python环境先安装NumPY
pip install numpy
1.下载OpenCV源码:https://github.com/opencv/opencv,
并却换到对应版本:git checkout 4.2.0
2.下载opencv_contrib源码:https://github.com/opencv/opencv_contrib/,
并却换到对应版本:git checkout 4.2.0
3.下载并安装CMake:https://cmake.org/download/
4.安装Visual Studio,安装时需勾选C++相关环境。
5.打开CMake,选择opencv源码文件夹与生成项目的文件夹。
6.点击Configure按钮,选择相应的Visual Studio版本,生成配置信息。
7.找到OPENCV_EXTRA_MODULES_PATH选项,选择opencv_contrib/modules文件夹。
8.找到PYTHON3_EXECUTABLE选项,选择python.exe文件。
9.找到PYTHON3_NUMPY_INCLUDE_DIRS选项,选择"python路径/lib/site-packages/numpy/core/include"文件夹。
10.找到PYTHON3_LIBRARY选项,选择"python路径/libs/python37.lib"文件
11.找到PYTHON3_PACKAGES_PATH选项,选择"python路径/Lib/site-packages"文件夹。
12.找到PYTHON3_INCLUDE_DIR选项,选择"python路径/include"文件夹。
13.勾选OPENCV_ENABLE_NONFREE选项。
14.新建一个BUILD_opencv_python3选项,并勾选。
15.新建一个PYTHON3_INCLUDE_PATH选项,与PYTHON3_INCLUDE_DIR值一样。
16.新建一个PYTHON3_LIBRARIES选项,与PYTHON3_LIBRARY值一样。
17.取消勾选BUILD_TESTS选项。
18.多次点击Configure,直到所有红色选项变成白色,这里注意日志下载异常,如果异常可能需要手动下载,放到目录.cache文件夹内。
19.点击Generate,生成项目,并用Visual Studio打开项目。
20.选择Release,重新生成ALL_BUILD项目。
21.生成INSTALL项目,即安装完成。"python路径/lib/site-packages/"文件夹下会生成cv2文件夹,注意版本号是否有误。
import cv2
import numpy as np
import time
import math
def fileToOpenCVImage(file_path):
'''OpenCV读取图片文件(中文路径)'''
nparr = np.fromfile(file_path, dtype=np.uint8)
opencv_img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return opencv_img
def openCVImageToFile(file_path, opencv_img):
'''OpenCV读取图片文件(中文路径)'''
cv2.imencode('.jpg', opencv_img)[1].tofile(file_path)
# 读取图片
img1 = fileToOpenCVImage('./data/sift_img/正面.jpg')
img2 = fileToOpenCVImage('./data/sift_img/侧面.jpg')
# 调整图片大小
img1 = cv2.resize(img1, (800, 450))
img2 = cv2.resize(img2, (800, 450))
img1 = cv2.GaussianBlur(img1,(0,0),3)
img2 = cv2.GaussianBlur(img2,(0,0),3)
# 创建SIFT对象,检测400个特征点
surf = cv2.xfeatures2d.SIFT_create(400)
# 提取两张图的特征信息
start = time.time()
kp1, des1 = surf.detectAndCompute(img1, None)
kp2, des2 = surf.detectAndCompute(img2, None)
end = time.time()
print(len(kp1), len(kp2))
print('特征耗时:%.5f s' % (end-start))
# 画出特征点
img1 = cv2.drawKeypoints(img1, kp1, img1)
img2 = cv2.drawKeypoints(img2, kp2, img2)
hmerge = np.hstack((img1, img2)) # 水平拼接
cv2.imshow("merge_img", hmerge) # 拼接显示
cv2.waitKey(0)
# BFMatcher匹配特征
bf = cv2.BFMatcher()
start = time.time()
matches = bf.knnMatch(des1, des2, k=2)
end = time.time()
print('匹配耗时:%.5f s' % (end-start))
# 调整ratio,按照距离比例筛选掉密集的特征点
good = []
for m, n in matches:
if m.distance/n.distance < 0.5:
good.append([m])
good.sort(key=lambda m: -m[0].distance)
# 画出未筛选的关系
img_BFmatch = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, flags=2)
cv2.imshow("BFmatch_all", img_BFmatch)
cv2.waitKey(0)
# 画出筛选后的关系
img_BFmatch = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)
cv2.imshow("BFmatch_good", img_BFmatch)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 正面坐标
org = np.float32([[kp1[good[0][0].queryIdx].pt[0], kp1[good[0][0].queryIdx].pt[1]],
[kp1[good[1][0].queryIdx].pt[0], kp1[good[1][0].queryIdx].pt[1]],
[kp1[good[2][0].queryIdx].pt[0], kp1[good[2][0].queryIdx].pt[1]],
[kp1[good[3][0].queryIdx].pt[0], kp1[good[3][0].queryIdx].pt[1]]])
# 侧面坐标
dst = np.float32([[kp2[good[0][0].trainIdx].pt[0], kp2[good[0][0].trainIdx].pt[1]],
[kp2[good[1][0].trainIdx].pt[0], kp2[good[1][0].trainIdx].pt[1]],
[kp2[good[2][0].trainIdx].pt[0], kp2[good[2][0].trainIdx].pt[1]],
[kp2[good[3][0].trainIdx].pt[0], kp2[good[3][0].trainIdx].pt[1]]])
print([kp1[good[0][0].queryIdx].pt[0], kp1[good[0][0].queryIdx].pt[1]],
[kp2[good[0][0].trainIdx].pt[0], kp2[good[0][0].trainIdx].pt[1]],
good[0][0].distance)
print(org)
print(dst)
# 透视变换
warpM = cv2.getPerspectiveTransform(dst, org)
result_img = cv2.warpPerspective(
img2, warpM, (img2.shape[1], img2.shape[0]), borderValue=(255, 255, 255))
cv2.imshow("perspective_img", result_img)
cv2.waitKey(0)
# openCVImageToFile('./data/sift_img/c(450x800).jpg', result_img)
hmerge = np.hstack((img1, result_img)) # 水平拼接
cv2.imshow("merge_img", hmerge) # 拼接显示
cv2.waitKey(0)