加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
smoke.py 5.10 KB
一键复制 编辑 原始数据 按行查看 历史
KX 提交于 2023-02-12 16:34 . f
import math
import cv2
import dlib
from imutils import face_utils
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("G:\\test\\shape_predictor_68_face_landmarks.dat")
cap = cv2.VideoCapture(0)
ret, image = cap.read()
while ret:
# sta = time.time()
ret, image = cap.read()
# image = cv2.resize(image, (640,384))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 1)
# enumerate()方法用于将一个可遍历的数据对象(列表、元组、字典)组合
# 为一个索引序列,同时列出 数据下标 和 数据 ,一般用在for循环中
check_smoke = False
if rects is None:
continue
for (i, rect) in enumerate(rects):
shape = predictor(gray, rect) # 标记人脸中的68个landmark点
shape = face_utils.shape_to_np(shape) # shape转换成68个坐标点矩阵
(mStart, mEnd) = face_utils.FACIAL_LANDMARKS_68_IDXS["mouth"]
(x_face, y_face, w_face, h_face) = face_utils.rect_to_bb(rect) # 返回人脸框的左上角坐标和矩形框的尺寸
# cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),
# cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# landmarksNum = 0;
m_49 = None
m_55 = None
m_52 = None
m_58 = None
for id, (x, y) in enumerate(shape):
if id == 49:
m_49 = (x, y)
# cv2.circle(image, (x, y), 2, (0, 0, 255), -1)
elif id == 52:
m_52 = (x, y)
# cv2.circle(image, (x, y), 2, (0, 0, 255), -1)
elif id == 55:
m_55 = (x, y)
# cv2.circle(image, (x, y), 2, (0, 0, 255), -1)
elif id == 58:
m_58 = (x, y)
# cv2.circle(image, (x, y), 2, (0, 0, 255), -1)
mouse_center = (int((m_49[0] + m_55[0]) / 2), int((m_49[1] + m_55[1]) / 2))
mouse_w = abs(m_55[0] - m_49[0])
mouse_h = abs(m_58[1] - m_52[1])
# mouse_h=m_55[0]-m_49[0]
mouse_left = (mouse_center[0] - 2 * mouse_w, mouse_center[1] - 2 * mouse_h)
mouse_right = (mouse_center[0] + 2 * mouse_w, mouse_center[1] + 2 * mouse_h)
cv2.rectangle(image, mouse_left, mouse_right, (0, 0, 255), 2)
"""
crop image
"""
crop_smoke = image[mouse_left[1]:mouse_right[1], mouse_left[0]:mouse_right[0], :]
gray = cv2.cvtColor(crop_smoke, cv2.COLOR_RGB2GRAY)
# 将灰度图转换为二值图像
ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)
# contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
# cv2.CHAIN_APPROX_SIMPLE) # 该函数计算一幅图像中目标的轮廓
# cua = cv2.Canny(crop_smoke, 600, 384)
# r = cv2.bilateralFilter(crop_smoke, 9, 75, 75)
contours, cnt = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# area = cv2.contourArea(contours[0])
# print('contourArea', area)
d_limit_x=0.0
d_limit_y=0.0
for c in contours:
if cv2.contourArea(c) < 10 or cv2.contourArea(
c) > 30: # 对于矩形区域,只显示大于给定阈值的轮廓,所以一些微小的变化不会显示。对于光照不变和噪声低的摄像头可不设定轮廓最小尺寸的阈值
continue
res = cv2.minAreaRect(c)
cen_ = res[0]
#
len = math.sqrt(((mouse_center[0] - cen_[0] - mouse_left[0]) ** 2) + (
(mouse_center[1] - cen_[1] - mouse_left[1]) ** 2))
print(len)
x = cen_[0] + mouse_center[0]
y = cen_[1] + mouse_center[1]
d_limit_x = x_face + w_face + mouse_w * 2
d_limit_y = y_face + h_face + mouse_w * 2
if len < mouse_w * 2:
cv2.circle(image, (int(mouse_center[0]), int(mouse_center[1])), 2, (0, 0, 255), -1)
cv2.circle(image, (int(cen_[0]), int(cen_[1])), 2, (0, 0, 255), -1)
(x, y, w, h) = cv2.boundingRect(c) # 该函数计算矩形的边界框
x = mouse_left[0] + x
y = mouse_left[1] + y
if x < d_limit_x and y < d_limit_y:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
check_smoke = True
cv2.putText(image, "x:{}".format(x), (0, 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(image, "y:{}".format(y), (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(image, "d_limit_x:{}".format(d_limit_x), (0, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(image, "d_limit_y:{}".format(d_limit_y), (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255),2)
cv2.imshow("test",image)
if check_smoke: cv2.putText(image,"smoke!!!",(10, 60),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
cap.release()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化