本文为9月10日OpenCV学习笔记——Mask、彩色直方图、人脸检测,分为五个章节:
提取感兴趣的区域。
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# 方法:显示图片
def show_image(image, title, pos):
img_RGB = image[:, :, ::-1] # BGR to RGB
plt.title(title)
plt.subplot(2, 2, pos)
plt.imshow(img_RGB)
# 方法:显示灰度直方图
def show_histogram(hist, title, pos, color):
plt.subplot(2, 2, pos)
plt.title(title)
plt.xlim([0, 256])
plt.plot(hist, color=color)
# 主函数
def main():
# 创建一个画布
plt.figure(figsize=(12, 7))
plt.suptitle("Gray Image and Histogram with mask", fontsize=14, fontweight="bold")
# 加载图片并转成灰度,计算直方图、显示
img_gray = cv.imread("images/vonmises.png", cv.COLOR_BGR2GRAY)
img_gray_hist = cv.calcHist([img_gray], [0], None, [256], [0, 256]) # 计算直方图
show_image(img_gray, "image gray", 1)
show_histogram(img_gray_hist, "image gray histogram", 2, "m")
# 创建 mask,计算位图,直方图
mask = np.zeros(img_gray.shape[:2], np.uint8)
mask[130:500, 300:700] = 255 # 获取 mask,并赋予颜色
img_mask_hist = cv.calcHist([img_gray], [0], mask, [256], [0, 256]) # 计算 mask 直方图
# 通过与运算计算带有 mask 的灰度图片
mask_img = cv.bitwise_and(img_gray, img_gray, mask=mask)
# 显示带有 mask 的图片和直方图
show_image(mask_img, "gray image with mask", 3)
show_histogram(img_mask_hist, "histogram with masked gray image", 4, "m")
plt.show()
if __name__ == '__main__':
main()
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# 方法:显示图片
def show_image(image, title, pos):
plt.subplot(3, 2, pos)
plt.title(title)
image_RGB = image[:, :, ::-1] # BGR to RGB
plt.imshow(image_RGB)
plt.axis("off")
# 方法:显示彩色直方图
def show_histogram(hist, title, pos, color):
plt.subplot(3, 2, pos)
plt.title(title)
plt.xlim([0, 256])
for h, c in zip(hist, color): # color: ('b', 'g', 'r')
plt.plot(h, color=c)
# 方法:计算直方图
def calc_color_hist(image):
# b, g, r
hist = []
color = ('b', 'g', 'r')
# print(tuple(enumerate(color)))
for i, _ in enumerate(color): # list(enumerate) ==> [(0, 'b'), (1, 'g'), (2, 'r')]
hist.append(cv.calcHist([image], [i], None, [256], [0, 256]))
return hist
# 主函数
def main():
# 创建画布
plt.figure(figsize=(12, 8))
plt.suptitle("Color Histogram", fontsize=14, fontweight="bold")
# 读取原图片
img = cv.imread("./images/vonmises.png")
# 计算直方图
img_hist = calc_color_hist(img)
# 显示图片和直方图
show_image(img, "RGB Image", 1)
show_histogram(img_hist, "RGB Image Hist", 2, ('b', 'g', 'r'))
# 原始图片中的每个像素增加 50个像素值
M = np.ones(img.shape, dtype="uint8") * 50
added_image = cv.add(img, M)
added_image_hist = calc_color_hist(added_image)
show_image(added_image, "Added Image", 3)
show_histogram(added_image_hist, "Added Image Hist", 4, ('b', 'g', 'r'))
# 原始图片中的每个像素减少 50个像素值
subtracted_img = cv.subtract(img, M)
subtracted_img_hist = calc_color_hist(subtracted_img)
show_histogram(subtracted_img, "Subtracted Image", 5, ('b', 'g', 'r'))
show_histogram(subtracted_img_hist, "Subtracted Image Hist", 6, ('b', 'g', 'r'))
plt.show()
if __name__ == '__main__':
main()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 定义颜色(字典形式)
colors = {'blue': (255, 0, 0),
'green': (0, 255, 0),
'red': (0, 0, 255),
'yellow': (0, 255, 255),
'magenta': (255, 0, 255),
'cyan': (255, 255, 0),
'white': (255, 255, 255),
'black': (0, 0, 0),
'gray': (125, 125, 125),
'rand': np.random.randint(0, high=256, size=(3, )).tolist(),
'dark_gray': (50, 50, 50),
'light_gray': (220, 220, 220)}
# 方法:显示图片
def show_image(image, title):
img_RGB = image[:, :, ::-1] # BGR to RGB
plt.title(title)
plt.imshow(img_RGB)
plt.show()
# 创建画布
canvas = np.zeros((400, 400, 3), np.uint8) # 默认背景是黑色
canvas[:] = colors["white"]
show_image(canvas, "Background")
# 画直线 cv.line()
cv.line(canvas, (0, 0), (400, 400), colors['green'], 5)
cv.line(canvas, (0, 400), (400, 0), colors['black'], 5)
show_image(canvas, "cv.line()")
cv.rectangle(canvas, (10, 20), (70, 120), colors['green'], 3)
cv.rectangle(canvas, (150, 50), (200, 300), colors['blue'], -1) # -1: 填充
show_image(canvas, "cv.rectangle()")
cv.circle(canvas, (200, 200), 150, colors["black"], 3)
cv.circle(canvas, (200, 200), 50, colors["green"], -1)
show_image(canvas, "cv.circle()")
pts = np.array([[250, 5], [220, 80], [280, 80]], np.int32)
pts = pts.reshape((-1, 1, 2))
cv.polylines(canvas, [pts], True, colors["green"], 3)
pts2 = np.array([[150, 200], [90, 130], [280, 180]], np.int32)
pts2 = pts2.reshape([-1, 1, 2])
cv.polylines(canvas, [pts2], False, colors['black'], 5)
show_image(canvas, "cv.polylines")
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 定义颜色(字典形式)
colors = {'blue': (255, 0, 0),
'green': (0, 255, 0),
'red': (0, 0, 255),
'yellow': (0, 255, 255),
'magenta': (255, 0, 255),
'cyan': (255, 255, 0),
'white': (255, 255, 255),
'black': (0, 0, 0),
'gray': (125, 125, 125),
'rand': np.random.randint(0, high=256, size=(3, )).tolist(),
'dark_gray': (50, 50, 50),
'light_gray': (220, 220, 220)}
# 方法:显示图片
def show_image(image, title):
img_RGB = image[:, :, ::-1] # BGR to RGB
plt.title(title)
plt.imshow(img_RGB)
plt.show()
# 创建画布
canvas = np.zeros((400, 400, 3), np.uint8) # 默认背景是黑色
canvas.fill(255) # canvas[:] = colors[""]
# 往画布上输入文本
cv.putText(canvas, "Hello World", (50, 50), cv.FONT_HERSHEY_SIMPLEX, 0.9, colors["red"], cv.LINE_4)
show_image(canvas, "Canvas")
目标: 确定人脸位置,画出矩形框。
原理: 使用 Haar-like 特征做检测:特征值为白色矩形像素和减去黑色矩形像素和。
import cv2 as cv
# 方法:绘制图片中检测到的人脸
def plot_rectangle(image, faces):
# 拿到检测到的人脸数据(4个值):坐标(x, y), width, height
for (x, y, w, h) in faces:
cv.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 3)
return image
# 主函数
def main():
# 读取摄像头
capture = cv.VideoCapture(0)
# 通过 cv.CascadeClassifier() 加载级联分类器
faces_alt2 = cv.CascadeClassifier("haarcascade_frontalface_alt2.xml")
# 判断摄像头是否正常工作
if capture.isOpened() is False:
print("Camera Error !")
while capture.isOpened():
# 获取每一帧
ret, frame = capture.read()
print(ret)
if ret:
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 使用该分类器对图像中的人脸进行检测
faces_alt2_detect = faces_alt2.detectMultiScale(gray)
# 绘制图片中检测到的人脸
faces_alt2_result = plot_rectangle(frame.copy(), faces_alt2_detect)
cv.imshow("Face Detection", faces_alt2_result)
if cv.waitKey(20) & 0xFF == ord("q"):
break
else:
break
capture.release()
cv.destroyAllWindows()
if __name__ == '__main__':
main()