当我们进行目标追踪目标分割的时候一个基础的问题是:我们要找到吐下那个的特征,这些特征要易于被追踪比较。通俗的来说就是找到图象中的一些区域,无论你想向那个方向移动这些区域变化都很大,这个找到图象特征的技术被称为特征检测。
原理。此外简单说一句这个算法的主要思想是计算像素的某个值,当其大于某个阈值时就认为该像素是角点(特征点)。
cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
src是输入图象
blocksize角点检测中考虑的领域大小
ksizesobel求导中使用的窗口大小
k是harris角点检测方程中的自由参数,取值范围[0.04,0.06]
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('C:/Users/dell/Desktop/c1.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray=np.float32(gray)
#输入的图像必须是float32格式的,最后一个参数的要求在上面
dst=cv2.cornerHarris(gray,2,3,0.04)
#这里的膨胀操作使标记的点膨胀,当然没有这步也可以。
dst=cv2.dilate(dst,None)
#把原图像中超过相应阈值的区域标红,参数不是固定的注意调参。
img[dst>0.01*dst.max()]=[0,0,255]
cv2.imshow('dst',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
有时我们还需要最大精度的角点检测,opencv也为我们提供了函数。
基本原理是,我们先找到harris角点,然后将角点的中心传给这个函数进行修正。harris角点用红色标出,绿色像素是修正后的像素。使用这个函数我们要定义一条迭代停止条件,当迭代此时或者精度达到调节后迭代就会停止。我们也需要定义角点搜索邻域的大小。
Python: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)
image是输入图象
corner是 输入角点的初始坐标和为输出提供的精确坐标
winsize是搜索窗口边长的一半。例如,如果 winSize=Size(5,5)使用 5 * 2 + 1 \ times 5 * 2 + 1 = 11 \ times 11 搜索窗口
zerozone是搜索区域中间的死区大小的一半,以下公式中的求和未完成。它有时用于避免自相关矩阵的可能奇点。(-1,-1)的值表示没有这样的大小
criteria是迭代停止的条件。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('C:/Users/dell/Desktop/c1.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#先找出角点
gray=np.float32(gray)
dst=cv2.cornerHarris(gray,3,3,0.04)
dst=cv2.dilate(dst,None)
ret,dst=cv2.threshold(dst,0.01*dst.max(),255,0)
dst=np.uint8(dst)
#cv2.connectedComponentsWithStats函数是opencv3新出的一个函数,作用是连接#图像内部的缺口使之成为一个整体(对比新旧函数,用于过滤原始图像中轮廓分析后较小的区域,留下较大区域)
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)
#hstack按照列顺序堆叠数组,同理vstack是行顺序
res=np.hstack((centroids,corners)
#int0可以省略小数点后面的数字
res=np.int0(res)
#虽然res是4列的但是还不清楚为什莫这样标记
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]]=[0,255,0]
b,g,r=cv2.split(img)
img2=cv2.merge([r,g,b])
plt.imshow(img2)