HOG方向梯度直方图
实现过程:
import cv2
import numpy as np
# 判断矩形i是否完全包含在矩形o中
def is_inside(o, i):
ox, oy, ow, oh = 0
ix, iy, iw, ih = i
return ox > ix and oy > iy and ox+ow < ix+iw and oy+oh < iy+ih
# 对人体绘制颜色框
def draw_person(image, person):
x, y, w, h = person
cv2.rectangle(image, (x,y), (x+w, y+h), (0,0,255), 1)
img = cv2.imread("person.png")
hog = cv2.HOGDescriptor() # 启动检测器对象
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) # 指定检测器类型为人体
found, w = hog.detectMultiScale(img, 0.1, (1,1)) # 加载并检测对象
print(found)
# 丢弃某些完全被其它矩形包含在内的矩形,即其他都加入队列里
found_filtered = []
for ri, r in enumerate(found):
for qi, q in enumerate(found):
if ri != qi and is_inside(r, q):
break
else:
found_filtered.append(r)
print(found_filtered)
# 对其他有效矩形进行框定
for person in person_filtered:
draw_person(img, person)
cv2.imshow("person detection", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
实现过程:
import cv2
import numpy as np
img = cv2.imread("img.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray) # 转换成numpy矩阵
# 输入图像必须是float32,blockSize,kernelsize,最后一个自由参数
#(经验取值在0.03~0.06之间)
dst = cv2.cornerHarris(gray, 2, 3, 0.03)
# 设定角点阈值,不同图像阈值不同
# 将角点用红色标注
img[dst>0.01*dst.max()]=[0, 0, 255]
# print(dst.max()) # 533091900.0
cv2.imshow("dst_img",img)
cv2.waitKey(0)
cv2.destryAllWindows()
角点检测:
在原图上进行角点标注:
可以对角点进行膨胀,看得更清楚:dst = cv2.dilate(dst,None)
Scale-invariant feature transform, 尺度不变特征变换算法
实现过程:
OpenCV > 4.0受到专利限制移除了xfeatures2d
函数
import cv2
import numpy as np
img = cv2.imread("1.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray, None) # 找到关键点
img = cv2.drawKeypoints(gray, kp, img) # 绘制关键点
cv2.imshow('sp', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Local Binary Pattern, 局部二值模式
LBP算子定义在3X3的窗口内,以窗口中心为阈值,与相邻的8个像素的灰度值比较,若周围的像素值大于中心像素值,则该位置被标为1;否则标记为0。
def LBP(src):
height = src.shape[0]
width = src.shape[1]
dst = src.copy() # 浅拷贝
lbp_value = np.zeros((1, 8), dtype=np.uint8)
neighbours = np.zeros((1, 8), dtype=np.uint8)
for x in range(1, width-1):
for y in range(1, height-1):
neighbours[0, 0] = src[y - 1, x - 1]
neighbours[0, 1] = src[y - 1, x]
neighbours[0, 2] = src[y - 1, x + 1]
neighbours[0, 3] = src[y, x - 1]
neighbours[0, 4] = src[y, x + 1]
neighbours[0, 5] = src[y + 1, x - 1]
neighbours[0, 6] = src[y + 1, x]
neighbours[0, 7] = src[y + 1, x + 1]
center = src[y, x]
for i in range(8):
if neighbours[0, i] > center:
lbp_value[0, i] = 1
else:
lbp_value[0, i] = 0
# 计算lbp值(即二进制到十进制)
lbp = lbp_value[0, 0] * 1 + lbp_value[0, 1] * 2 + lbp_value[0, 2] * 4 + lbp_value[0, 3] * 8 \
+ lbp_value[0, 4] * 16 + lbp_value[0, 5] * 32 + lbp_value[0, 6] * 64 + lbp_value[0, 7] * 128
# 将中心值改为lbp值
dst[y, x] = lbp
return dst
import cv2
import numpy as np
img = cv2.imread('building.png', 0) # 以单通道读入图像
# 看下源图
cv2.imshow('src',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
new_img = LBP(img)
cv2.imshow('lbp',new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
一个完整的人脸识别系统一般包含4个主要组成部分:
Face Detect
Face Alignment
Face Feature Extraction
Face Recognition
import cv2
img = cv2.imread("1.png")
# 检测器,加载人脸特征(该文件在python安装目录下)
face_cascade = cv2.CascadeClassifier(r'haaracascade_frontalface_default.xml')
# 灰度图减少计算强度(避免颜色干扰)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测的一个人脸坐标[x,y,w,h]是一个list,所以list的数量就是人脸数量
faces = face_cascade.detectMultiScale(gray, scaleFactor = 1.15, minNeighbors = 4, minSize = (5, 5))
print("Faces:{0}".format(len(faces)))
# 用矩形圈出人脸的位置(提供左上角和右下角坐标)
for(x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow("Faces", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Face : 1
通过其他照片的试验,OpenCV自带的方法和dilb对于标准正脸检测OK的,但是对于侧脸(不同角度)以及低像素基本完全不OK
# -*- coding:utf-8 -*-
import cv2
import dlib
import numpy as np
predictor_model = 'shape_predictor_68_face_landmarks/shape_predictor_68_face_landmarks.dat'
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_model)
dlib库没办法直接pip安装
找python3.8对应的dlib的轮子找了好一会儿,放百度盘了需要自取
许多博客尤其是
CSDN,免费开源的放自己文章里收费,很不友好,目前还是习惯在这里记一些流水帐笔记