Python3利用Dlib19.7实现摄像头人脸识别的方法


Posted in Python onMay 11, 2018

0.引言

利用python开发,借助Dlib库捕获摄像头中的人脸,提取人脸特征,通过计算欧氏距离来和预存的人脸特征进行对比,达到人脸识别的目的;

可以自动从摄像头中抠取人脸图片存储到本地,然后提取构建预设人脸特征;

根据抠取的 / 已有的同一个人多张人脸图片提取128D特征值,然后计算该人的128D特征均值;

然后和摄像头中实时获取到的人脸提取出的特征值,计算欧氏距离,判定是否为同一张人脸;

人脸识别 / face recognition的说明:

wikipedia 关于人脸识别系统 / face recognition system 的描述:theywork by comparing selected facial featuresfrom given image with faces within a database.

本项目中就是比较 预设的人脸的特征和 摄像头实时获取到的人脸的特征;

核心就是提取128D人脸特征,然后计算摄像头人脸特征和预设的特征脸的欧式距离,进行比对;

效果如下(摄像头认出来我是default_person预设的人脸 / 另一个人不是预设人脸显示diff):

Python3利用Dlib19.7实现摄像头人脸识别的方法

图1 摄像头人脸识别效果gif

1.总体流程

先说下 人脸检测 (face detection) 和 人脸识别 (face recognition) ,前者是达到检测出场景中人脸的目的就可以了,而后者不仅需要检测出人脸,还要和已有人脸数据进行比对,识别出是否在数据库中,或者进行身份标注之类处理,人脸检测和人脸识别两者有时候可能会被理解混淆;

