OpenCV-Python中的图像处理-图像特征

news/2024/7/21 5:43:19 标签: python, opencv, 图像处理

OpenCV-Python中的图像处理-图像特征

  • 图像特征
    • Harris角点检测
    • 亚像素级精度的角点检测
    • Shi-Tomasi角点检测
    • SIFT(Scale-Invariant Feature Transfrom)
    • SURF(Speeded-Up Robust Features)
    • FAST算法
    • BRIEF(Binary Robust Independent Elementary Features)算法
    • ORB (Oriented FAST and Rotated BRIEF)算法
  • 特征匹配
    • Brute-Force 蛮力匹配
      • 对 ORB 描述符进行蛮力匹配
      • 对 SIFT 描述符进行蛮力匹配和比值测试
    • FLANN 匹配

图像特征

  • 特征理解
  • 特征检测
  • 特征描述

Harris角点检测

  • cv2.cornerHarris(img, blockSize, ksize, k, borderType=…)
    • img:输入图像,数据类型为float32
    • blockSize:角点检测中要考虑的领域大小
    • ksize:Sobe求导中使用的窗口大小
    • k:Harris角点检测方程中的自由参数,取值参数为 [0.04,0.06]
    • borderType:边界类型
python">import numpy as np
import cv2
from matplotlib import pyplot as plt

# img = cv2.imread('./resource/opencv/image/chessboard.png', cv2.IMREAD_COLOR)
img = cv2.imread('./resource/opencv/image/pattern.png', cv2.IMREAD_COLOR)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)

# 输入图像必须是float32,最后一个参数在0.04到0.05之间
dst = cv2.cornerHarris(gray, 2, 3, 0.05)
dst = cv2.dilate(dst, None)

img[dst>0.01*dst.max()] = [0, 0, 255]

cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

亚像素级精度的角点检测

  • cv2.cornerSubPix(img, corners, winSize, zeroZone, criteria)
    最大精度的角点检测,首先要找到 Harris角点,然后将角点的重心传给这个函数进行修正。
python">import numpy as np
import cv2
from matplotlib import pyplot as plt


img = cv2.imread('./resource/opencv/image/subpixel.png', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
dst = cv2.dilate(dst, None)
ret, dst = cv2.threshold(dst, 0.01*dst.max(), 255, 0)
dst = np.uint8(dst)

ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)

corners = cv2.cornerSubPix(gray, np.float32(centroids), (5,5), (-1, -1), criteria)

res = np.hstack((centroids, corners))

res = np.int0(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]]=[0,255,0]

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Harris 角点用红色像素标出,绿色像素是修正后的角点。
在这里插入图片描述

Shi-Tomasi角点检测

  • cv2.goodFeatureToTrack()
