有勇气的牛排博客

深入浅出 OpenCV-Contrib-Python:实用教程与应用案例

有勇气的牛排 610 Python 2024-12-02 22:41:28

1 前言

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它提供了丰富的功能,可以处理图像和视频数据,广泛应用于计算机视觉领域的项目中,例如人脸识别、目标检测、图像增强和视频处理。

中文文档:

opencv-contrib-python==4.8.0.74 # cv2 numpy==1.24.2

2 基础属性demo

打开一张图片:

import cv2 img = cv2.imread('./girl.jpg') print(img.shape) # (1536, 1024, 3) 数组形状 print(type(img)) # numpy 数组 print(img) # 三维数组(彩色图片:高度、宽度、像素红绿蓝[蓝0, 绿1, 红2]) cv2.waitKey() # 等待键盘任意输入,然后窗口消失 cv2.destroyAllWindows() # 销毁内存

4 颜色

在OpenCV中有超过150种颜色转换的方法,常用的有 BGR↔Gray 和 BGR↔HSV。

4.1 Gray 灰度处理

# 黑白图片/灰度化处理 # cv2.COLOR_BGR2GRAY gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imshow('gray', gray)

4.2 HSV 颜色空间

RGB适用于显示系统;

HSV适用于图像处理(物体跟踪)。

属性 取值范围
H(色彩/色度) [0, 179]
S(饱和度) [0, 255]
V(亮度) [0, 255]

注意:不同软件取值可能不同。

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) cv2.imshow('hsv', hsv)

4.3 颜色调整&翻转

# 颜色翻转 # 颜色翻转 img[:, :, ::-1] cv2.imshow("girl老铁", img[:, :, ::-1]) # 三原色调整 cv2.imshow("girl老铁", img[:, :, [0, 2, 1]])

4.4 物体跟踪(蓝色物体周围画一个圈)

import cv2 import numpy as np img = cv2.imread('./url.png') cv2.imshow('img', img) # HSV 在物体跟踪时比较有效 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 颜色空间转变 # cv2.imshow('hsv', hsv) # 定义在HSV颜色空间中的 蓝色 范围 lower_blue = np.array([110, 50, 50]) # 浅蓝 upper_blue = np.array([130, 255, 255]) # 深蓝 # 根据蓝色的范围,标记图片中哪些位置是蓝色 # 在范围内标记为1,不在标记为0 mask = cv2.inRange(hsv, lower_blue, upper_blue) # 位运算 res = cv2.bitwise_and(img, img, mask=mask) cv2.imshow('res', res) # 0:无限等待 cv2.waitKey(3000) # 无操作,2s后自动消失 cv2.destroyAllWindows() # 销毁内存

image.png

5 大小与位置

5.1 翻转

# 上下翻转 img[::-1, :, :] cv2.imshow("girl老铁", img[::-1, :, :]) # 上下翻转 弹出窗口(文字只能是英文)

6 图片马赛克

6.1 缩小->放大拉伸

这种方式,可以理解为模糊化

img2 = cv2.resize(img, (30, 16)) img3 = cv2.resize(img2, (240, 128))

image.png

6.2 缩小,放大比例

img2 = cv2.resize(img, (100, 100)) # 先缩小 img3 = np.repeat(img2, 5, axis=1) # x轴 放大10倍 img4 = np.repeat(img3, 5, axis=0) # y轴 放大10倍

image.png

6.3 像素抽取

每10个中 取一个像素

import cv2 img = cv2.imread("./img/girl2.png") print(img.shape) # 宽512、高512 img2 = img[::10, ::10] # 每10个中 取一个像素 # 由于图片比较小,我们加入下面2行代码,放大窗口 cv2.namedWindow("girl", flags=cv2.WINDOW_NORMAL) cv2.resizeWindow("girl", 512, 512) cv2.imshow('girl', img2) cv2.waitKey(0) cv2.destroyAllWindows()

image20230823155511821.png

7 人脸操作

7.1 人脸检测

下载特征文件:

https://github.com/opencv/opencv/tree/4.x/data/haarcascades