我的之前一些项目都是用dlib做人脸检测这块,这个项目想要实现的功能是人脸识别功能,借助的是 dlib官网中 face_recognition.py这个例程 (link:http://dlib.net/face_recognition.py.html);

核心在于 利用 “dlib_face_recognition_resnet_model_v1.dat” 这个model,提取人脸图像的128D特征,然后比对不同人脸图片的128D特征,设定阈值计算欧氏距离来判断是否为同一张脸;

# face recognition model, the object maps human faces into 128D vectors
facerec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
 
shape = predictor(img, dets[0])
face_descriptor = facerec.compute_face_descriptor(img, shape)

Python3利用Dlib19.7实现摄像头人脸识别的方法

图2 总体设计流程

2.源码介绍

主要有

  1. get_face_from_camera.py ,
  2. get_features_into_CSV.py
  3. face_reco_from_camera.py

这三个py文件;

2.1get_face_from_camera.py / 采集构建XXX人脸数据

人脸识别需要将 提取到的图像数据 和已有图像数据进行比对分析,所以这个py文件实现的功能就是采集构建XXX的人脸数据;

程序会生成一个窗口,显示调用的摄像头实时获取的图像(关于摄像头的调用方式可以参考我的另一博客https://3water.com/article/135512.htm);

按s键可以保存当前视频流中的人脸图像,保存的路径由 path_save = “xxxx/get_from_camera/” 规定;

按q键退出窗口;

摄像头的调用是利用opencv库的cv2.VideoCapture(0), 此处参数为0代表调用的是笔记本的默认摄像头,你也可以让它调用传入已有视频文件;

Python3利用Dlib19.7实现摄像头人脸识别的方法

图3get_face_from_camera.py 的界面

这样的话,你就可以在 path_save指定的目录下得到一组捕获到的人脸;

Python3利用Dlib19.7实现摄像头人脸识别的方法

图4 捕获到的一组人脸

源码如下:

# 2018-5-11
# By TimeStamp
# cnblogs: http://www.cnblogs.com/AdaminXie

import dlib # 人脸识别的库dlib
import numpy as np # 数据处理的库numpy
import cv2 # 图像处理的库OpenCv

# dlib预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

# 创建cv2摄像头对象
cap = cv2.VideoCapture(0)

# cap.set(propId, value)
# 设置视频参数,propId设置的视频参数,value设置的参数值
cap.set(3, 480)

# 截图screenshoot的计数器
cnt_ss = 0

# 人脸截图的计数器
cnt_p = 0

# 保存
path_save = "F:/code/python/P_dlib_face_reco/data/get_from_camera/"

# cap.isOpened() 返回true/false 检查初始化是否成功
while cap.isOpened():

 # cap.read()
 # 返回两个值:
 # 一个布尔值true/false,用来判断读取视频是否成功/是否到视频末尾
 # 图像对象,图像的三维矩阵q
 flag, im_rd = cap.read()

 # 每帧数据延时1ms,延时为0读取的是静态帧
 kk = cv2.waitKey(1)

 # 取灰度
 img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)

 # 人脸数rects
 rects = detector(img_gray, 0)

 # print(len(rects))

 # 待会要写的字体
 font = cv2.FONT_HERSHEY_SIMPLEX

 if (len(rects) != 0):
 # 检测到人脸

 # 矩形框
 for k, d in enumerate(rects):

 # 计算矩形大小
 # (x,y), (宽度width, 高度height)
 pos_start = tuple([d.left(), d.top()])
 pos_end = tuple([d.right(), d.bottom()])

 # 计算矩形框大小
 height = d.bottom() - d.top()
 width = d.right() - d.left()

 # 根据人脸大小生成空的图像
 im_blank = np.zeros((height, width, 3), np.uint8)

 im_rd = cv2.rectangle(im_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255), 2)
 im_blank = np.zeros((height, width, 3), np.uint8)

 # 保存人脸到本地
 if (kk == ord('s')):
 cnt_p += 1
 for ii in range(height):
  for jj in range(width):
  im_blank[ii][jj] = im_rd[d.top() + ii][d.left() + jj]
 print(path_save + "img_face_" + str(cnt_p) + ".jpg")
 cv2.imwrite(path_save + "img_face_" + str(cnt_p) + ".jpg", im_blank)
 cv2.putText(im_rd, "faces: " + str(len(rects)), (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)

 else:
 # 没有检测到人脸
 cv2.putText(im_rd, "no face", (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)

 # 添加说明
 im_rd = cv2.putText(im_rd, "s: save face", (20, 400), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)
 im_rd = cv2.putText(im_rd, "q: quit", (20, 450), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)
 
 # 按下q键退出
 if (kk == ord('q')):
 break

 # 窗口显示
 cv2.imshow("camera", im_rd)

# 释放摄像头
cap.release()

# 删除建立的窗口
cv2.destroyAllWindows()

2.2get_features_into_CSV.py / 提取特征存入CSV

已经得到了XXX的一组人脸图像,现在就需要把他的面部特征提取出来;

这里借助 dlib 库的 face recognition model 人脸识别模型;

# face recognition model, the object maps human faces into 128D vectors
facerec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

# detector to find the faces
detector = dlib.get_frontal_face_detector()

# shape predictor to find the face landmarks
predictor = dlib.shape_predictor("shape_predictor_5_face_landmarks.dat")

# 读取图片
img = io.imread(path_img)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

dets = detector(img_gray, 1)
shape = predictor(img_gray, dets[0])
face_descriptor = facerec.compute_face_descriptor(img_gray, shape)

我们可以看下对于某张图片,face_descriptor的输出结果:

绿色框内是我们的返回128D特征的函数;

在红色框内调用该函数来计算img_face_13.jpg;

可以看到黄色框中的输出为128D的向量;

Python3利用Dlib19.7实现摄像头人脸识别的方法

图5 返回单张图像的128D特征的计算结果

所以我们就可以把path_save中的图像,进行批量的特征计算,然后写入CSV中(利用 write_into_CSV函数),我这边csv的命名为default_person.csv;

就可以得到行数(人脸数)*128列的一个特征CSV;

这是某个人的人脸特征,然后计算128D特征的均值,求mean(利用 compute_the_mean函数)

运行的输出结果,这个128D的特征值,就是default_person的特征;

也就是我们内置/预设的人脸,之后摄像头捕获的人脸将要拿过来和这个特征值进行比对,进行人脸识别的处理;

[-0.030892765492592986, 0.13333227054068916, 0.054221574805284799, -0.050820438289328626, -0.056331159841073189, 0.0039378538311116004, -0.044465327145237675, -0.13096490031794497, 0.14215188983239627, -0.084465635842398593, 0.34389359700052363, -0.062936659118062566, -0.24372901571424385, -0.13270603316394905, -0.0472818422866495, 0.15475224742763921, -0.24415240554433121, -0.11213862150907516, 0.032288033417180964, 0.023676671577911628, 0.098508275653186594, -0.010117797634417289, 0.0048202000815715448, -0.014808513420192819, -0.060100053486071135, -0.34934839135722112, -0.095795629448012301, -0.050788544706608117, 0.032316677762489567, -0.099673464894294739, -0.080181991975558434, 0.096361607705291952, -0.1823408101734362, -0.045472671817007815, -0.0066827326326778062, 0.047393877549391041, -0.038414973079373964, -0.039067085930391363, 0.15961966781239761, 0.0092458106136243598, -0.16182226570029007, 0.026322136191945327, -0.0039144184832510193, 0.2492692768573761, 0.19180528427425184, 0.022950534855848866, -0.019220497949342979, -0.15331173021542399, 0.047744840089427795, -0.17038608616904208, 0.026140184680882254, 0.19366614363695445, 0.066497623724372762, 0.07038829416820877, -0.0549700813073861, -0.11961311768544347, -0.032121153940495695, 0.083507449611237169, -0.14934051350543373, 0.011458799806668571, 0.10686114273573223, -0.10744074888919529, -0.04377919611962218, -0.11030520381111848, 0.20804878441910996, 0.093076545941202266, -0.11621182490336268, -0.1991656830436305, 0.10751579348978244, -0.11251544991606161, -0.12237925866716787, 0.058218707869711672, -0.15829276019021085, -0.17670038891466042, -0.2718416170070046, 0.034569320955166689, 0.30443575821424784, 0.061833358712886512, -0.19622498672259481, 0.011373612000361868, -0.050225612756453063, -0.036157087079788507, 0.12961127491373764, 0.13962576616751521, -0.0074232793168017737, 0.020964263007044792, -0.11185114399382942, 0.012502493042694894, 0.17834208513561048, -0.072658227462517586, -0.041312719401168194, 0.25095899873658228, -0.056628625839948654, 0.10285118379090961, 0.046701753217923012, 0.042323612264896691, 0.0036216247826814651, 0.066720707440062574, -0.16388990533979317, -0.0193739396421925, 0.027835704435251261, -0.086023958105789985, -0.05472404568603164, 0.14802298341926776, -0.10644183582381199, 0.098863413851512108, 0.00061285014778963834, 0.062096107555063146, 0.051960245755157973, -0.099548895108072383, -0.058173993112225285, -0.065454461562790375, 0.14721672511414477, -0.25363486848379435, 0.20384312381869868, 0.16890435312923632, 0.097537552447695477, 0.087824966562421697, 0.091438713434495431, 0.093809676797766431, -0.034379941362299417, -0.085149037210564868, -0.24900743130006289, 0.021165960517368819, 0.076710369830068792, -0.0061752907196549996, 0.028413473285342519, -0.029983982541843465]

源码:

# 2018-5-11
# By TimeStamp
# cnblogs: http://www.cnblogs.com/AdaminXie

# return_128d_features() 获取某张图像的128d特征
# write_into_csv() 将某个文件夹中的图像读取特征兵写入csv
# compute_the_mean() 从csv中读取128d特征,并计算特征均值

import cv2
import os
import dlib
from skimage import io
import csv
import numpy as np
import pandas as pd

path_pics = "F:/code/python/P_dlib_face_reco/data/get_from_camera/"
path_csv = "F:/code/python/P_dlib_face_reco/data/csvs/"

# detector to find the faces
detector = dlib.get_frontal_face_detector()

# shape predictor to find the face landmarks
predictor = dlib.shape_predictor("shape_predictor_5_face_landmarks.dat")

# face recognition model, the object maps human faces into 128D vectors
facerec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

# 返回单张图像的128D特征
def return_128d_features(path_img):
 img = io.imread(path_img)
 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 dets = detector(img_gray, 1)

 if(len(dets)!=0):
 shape = predictor(img_gray, dets[0])
 face_descriptor = facerec.compute_face_descriptor(img_gray, shape)
 else:
 face_descriptor = 0
 print("no face")

 # print(face_descriptor)
 return face_descriptor

#return_128d_features(path_pics+"img_face_13.jpg")

# 将文件夹中照片特征提取出来,写入csv
# 输入input:
# path_pics: 图像文件夹的路径
# path_csv: 要生成的csv路径

def write_into_csv(path_pics ,path_csv):
 dir_pics = os.listdir(path_pics)

 with open(path_csv, "w", newline="") as csvfile:
 writer = csv.writer(csvfile)
 for i in range(len(dir_pics)):
 # 调用return_128d_features()得到128d特征
 print(path_pics+dir_pics[i])
 features_128d = return_128d_features(path_pics+dir_pics[i])
 # print(features_128d)
 # 遇到没有检测出人脸的图片跳过
 if features_128d==0:
 i += 1
 else:
 writer.writerow(features_128d)

#write_into_csv(path_pics, path_csv+"default_person.csv")

path_csv_rd = "F:/code/python/P_dlib_face_reco/data/csvs/default_person.csv"

# 从csv中读取数据,计算128d特征的均值
def compute_the_mean(path_csv_rd):
 column_names = []

 for i in range(128):
 column_names.append("features_" + str(i + 1))

 rd = pd.read_csv(path_csv_rd, names=column_names)

 # 存放128维特征的均值
 feature_mean = []

 for i in range(128):
 tmp_arr = rd["features_"+str(i+1)]
 tmp_arr = np.array(tmp_arr)

 # 计算某一个特征的均值
 tmp_mean = np.mean(tmp_arr)

 feature_mean.append(tmp_mean)

 print(feature_mean)
 return feature_mean

compute_the_mean(path_csv_rd)

2.3 face_reco_from_camera.py / 实时人脸识别对比分析

这个py就是调用摄像头,捕获摄像头中的人脸,然后如果检测到人脸,将摄像头中的人脸提取出128D的特征,然后和预设的default_person的128D特征进行计算欧式距离,如果比较小,可以判定为一个人,否则不是一个人;

欧氏距离对比的阈值设定,是在 return_euclidean_distance函数的dist变量;

我这里程序里面指定的是0.4,具体阈值可以根据实际情况或者测得结果进行修改;

源码:

# 2018-5-11
# By TimeStamp
# cnblogs: http://www.cnblogs.com/AdaminXie

import dlib # 人脸识别的库dlib
import numpy as np # 数据处理的库numpy
import cv2 # 图像处理的库OpenCv

# face recognition model, the object maps human faces into 128D vectors
facerec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

# 计算两个向量间的欧式距离
def return_euclidean_distance(feature_1,feature_2):
 feature_1 = np.array(feature_1)
 feature_2 = np.array(feature_2)
 dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
 print(dist)

 if dist > 0.4:
 return "diff"
 else:
 return "same"


features_mean_default_person = [-0.030892765492592986, 0.13333227054068916, 0.054221574805284799, -0.050820438289328626, -0.056331159841073189, 0.0039378538311116004, -0.044465327145237675, -0.13096490031794497, 0.14215188983239627, -0.084465635842398593, 0.34389359700052363, -0.062936659118062566, -0.24372901571424385, -0.13270603316394905, -0.0472818422866495, 0.15475224742763921, -0.24415240554433121, -0.11213862150907516, 0.032288033417180964, 0.023676671577911628, 0.098508275653186594, -0.010117797634417289, 0.0048202000815715448, -0.014808513420192819, -0.060100053486071135, -0.34934839135722112, -0.095795629448012301, -0.050788544706608117, 0.032316677762489567, -0.099673464894294739, -0.080181991975558434, 0.096361607705291952, -0.1823408101734362, -0.045472671817007815, -0.0066827326326778062, 0.047393877549391041, -0.038414973079373964, -0.039067085930391363, 0.15961966781239761, 0.0092458106136243598, -0.16182226570029007, 0.026322136191945327, -0.0039144184832510193, 0.2492692768573761, 0.19180528427425184, 0.022950534855848866, -0.019220497949342979, -0.15331173021542399, 0.047744840089427795, -0.17038608616904208, 0.026140184680882254, 0.19366614363695445, 0.066497623724372762, 0.07038829416820877, -0.0549700813073861, -0.11961311768544347, -0.032121153940495695, 0.083507449611237169, -0.14934051350543373, 0.011458799806668571, 0.10686114273573223, -0.10744074888919529, -0.04377919611962218, -0.11030520381111848, 0.20804878441910996, 0.093076545941202266, -0.11621182490336268, -0.1991656830436305, 0.10751579348978244, -0.11251544991606161, -0.12237925866716787, 0.058218707869711672, -0.15829276019021085, -0.17670038891466042, -0.2718416170070046, 0.034569320955166689, 0.30443575821424784, 0.061833358712886512, -0.19622498672259481, 0.011373612000361868, -0.050225612756453063, -0.036157087079788507, 0.12961127491373764, 0.13962576616751521, -0.0074232793168017737, 0.020964263007044792, -0.11185114399382942, 0.012502493042694894, 0.17834208513561048, -0.072658227462517586, -0.041312719401168194, 0.25095899873658228, -0.056628625839948654, 0.10285118379090961, 0.046701753217923012, 0.042323612264896691, 0.0036216247826814651, 0.066720707440062574, -0.16388990533979317, -0.0193739396421925, 0.027835704435251261, -0.086023958105789985, -0.05472404568603164, 0.14802298341926776, -0.10644183582381199, 0.098863413851512108, 0.00061285014778963834, 0.062096107555063146, 0.051960245755157973, -0.099548895108072383, -0.058173993112225285, -0.065454461562790375, 0.14721672511414477, -0.25363486848379435, 0.20384312381869868, 0.16890435312923632, 0.097537552447695477, 0.087824966562421697, 0.091438713434495431, 0.093809676797766431, -0.034379941362299417, -0.085149037210564868, -0.24900743130006289, 0.021165960517368819, 0.076710369830068792, -0.0061752907196549996, 0.028413473285342519, -0.029983982541843465]


# dlib预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

# 创建cv2摄像头对象
cap = cv2.VideoCapture(0)

# cap.set(propId, value)
# 设置视频参数,propId设置的视频参数,value设置的参数值
cap.set(3, 480)

def get_128d_features(img_gray):
 dets = detector(img_gray, 1)
 if (len(dets) != 0):
 shape = predictor(img_gray, dets[0])
 face_descriptor = facerec.compute_face_descriptor(img_gray, shape)
 else:
 face_descriptor=0
 return face_descriptor

# cap.isOpened() 返回true/false 检查初始化是否成功
while (cap.isOpened()):

 # cap.read()
 # 返回两个值:
 # 一个布尔值true/false,用来判断读取视频是否成功/是否到视频末尾
 # 图像对象,图像的三维矩阵
 flag, im_rd = cap.read()

 # 每帧数据延时1ms,延时为0读取的是静态帧
 kk = cv2.waitKey(1)

 # 取灰度
 img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)

 # 人脸数rects
 rects = detector(img_gray, 0)

 # print(len(rects))

 # 待会要写的字体
 font = cv2.FONT_HERSHEY_SIMPLEX

 cv2.putText(im_rd, "q: quit", (20, 400), font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)

 if (len(rects) != 0):
 # 检测到人脸

 # 将捕获到的人脸提取特征和内置特征进行比对
 features_rd = get_128d_features(im_rd)
 compare = return_euclidean_distance(features_rd, features_mean_default_person)

 im_rd = cv2.putText(im_rd, compare.replace("same", "default_person"), (20, 350), font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)

 # 矩形框
 for k, d in enumerate(rects):

 # 绘制矩形框
 im_rd = cv2.rectangle(im_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255), 2)

 cv2.putText(im_rd, "faces: " + str(len(rects)), (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)

 else:
 # 没有检测到人脸
 cv2.putText(im_rd, "no face", (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)


 # 按下q键退出
 if (kk == ord('q')):
 break

 # 窗口显示
 cv2.imshow("camera", im_rd)

# 释放摄像头
cap.release()

# 删除建立的窗口
cv2.destroyAllWindows()

实时输出结果:

Python3利用Dlib19.7实现摄像头人脸识别的方法

图6 实时输出的欧氏距离结果

通过实时的输出结果,看的比较明显;

输出绿色部分:当是我自己(即之前分析提取特征的default_person)时,计算出来的欧式距离基本都在0.2 左右;

输出红色部分:而换一张图片上去比如特朗普,明显看到欧式距离计算结果达到了0.8,此时就可以判定,后来这张人脸不是我们预设的人脸;

所以之前提到的欧式距离计算对比的阈值可以由此设定,本项目中取的是0.4;

3.总结

之前接着那个摄像头人脸检测写的,不过拖到现在才更新,写的也比较粗糙,大家有具体需求和应用场景可以加以修改,有什么问题可以留言或者直接mail 我。。。不好意思

核心就是提取人脸特征,然后计算欧式距离和预设的特征脸进行比对;

不过这个实时获取摄像头人脸进行比对,要实时的进行计算摄像头脸的特征值,然后还要计算欧氏距离,所以计算量比较大,可能摄像头视频流会出现卡顿;

# 代码已上传到了我的GitHub,如果对您有帮助欢迎star下:https://github.com/coneypo/Dlib_face_recognition_from_camera

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python定时采集摄像头图像上传ftp服务器功能实现
Dec 23 Python
在 Python 应用中使用 MongoDB的方法
Jan 05 Python
Django中redis的使用方法(包括安装、配置、启动)
Feb 21 Python
Python学生信息管理系统修改版
Mar 13 Python
Python使用re模块正则提取字符串中括号内的内容示例
Jun 01 Python
Python tkinter实现图片标注功能(完整代码)
Dec 08 Python
Django使用Celery加redis执行异步任务的实例内容
Feb 20 Python
python剪切视频与合并视频的实现
Mar 03 Python
利用Python实现斐波那契数列的方法实例
Jul 26 Python
selenium.webdriver中add_argument方法常用参数表
Apr 08 Python
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 25 Python
深入探讨opencv图像矫正算法实战
May 21 Python
Python中的TCP socket写法示例
May 11 #Python
Python简单定义与使用二叉树示例
May 11 #Python
Python堆排序原理与实现方法详解
May 11 #Python
python 执行shell命令并将结果保存的实例
May 11 #Python
python 实现登录网页的操作方法
May 11 #Python
Python利用splinter实现浏览器自动化操作方法
May 11 #Python
Python爬虫信息输入及页面的切换方法
May 11 #Python
You might like
攻克CakePHP系列三 表单数据增删改
2008/10/22 PHP
php 显示指定路径下的图片
2009/10/29 PHP
显示youtube视频缩略图和Vimeo视频缩略图代码分享
2014/02/13 PHP
php中简单的对称加密算法实现
2017/01/05 PHP
Yii1.1中通过Sql查询进行的分页操作方法
2017/03/16 PHP
PHP 使用二进制保存用户状态的实例
2018/01/29 PHP
PHP实现微信商户支付企业付款到零钱功能
2018/09/30 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
如何使用Javascript获取距今n天前的日期
2013/07/08 Javascript
JS辨别访问浏览器判断是android还是ios系统
2014/08/19 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
2016/01/05 Javascript
Javascript实现跑马灯效果的简单实例
2016/05/31 Javascript
JS HTML5实现拖拽移动列表效果
2020/08/27 Javascript
深入理解JavaScript中的预解析
2017/01/04 Javascript
jQuery实现的点击标题文字切换字体效果示例【测试可用】
2018/04/26 jQuery
如何在基于vue-cli的项目自定义打包环境
2018/11/10 Javascript
vue实现路由懒加载及组件懒加载的方式
2019/06/11 Javascript
vue 解决form表单提交但不跳转页面的问题
2019/10/30 Javascript
js实现翻牌小游戏
2020/07/31 Javascript
python字符串的常用操作方法小结
2016/05/21 Python
django 发送手机验证码的示例代码
2018/04/25 Python
pytorch + visdom CNN处理自建图片数据集的方法
2018/06/04 Python
Python爬虫包BeautifulSoup实例(三)
2018/06/17 Python
对python中的argv和argc使用详解
2018/12/15 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
python计算波峰波谷值的方法(极值点)
2020/02/18 Python
python中如何使用虚拟环境
2020/10/14 Python
css3 旋转按钮 使用CSS3创建一个旋转可变色按钮
2012/12/31 HTML / CSS
CAT鞋加拿大官网:CAT Footwear加拿大
2020/08/05 全球购物
光声世纪笔试题目
2012/08/25 面试题
爱岗敬业演讲稿范文
2014/01/14 职场文书
学习型党组织建设经验材料
2014/05/26 职场文书
纪律教育月活动总结
2014/08/26 职场文书
企业挂职心得体会
2014/09/10 职场文书
初中运动会前导词
2015/07/20 职场文书