python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('./resource/opencv/image/shitomasi_block.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

corners = cv2.goodFeaturesToTrack(gray, 25, 0.01, 10)

corners = np.int0(corners)

for i in corners:
    x,y = i.ravel()
    cv2.circle(img, (x,y), 3, 255, -1)

plt.imshow(img)
plt.show()

在这里插入图片描述

SIFT(Scale-Invariant Feature Transfrom)

  • SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。

  • cv2.SIFT_create()

    • kp = sift.detect(img, None):查找特征点
    • kp, des = sift.compute(img, kp):计算特征点
    • kp, des = sift.detectAndCompute(img, None) :直接找到特征点并计算描述符
  • cv2.drawKeypoints(img, kp, out_img, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS):画特征点

    • img : 输入图像
    • kp:图像特征点
    • out_img:输出图像
    • flags:
      cv2.DRAW_MATCHES_FLAGS_DEFAULT
      cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
      cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
python">import numpy as np
import cv2


# 读取图片
# img = cv2.imread('./resource/opencv/image/home.jpg')
img = cv2.imread('./resource/opencv/image/AverageMaleFace.jpg')
key_points = img.copy()
 
# 实例化SIFT算法
sift = cv2.SIFT_create()
 
# 得到特征点
kp = sift.detect(img, None)
print(np.array(kp).shape)

# 绘制特征点
cv2.drawKeypoints(img, kp, key_points, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)
 
# 图片展示
cv2.imshow("key points", key_points)
cv2.waitKey(0)
cv2.destroyAllWindows()
 
# 保存图片
# cv2.imwrite("key_points.jpg", key_points)
 
# 计算特征
kp, des = sift.compute(img, kp)
 
# 调试输出
print(des.shape)
print(des[0])

cv2.imshow('kp', key_points)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

SURF(Speeded-Up Robust Features)

  • 文章前面介绍了使用 SIFT 算法进行关键点检测和描述。但是这种算法的执行速度比较慢,人们需要速度更快的算法。在 2006 年Bay,H.,Tuytelaars,T. 和 Van Gool,L 共同提出了 SURF(加速稳健特征)算法。跟它的名字一样,这是个算法是加速版的 SIFT。
  • 与 SIFT 相同 OpenCV 也提供了 SURF 的相关函数。首先我们要初始化一个 SURF 对象,同时设置好可选参数: 64/128 维描述符, Upright/Normal 模式等。所有的细节都已经在文档中解释的很明白了。就像我们在SIFT 中一样,我们可以使用函数 SURF.detect(), SURF.compute() 等来进行关键点搀着和描述。

img = cv2.imread(‘fly.png’, 0)
surf = cv2.SURF(400)
kp, des = surf.detectAndCompute(img, None)
len(kp) # 699
print(surf.hessianThreshold)
surf.hessianThreshold = 50000
kp, des = surf.detectAndCompute(img,None)
print(len(kp)) # 47
不检测关键点的方向
print(surf.upright) #False
surf.upright = True

FAST算法

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)

# fast = cv2.FastFeatureDetector_create(threshold=100, nonmaxSuppression=False, type=cv2.FAST_FEATURE_DETECTOR_TYPE_5_8)
fast = cv2.FastFeatureDetector_create(threshold=400)
kp = fast.detect(img, None)
img2 = cv2.drawKeypoints(img, kp, img.copy(), color=(0, 0, 255), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow('fast', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

BRIEF(Binary Robust Independent Elementary Features)算法

  • BRIEF(Binary Robust Independent Elementary Features)
python">import numpy as np
import cv2
from matplotlib import pyplot as plt


img = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)


# Initiate STAR detector
star = cv2.FeatureDetector_create("STAR")
# Initiate BRIEF extractor
brief = cv2.DescriptorExtractor_create("BRIEF")
# find the keypoints with STAR
kp = star.detect(img,None)
# compute the descriptors with BRIEF
kp, des = brief.compute(img, kp)
print(brief.getInt('bytes'))
print(des.shape)

ORB (Oriented FAST and Rotated BRIEF)算法

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)


# ORB_create(nfeatures=..., scaleFactor=..., nlevels=..., edgeThreshold=..., firstLevel=..., WTA_K=..., scoreType=..., patchSize=..., fastThreshold=...)
orb = cv2.ORB_create()

kp = orb.detect(img, None)

kp, des = orb.compute(img, kp)

img2 = cv2.drawKeypoints(img, kp, img.copy(), color=(255, 0, 0), flags=0)
plt.imshow(img2)
plt.show()

在这里插入图片描述

特征匹配

OpenCV 中的特征匹配

  • 蛮力( Brute-Force)匹配
  • FLANN 匹配

Brute-Force 蛮力匹配

对 ORB 描述符进行蛮力匹配

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)


orb = cv2.ORB_create()

kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck=True)

matches = bf.match(des1, des2)

# matches = bf:match(des1; des2) 返回值是一个 DMatch 对象列表。这个
# DMatch 对象具有下列属性:
# • DMatch.distance - 描述符之间的距离。越小越好。
# • DMatch.trainIdx - 目标图像中描述符的索引。
# • DMatch.queryIdx - 查询图像中描述符的索引。
# • DMatch.imgIdx - 目标图像的索引。

# 距离排序
matches = sorted(matches, key = lambda x:x.distance)

# 画出前30匹配
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)

cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

对 SIFT 描述符进行蛮力匹配和比值测试

