算法介绍
Harris角点检测算法:
是一种常用的计算机视觉算法,用于检测图像中的角点。该算法通过计算图像中每个像素的局部自相关矩阵,来判断该像素是否为角点。
角点检测算法的基本思想:
使用一个固定的小窗口在图像上进行任意方向的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化(sobel算子),那么我们可以认为该窗口中存在角点。
# cornerHarris(img,blockSize,ksize,k[,dst[,borderType]]) -> dst
# img:输入图像
# blockSize:角点检测中要考虑的领域大小
# ksize:Sobel求导中使用的窗口大小
# k: Harris角点检测方程中的自由参数,取值参数为[0.04,0.06],算法中的参数。
## dst: 返回numpy.ndarray对象,大小和src相同,值越大,对应像素点是角的概率越高
代码示例
#导入工具包
import cv2
import numpy as np
import argparse #args()函数
#设置参数,通过命令参数传入需要处理的图片,-i 图片路径
ap=argparse.ArgumentParser(description="Description of your program")#创建了一个命令参数对象
ap.add_argument("-i","--image",required=True,
help="Path to the to be scanned")# 添加命令数据
args = ap.parse_args()# 解析命令行参数
args=vars(ap.parse_args())# 把命令解压为字典
#函数定义
def cv_show(name,img):#绘图展示
cv2.imshow(name,img)
cv2.waitKey(0)
def resize(image,width=None,height=None,inter=cv2.INTER_AREA):
dim=None
(h,w)=image.shape[:2]
if width is None and height is None:
return image
if width is None:
r=height/float(h)
dim=(int(w*r),height)
else:
r=width/float(w)
dim=(width,int(h*r))
resized=cv2.resize(image,dim,interpolation=inter)
return resized
img = cv2.imread('fapiao.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray,4,3,0.04)
print(dst)
a = dst>0.05*dst.max()
img[dst>0.05*dst.max()] = [0,255,0] #像图像中填充内容。0.05是认为控制的
# cv2.imshow('gray',gray)
# cv2.waitKey(0)
cv2.imshow('img',img)
cv2.waitKey(0)
#读取输入
image=cv2.imread(args["image"])
cv2.namedWindow("image",cv2.WINDOW_NORMAL) #改变窗口函数,自动改变窗口大小
cv_show('image',image)
#图片过大,进行缩小处理
ratio=image.shape[0] / 500.0 #计算缩小比率
orig = image.copy()
image=resize(orig,height=500)
#轮廓检测
print("STEP 1:轮廓检测")
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #读取灰度图
edged=cv2.threshold(gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] #自动寻找阈值二值化
cnts = cv2.findContours(edged.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[1]
image_contours=cv2.drawContours(image.copy(),cnts,-1,(0,0,255),1)
cv_show('image_contours',image_contours)
print("STEP 2:获取最大轮廓")
screenCnt=sorted(cnts,key=cv2.contourArea,reverse=True)[0] # 获取面积最大的轮廓
peri=cv2.arcLength(screenCnt,True) # 计算轮廓周长
screenCnt=cv2.approxPolyDP(screenCnt,0.02*peri,True) # 轮廓近似
image_contour=cv2.drawContours(image.copy(),[screenCnt],-1,(0,255,0),2)
cv_show('image_contour',image_contour)
执行结果
dst:每一个像素进行检测的结果保存在dst里里面