data/haarcascades/haarcascade_frontalface_alt.xml

# -*- coding:utf-8 -*- """ @Author :有勇气的牛排 @FileName : 06 人脸检测.py @desc : 描述 """ import cv2 img = cv2.imread("./img/girls2.png") # 加载 人脸 特征文件(opencv库貌似自带) face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml") # 识别人脸,并且获取坐标:x、y、w、h """ [[744 100 142 142] [205 165 153 153]] """ faces = face_detector.detectMultiScale(img) print(faces) for x, y, w, h in faces: # 绘制 矩形 """ pt1: 左上角 pt2: 左下角 thickness: 线条粗细 """ cv2.rectangle(img, pt1=(x, y), pt2=(x + w, y + h), color=[0, 0, 255], thickness=2) cv2.imshow("girl", img) cv2.waitKey(0) cv2.destroyAllWindows()

image.png

优化:

  • 黑白色更容易识别
  • 识别效果系数整
# -*- coding:utf-8 -*- """ @Author :有勇气的牛排 @FileName : 06 人脸检测.py @desc : 描述 """ import cv2 img = cv2.imread("./img/hezhao.png") # 图片 改为 黑白色,识别更友好(数据更少) gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY) # 加载 人脸 特征文件(opencv库貌似自带) face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml") # 识别人脸,并且获取坐标:x、y、w、h """ [[744 100 142 142] [205 165 153 153]] scaleFactor: 缩放 倍数 -> 放大缩小 判断是否是人脸 scaleFactor: 坐标 x、y、w、h """ faces = face_detector.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=3) print(faces) for x, y, w, h in faces: # 绘制 矩形 """ pt1: 左上角 pt2: 左下角 thickness: 线条粗细 """ # cv2.rectangle(img, # pt1=(x, y), # pt2=(x + w, y + h), # color=[0, 0, 255], # thickness=2) # 画圆圈 cv2.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0, 255, 0], thickness=2) cv2.imshow("girl", img) cv2.waitKey(0) cv2.destroyAllWindows()

image.png

7.2 人脸 马赛克

# -*- coding:utf-8 -*- """ @Author :有勇气的牛排 @FileName : 07 人脸 马赛克.py @desc : 描述 """ import cv2 import numpy as np img = cv2.imread("./img/girl2.png") # 图片 改为 黑白色,识别更友好(数据更少) gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY) # 加载 人脸 特征文件(opencv库貌似自带) face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml") # 识别人脸,并且获取坐标:x、y、w、h faces = face_detector.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=3) """ 187 89 152 152 人脸1: 左上角 坐标:(187, 89) 右下角 坐标:(339, 241) """ for x, y, w, h in faces: # cv2.rectangle(img, # pt1=(x, y), # pt2=(x + w, y + h), # color=[0, 0, 255], # thickness=2) print(x, y, w, h) # 获取人脸区域 切片 face = img[y:y + h, x:x + w] # img[y:y+h, x:x+w] = face[:, :, ::-1] # 脸部区域 变色 测试 # 人脸 马赛克,切片 face = face[::10, ::10] # 每10个中取一个像素 face = np.repeat(face, 10, axis=0) # 高 --- 行 face = np.repeat(face, 10, axis=1) # 宽 --- 列 # 将马赛克区域 尺寸矫正 img[y:y + h, x:x + w] = face[:152, :152] cv2.imshow("girl", img) cv2.waitKey(0) cv2.destroyAllWindows()

image.png

7.3 人脸加贴纸

for x, y, w, h in faces: cv2.rectangle(img, pt1=(x, y), pt2=(x + w, y + h), color=[0, 0, 255], thickness=2) print(x, y, w, h) # 填满整个脸 # img[y:y+h, x:x+w] = cv2.resize(sticker, (w, h)) # 脸部1/4 左上角 # img[y:y+h//2, x:x+w//2] = cv2.resize(sticker, (w//2, h//2)) # 居中 img[y:y+h//2, x+30:x+w//2+30] = cv2.resize(sticker, (w // 2, h // 2))

image.png


留言

专栏
文章
加入群聊