现在我们使用 BFMatcher.knnMatch() 来获得 k 对最佳匹配。在本例中我们设置 k = 2,这样我们就可以使用 D.Lowe 文章中的比值测试了。

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher_create()
matches = bf.knnMatch(des1, des2, k=2)

good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])

# drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=..., singlePointColor=..., matchesMask=..., flags: int = ...)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:100], None, flags=2)
plt.imshow(img3)
plt.show()

在这里插入图片描述

FLANN 匹配

FLANN 是快速最近邻搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的简称。它是一个对大数据集和高维特征进行最近邻搜索的算法的集合,而且这些算法都已经被优化过了。在面对大数据集时它的效果要好于 BFMatcher。我们来对第二个例子使用 FLANN 匹配看看它的效果。

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)


sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

flann = cv2.FlannBasedMatcher_create()
matches = flann.knnMatch(des1, des2, k=2)

matchesMask = [[0,0] for i in range(len(matches))]

for i, (m, n) in enumerate(matches):
    if m.distance < 0.7*n.distance:
        matchesMask[i] = [1,0]

draw_params = dict(matchColor = (0, 255, 0),
        singlePointColor = (255, 0, 0),
        matchesMask = matchesMask,
        flags = 0)

img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)
plt.imshow(img3)
plt.show()

在这里插入图片描述


http://www.niftyadmin.cn/n/4951410.html

相关文章

Docker容器的重启策略

1、 Docker容器的重启策略 Docker容器的重启策略如下&#xff1a; no&#xff0c;默认策略&#xff0c;在容器退出时不重启容器on-failure&#xff0c;在容器非正常退出时&#xff08;退出状态非0&#xff09;&#xff0c;才会重启容器 on-failure:3&#xff0c;指定启动的次…

MySQL--存储过程--详解/示例

MySQL中的存储过程详解 在MySQL数据库中&#xff0c;存储过程是一种预先编译好的SQL代码块&#xff0c;可以被重复调用。它们允许我们将常用的操作逻辑封装起来&#xff0c;并简化数据库交互。本文将介绍MySQL存储过程的基本语法和使用示例。 创建存储过程 使用CREATE PROCE…

python浅拷贝和深拷贝

1、B站视频 十分钟&#xff01;彻底弄懂Python深拷贝与浅拷贝机制_哔哩哔哩_bilibili 2、简书 NumPy之浅拷贝和深拷贝 - 简书 (jianshu.com) 3、CSDN-numpy numpy copy(无拷贝 浅拷贝、深拷贝)类型说明_genghaihua的博客-CSDN博客 4、CSDN-pytorch python、pytorch中的常见…

【LVS】1、LVS负载均衡群集

1.群集的含义&#xff1a; Cluster、群集、集群 由多台主机构成并作为一个整体&#xff0c;只提供一个访问入口&#xff08;域名与IP地址&#xff09;&#xff1b;可伸缩 2.集群使用的场景&#xff1a; 高并发 3.企业群集的分类&#xff1a; 根据群集所针对的目标差异&a…

IDEA两种方法修改生成的jar包名字

方法一&#xff1a; 直接修改pom文件中的如下部分 <artifactId>excelreport</artifactId> <version>0.0.1-SNAPSHOT</version> <name>excelreport</name> <description>excelreport</description> 修改完成后&#xff0c;点…

【C# 基础精讲】LINQ 基础

LINQ&#xff08;Language Integrated Query&#xff09;是一项强大的C#语言特性&#xff0c;它使数据查询和操作变得更加简洁、灵活和可读性强。通过使用LINQ&#xff0c;您可以使用类似SQL的语法来查询各种数据源&#xff0c;如集合、数组、数据库等。本文将介绍LINQ的基础概…

cesium中获取高度的误区

this.ellipsoid viewer.scene.globe.ellipsoid; var cartesian viewer.camera.pickEllipsoid(e.position, this.ellipsoid);if(cartesian){// 苗卡尔椭球体的三维坐标 转 地图坐标&#xff08;弧度&#xff09;var cartographic viewer.scene.globe.ellipsoid.cartesianToCa…

【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…