进入九游app

2020-03-07由程序员日记发表于系统教程 浏览28次

目录

编译并安装OpenCV

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文件夹,注意版本号是否有误。

SIFT特征提取

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)

SIFT特征点

特征点匹配

筛选匹配

透视变换(左:原正面图,右:透视变换后的图)