0.出于好奇,思考中想要把2维图像怎么转化为3维图像,我在考虑怎么把草莓二维转为三维图像,这个领域其实早有人研究了,术语叫三维重建,使用matlab可以实现三维坐标标点来表达,后来我发现一个很好玩的事情就是我看到直播有人卖替换人脸和换装的程序,我就想试试怎么实现换脸…
//matlab
import cv2
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# 创建摄像头对象和其他必要的变量
cap = cv2.VideoCapture(0)
sift = cv2.SIFT_create()
des1 = None
pts1 = None
good_matches = []
match_threshold = 0.7
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 定义回调函数,用于调整匹配的阈值
def on_match_threshold_change(val):
global match_threshold
match_threshold = val / 100
print("Match threshold:", match_threshold)
# 创建窗口和滑块
cv2.namedWindow('Frame')
cv2.createTrackbar('Threshold(%)', 'Frame', int(match_threshold * 100), 100, on_match_threshold_change)
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
kp, des = sift.detectAndCompute(gray, None)
if des1 is None:
des1 = des
continue
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
matches = bf.match(des1, des)
good_matches = []
for m in matches:
if m.distance < match_threshold * 100:
good_matches.append(m)
pts2 = np.float32([kp[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
if len(pts2) > 4:
if pts1 is not None and len(pts1) == len(pts2):
E, mask = cv2.findEssentialMat(pts1, pts2)
_, R, t, _ = cv2.recoverPose(E, pts1, pts2)
P = np.eye(3, 4)
points = cv2.triangulatePoints(P, np.hstack((R, t)), pts1, pts2)
points /= points[3]
# 清空上一帧的点云数据
ax.cla()
# 绘制三维点云
ax.scatter(points[0], points[1], points[2])
# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# 显示图像
plt.pause(0.001)
des1 = des
pts1 = pts2
cv2.imshow('Frame', frame)
key = cv2.waitKey(1) & 0xFF
if key == ord(' '):
while cv2.waitKey(1) & 0xFF != ord(' '):
pass
elif key == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
1.环境 python3.9
pip install dlib
//代码
import dlib
import cv2
# 初始化人脸检测器
detector = dlib.get_frontal_face_detector()
# 加载特征点预测器模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 创建视频捕获对象
cap = cv2.VideoCapture(0) # 0表示默认摄像头
while True:
# 读取视频流中的帧
ret, frame = cap.read()
if not ret:
break
# 将帧转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 使用人脸检测器检测人脸位置
faces = detector(gray)
# 对每张检测到的人脸进行标记
for face in faces:
# 获取人脸的特征点
shape = predictor(gray, face)
# 在图像上标记人脸特征点
for i in range(68): # 假设使用的是68个特征点模型
x, y = shape.part(i).x, shape.part(i).y
cv2.circle(frame, (x, y), 2, (0, 255, 0), -1)
# 显示带有特征点标记的帧
cv2.imshow('Facial Landmark Detection', frame)
# 按下'q'键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放视频捕获对象并关闭窗口
cap.release()
cv2.destroyAllWindows()
2.只实现了人脸替换图片…
import dlib
import cv2
# 初始化人脸检测器
detector = dlib.get_frontal_face_detector()
# 加载特征点预测器模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 加载替换脸部的图片
new_face_image = cv2.imread('pic/my.jpg') # 替换为你想要使用的图片路径
# 创建视频捕获对象
cap = cv2.VideoCapture(0) # 0表示默认摄像头
while True:
# 读取视频流中的帧
ret, frame = cap.read()
if not ret:
break
# 将帧转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 使用人脸检测器检测人脸位置
faces = detector(gray)
# 对每张检测到的人脸进行替换
for face in faces:
# 获取人脸的特征点
shape = predictor(gray, face)
# 定义脸部区域
(x, y, w, h) = (face.left(), face.top(), face.width(), face.height())
# 将新的脸部图片大小调整为与脸部区域相匹配
new_face_resized = cv2.resize(new_face_image, (w, h))
# 替换脸部
try:
frame[y:y + h, x:x + w] = new_face_resized
except ValueError as e:
print("发生了形状不匹配的错误:", e)
# 其他处理代码
# 显示替换后的帧
cv2.imshow('Real-time Face Replacement', frame)
# 按下'q'键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放视频捕获对象并关闭窗口
cap.release()
cv2.destroyAllWindows()