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 灰度处理
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 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
res = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow('res', res)
cv2.waitKey(3000)
cv2.destroyAllWindows()

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))

6.2 缩小,放大比例
img2 = cv2.resize(img, (100, 100))
img3 = np.repeat(img2, 5, axis=1)
img4 = np.repeat(img3, 5, axis=0)

6.3 像素抽取
每10个中 取一个像素
import cv2
img = cv2.imread("./img/girl2.png")
print(img.shape)
img2 = img[::10, ::10]
cv2.namedWindow("girl", flags=cv2.WINDOW_NORMAL)
cv2.resizeWindow("girl", 512, 512)
cv2.imshow('girl', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

7 人脸操作
7.1 人脸检测
下载特征文件:
https://github.com/opencv/opencv/tree/4.x/data/haarcascades
data/haarcascades/haarcascade_frontalface_alt.xml
"""
@Author :有勇气的牛排
@FileName : 06 人脸检测.py
@desc : 描述
"""
import cv2
img = cv2.imread("./img/girls2.png")
face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml")
"""
[[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()

优化:
"""
@Author :有勇气的牛排
@FileName : 06 人脸检测.py
@desc : 描述
"""
import cv2
img = cv2.imread("./img/hezhao.png")
gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml")
"""
[[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.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()

7.2 人脸 马赛克
"""
@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)
face_detector = cv2.CascadeClassifier("./static/haarcascade_frontalface_alt.xml")
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:
print(x, y, w, h)
face = img[y:y + h, x:x + w]
face = face[::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()

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//2, x+30:x+w//2+30] = cv2.resize(sticker, (w // 2, h // 2))

<h2><a id="1__0"></a>1 前言</h2>
<p>OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它提供了丰富的功能,可以处理图像和视频数据,广泛应用于计算机视觉领域的项目中,例如人脸识别、目标检测、图像增强和视频处理。</p>
<p>中文文档:</p>
<pre><div class="hljs"><code class="lang-shell">opencv-contrib-python==4.8.0.74 # cv2
numpy==1.24.2
</code></div></pre>
<h2><a id="2_demo_11"></a>2 基础属性demo</h2>
<p>打开一张图片:</p>
<pre><div class="hljs"><code class="lang-shell">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() # 销毁内存
</code></div></pre>
<h2><a id="4__33"></a>4 颜色</h2>
<p>在OpenCV中有超过150种颜色转换的方法,常用的有 BGR↔Gray 和 BGR↔HSV。</p>
<h3><a id="41_Gray__37"></a>4.1 Gray 灰度处理</h3>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-comment"># 黑白图片/灰度化处理</span>
<span class="hljs-comment"># cv2.COLOR_BGR2GRAY</span>
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow(<span class="hljs-string">'gray'</span>, gray)
</code></div></pre>
<h3><a id="42_HSV__46"></a>4.2 HSV 颜色空间</h3>
<p>RGB适用于显示系统;</p>
<p>HSV适用于图像处理(物体跟踪)。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>取值范围</th>
</tr>
</thead>
<tbody>
<tr>
<td>H(色彩/色度)</td>
<td>[0, 179]</td>
</tr>
<tr>
<td>S(饱和度)</td>
<td>[0, 255]</td>
</tr>
<tr>
<td>V(亮度)</td>
<td>[0, 255]</td>
</tr>
</tbody>
</table>
<p>注意:不同软件取值可能不同。</p>
<pre><div class="hljs"><code class="lang-shell">hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)
</code></div></pre>
<h3><a id="43__65"></a>4.3 颜色调整&翻转</h3>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">颜色翻转</span>
<span class="hljs-meta"># </span><span class="language-bash">颜色翻转 img[:, :, ::-1]</span>
cv2.imshow("girl老铁", img[:, :, ::-1])
<span class="hljs-meta">
# </span><span class="language-bash">三原色调整</span>
cv2.imshow("girl老铁", img[:, :, [0, 2, 1]])
</code></div></pre>
<h3><a id="44__78"></a>4.4 物体跟踪(蓝色物体周围画一个圈)</h3>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-keyword">import</span> cv2
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
img = cv2.imread(<span class="hljs-string">'./url.png'</span>)
cv2.imshow(<span class="hljs-string">'img'</span>, img)
<span class="hljs-comment"># HSV 在物体跟踪时比较有效</span>
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) <span class="hljs-comment"># 颜色空间转变</span>
<span class="hljs-comment"># cv2.imshow('hsv', hsv)</span>
<span class="hljs-comment"># 定义在HSV颜色空间中的 蓝色 范围</span>
lower_blue = np.array([<span class="hljs-number">110</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>]) <span class="hljs-comment"># 浅蓝</span>
upper_blue = np.array([<span class="hljs-number">130</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>]) <span class="hljs-comment"># 深蓝</span>
<span class="hljs-comment"># 根据蓝色的范围,标记图片中哪些位置是蓝色</span>
<span class="hljs-comment"># 在范围内标记为1,不在标记为0</span>
mask = cv2.inRange(hsv, lower_blue, upper_blue)
<span class="hljs-comment"># 位运算</span>
res = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow(<span class="hljs-string">'res'</span>, res)
<span class="hljs-comment"># 0:无限等待</span>
cv2.waitKey(<span class="hljs-number">3000</span>) <span class="hljs-comment"># 无操作,2s后自动消失</span>
cv2.destroyAllWindows() <span class="hljs-comment"># 销毁内存</span>
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/501ff22b6b2bc082bda2b71bab13a956.png" alt="image.png" /></p>
<h2><a id="5__108"></a>5 大小与位置</h2>
<h3><a id="51__110"></a>5.1 翻转</h3>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">上下翻转 img[::-1, :, :]</span>
cv2.imshow("girl老铁", img[::-1, :, :]) # 上下翻转 弹出窗口(文字只能是英文)
</code></div></pre>
<h2><a id="6__119"></a>6 图片马赛克</h2>
<h3><a id="61_gt_121"></a>6.1 缩小->放大拉伸</h3>
<p>这种方式,可以理解为模糊化</p>
<pre><div class="hljs"><code class="lang-python">img2 = cv2.resize(img, (<span class="hljs-number">30</span>, <span class="hljs-number">16</span>))
img3 = cv2.resize(img2, (<span class="hljs-number">240</span>, <span class="hljs-number">128</span>))
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/e5441b76be976728e3d659a82a60f14b.png" alt="image.png" /></p>
<h3><a id="62__134"></a>6.2 缩小,放大比例</h3>
<pre><div class="hljs"><code class="lang-python">img2 = cv2.resize(img, (<span class="hljs-number">100</span>, <span class="hljs-number">100</span>)) <span class="hljs-comment"># 先缩小</span>
img3 = np.repeat(img2, <span class="hljs-number">5</span>, axis=<span class="hljs-number">1</span>) <span class="hljs-comment"># x轴 放大10倍</span>
img4 = np.repeat(img3, <span class="hljs-number">5</span>, axis=<span class="hljs-number">0</span>) <span class="hljs-comment"># y轴 放大10倍</span>
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/9c930d47aeaa152b9f9d369081e68a73.png" alt="image.png" /></p>
<h3><a id="63__148"></a>6.3 像素抽取</h3>
<p>每10个中 取一个像素</p>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-keyword">import</span> cv2
img = cv2.imread(<span class="hljs-string">"./img/girl2.png"</span>)
<span class="hljs-built_in">print</span>(img.shape) <span class="hljs-comment"># 宽512、高512</span>
img2 = img[::<span class="hljs-number">10</span>, ::<span class="hljs-number">10</span>] <span class="hljs-comment"># 每10个中 取一个像素</span>
<span class="hljs-comment"># 由于图片比较小,我们加入下面2行代码,放大窗口</span>
cv2.namedWindow(<span class="hljs-string">"girl"</span>, flags=cv2.WINDOW_NORMAL)
cv2.resizeWindow(<span class="hljs-string">"girl"</span>, <span class="hljs-number">512</span>, <span class="hljs-number">512</span>)
cv2.imshow(<span class="hljs-string">'girl'</span>, img2)
cv2.waitKey(<span class="hljs-number">0</span>)
cv2.destroyAllWindows()
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/7d8e06f1724e2eda40d7be5b39622b51.png" alt="image20230823155511821.png" /></p>
<h2><a id="7__174"></a>7 人脸操作</h2>
<h3><a id="71__176"></a>7.1 人脸检测</h3>
<p>下载特征文件:</p>
<p>https://github.com/opencv/opencv/tree/4.x/data/haarcascades</p>
<p><code>data/haarcascades/haarcascade_frontalface_alt.xml</code></p>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-comment"># -*- coding:utf-8 -*-</span>
<span class="hljs-string">"""
@Author :有勇气的牛排
@FileName : 06 人脸检测.py
@desc : 描述
"""</span>
<span class="hljs-keyword">import</span> cv2
img = cv2.imread(<span class="hljs-string">"./img/girls2.png"</span>)
<span class="hljs-comment"># 加载 人脸 特征文件(opencv库貌似自带)</span>
face_detector = cv2.CascadeClassifier(<span class="hljs-string">"./static/haarcascade_frontalface_alt.xml"</span>)
<span class="hljs-comment"># 识别人脸,并且获取坐标:x、y、w、h</span>
<span class="hljs-string">"""
[[744 100 142 142]
[205 165 153 153]]
"""</span>
faces = face_detector.detectMultiScale(img)
<span class="hljs-built_in">print</span>(faces)
<span class="hljs-keyword">for</span> x, y, w, h <span class="hljs-keyword">in</span> faces:
<span class="hljs-comment"># 绘制 矩形</span>
<span class="hljs-string">"""
pt1: 左上角
pt2: 左下角
thickness: 线条粗细
"""</span>
cv2.rectangle(img,
pt1=(x, y),
pt2=(x + w, y + h),
color=[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">255</span>],
thickness=<span class="hljs-number">2</span>)
cv2.imshow(<span class="hljs-string">"girl"</span>, img)
cv2.waitKey(<span class="hljs-number">0</span>)
cv2.destroyAllWindows()
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/a1d3463f7e2614d6b569d17b157fafb5.png" alt="image.png" /></p>
<p>优化:</p>
<ul>
<li>黑白色更容易识别</li>
<li>识别效果系数整</li>
</ul>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-comment"># -*- coding:utf-8 -*-</span>
<span class="hljs-string">"""
@Author :有勇气的牛排
@FileName : 06 人脸检测.py
@desc : 描述
"""</span>
<span class="hljs-keyword">import</span> cv2
img = cv2.imread(<span class="hljs-string">"./img/hezhao.png"</span>)
<span class="hljs-comment"># 图片 改为 黑白色,识别更友好(数据更少)</span>
gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
<span class="hljs-comment"># 加载 人脸 特征文件(opencv库貌似自带)</span>
face_detector = cv2.CascadeClassifier(<span class="hljs-string">"./static/haarcascade_frontalface_alt.xml"</span>)
<span class="hljs-comment"># 识别人脸,并且获取坐标:x、y、w、h</span>
<span class="hljs-string">"""
[[744 100 142 142]
[205 165 153 153]]
scaleFactor: 缩放 倍数 -> 放大缩小 判断是否是人脸
scaleFactor: 坐标 x、y、w、h
"""</span>
faces = face_detector.detectMultiScale(gray,
scaleFactor=<span class="hljs-number">1.05</span>,
minNeighbors=<span class="hljs-number">3</span>)
<span class="hljs-built_in">print</span>(faces)
<span class="hljs-keyword">for</span> x, y, w, h <span class="hljs-keyword">in</span> faces:
<span class="hljs-comment"># 绘制 矩形</span>
<span class="hljs-string">"""
pt1: 左上角
pt2: 左下角
thickness: 线条粗细
"""</span>
<span class="hljs-comment"># cv2.rectangle(img,</span>
<span class="hljs-comment"># pt1=(x, y),</span>
<span class="hljs-comment"># pt2=(x + w, y + h),</span>
<span class="hljs-comment"># color=[0, 0, 255],</span>
<span class="hljs-comment"># thickness=2)</span>
<span class="hljs-comment"># 画圆圈</span>
cv2.circle(img,
center=(x+w//<span class="hljs-number">2</span>, y+h//<span class="hljs-number">2</span>),
radius=w//<span class="hljs-number">2</span>,
color=[<span class="hljs-number">0</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0</span>],
thickness=<span class="hljs-number">2</span>)
cv2.imshow(<span class="hljs-string">"girl"</span>, img)
cv2.waitKey(<span class="hljs-number">0</span>)
cv2.destroyAllWindows()
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/8e4de573866b186e6e9dd3cb6c5b9384.png" alt="image.png" /></p>
<h3><a id="72____289"></a>7.2 人脸 马赛克</h3>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-comment"># -*- coding:utf-8 -*-</span>
<span class="hljs-string">"""
@Author :有勇气的牛排
@FileName : 07 人脸 马赛克.py
@desc : 描述
"""</span>
<span class="hljs-keyword">import</span> cv2
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
img = cv2.imread(<span class="hljs-string">"./img/girl2.png"</span>)
<span class="hljs-comment"># 图片 改为 黑白色,识别更友好(数据更少)</span>
gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
<span class="hljs-comment"># 加载 人脸 特征文件(opencv库貌似自带)</span>
face_detector = cv2.CascadeClassifier(<span class="hljs-string">"./static/haarcascade_frontalface_alt.xml"</span>)
<span class="hljs-comment"># 识别人脸,并且获取坐标:x、y、w、h</span>
faces = face_detector.detectMultiScale(gray,
scaleFactor=<span class="hljs-number">1.05</span>,
minNeighbors=<span class="hljs-number">3</span>)
<span class="hljs-string">"""
187 89 152 152
人脸1:
左上角 坐标:(187, 89)
右下角 坐标:(339, 241)
"""</span>
<span class="hljs-keyword">for</span> x, y, w, h <span class="hljs-keyword">in</span> faces:
<span class="hljs-comment"># cv2.rectangle(img,</span>
<span class="hljs-comment"># pt1=(x, y),</span>
<span class="hljs-comment"># pt2=(x + w, y + h),</span>
<span class="hljs-comment"># color=[0, 0, 255],</span>
<span class="hljs-comment"># thickness=2)</span>
<span class="hljs-built_in">print</span>(x, y, w, h)
<span class="hljs-comment"># 获取人脸区域 切片</span>
face = img[y:y + h, x:x + w]
<span class="hljs-comment"># img[y:y+h, x:x+w] = face[:, :, ::-1] # 脸部区域 变色 测试</span>
<span class="hljs-comment"># 人脸 马赛克,切片</span>
face = face[::<span class="hljs-number">10</span>, ::<span class="hljs-number">10</span>] <span class="hljs-comment"># 每10个中取一个像素</span>
face = np.repeat(face, <span class="hljs-number">10</span>, axis=<span class="hljs-number">0</span>) <span class="hljs-comment"># 高 --- 行</span>
face = np.repeat(face, <span class="hljs-number">10</span>, axis=<span class="hljs-number">1</span>) <span class="hljs-comment"># 宽 --- 列</span>
<span class="hljs-comment"># 将马赛克区域 尺寸矫正</span>
img[y:y + h, x:x + w] = face[:<span class="hljs-number">152</span>, :<span class="hljs-number">152</span>]
cv2.imshow(<span class="hljs-string">"girl"</span>, img)
cv2.waitKey(<span class="hljs-number">0</span>)
cv2.destroyAllWindows()
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/626831c5127e27f0814045285b98f904.png" alt="image.png" /></p>
<h3><a id="73__351"></a>7.3 人脸加贴纸</h3>
<pre><div class="hljs"><code class="lang-python"><span class="hljs-keyword">for</span> x, y, w, h <span class="hljs-keyword">in</span> faces:
cv2.rectangle(img,
pt1=(x, y),
pt2=(x + w, y + h),
color=[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">255</span>],
thickness=<span class="hljs-number">2</span>)
<span class="hljs-built_in">print</span>(x, y, w, h)
<span class="hljs-comment"># 填满整个脸</span>
<span class="hljs-comment"># img[y:y+h, x:x+w] = cv2.resize(sticker, (w, h))</span>
<span class="hljs-comment"># 脸部1/4 左上角</span>
<span class="hljs-comment"># img[y:y+h//2, x:x+w//2] = cv2.resize(sticker, (w//2, h//2))</span>
<span class="hljs-comment"># 居中</span>
img[y:y+h//<span class="hljs-number">2</span>, x+<span class="hljs-number">30</span>:x+w//<span class="hljs-number">2</span>+<span class="hljs-number">30</span>] = cv2.resize(sticker, (w // <span class="hljs-number">2</span>, h // <span class="hljs-number">2</span>))
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/2654170ee5e14997d80053ddfcf7b7c7.png" alt="image.png" /></p>
留言