NO.55——Face Swapping with Python,dlib,openCV(换脸)

2023-11-14

摘要

早前看过国外博主的一篇用200行代码实现图像换脸操作的文章,主要通过仿射变换和调色的方法,原理呢,晦涩难懂,具体效果呢,其实也并不是很理想,至少要比直接调用Face++的人脸融合接口要差很多,用于学习图像处理相关的知识还是不错的。下一篇文章就介绍一下如何调用Face++的人脸融合接口实现换脸操作。这篇文章介绍的方法主要是以下三步:

  1. 识别面部的landmark模型
  2. 对第二张图像进行仿射变换(旋转、缩放、平移),使得第二张图像的面部表情与第一张图像一致
  3. 调整第二张图像的颜色使得与第一张图像颜色相匹配

效果展示 

 


1.应用dlib提取人脸面部特征

在dlib里,通过68组特征点从而确定一张独一无二的 人脸。训练模型是人脸识别的关键,用于查找图片的关键点。下载地址:http://dlib.net/files/。下载文件:shape_predictor_68_face_landmarks.dat.bz2。当然你也可以训练自己的人脸关键点模型。

PREDICTOR_PATH = "/home/matt/dlib-18.16/shape_predictor_68_face_landmarks.dat"

detector = dlib.get_frontal_face_detector()  #面部检测
predictor = dlib.shape_predictor(PREDICTOR_PATH)   #特征提取

def get_landmarks(im):
    rects = detector(im, 1)
    
    if len(rects) > 1:
        raise TooManyFaces
    if len(rects) == 0:
        raise NoFaces

    return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])

  get_landmarks()函数通过输入一张图像,返回一个68*2的矩阵,矩阵每一行的x,y元素表征每一个关键点的特征。特征提取器需要一个粗略的矩形检测边框作为输入,而这个输入是由面部检测器提供,它返回了一系列框起人脸的矩形。

2.仿射变换

仿射变换就是线性变换再加上平移。旋转 (线性变换)缩放操作(线性变换)平移 (向量加)如果没有了第3个平移的操作,那它就是线性变换。

将这三种变换写成矩阵形式:


        这个式子中,s就是缩放比例,θ就是旋转角度,最后的T代表平移的位移,其中R是一个正交矩阵。
                                                                                              R^TR=I

图像的变换要对图像的每一个像素点进行操作,假设其中的一个像素点的坐标是(x,y),我们用矩阵形式表示:

我们通常使用2x3矩阵来表示仿射变换:

其中矩阵A控制旋转和伸缩,矩阵B控制平移,矩阵M是完整的仿射变换矩阵。经过仿射变换后的点的矩阵坐标是T,我们已经知道放射变换就是线性变换加上平移,用矩阵表示的话就是

        计算可得

        图像平移的代码:

import cv2
import numpy as np        

img = cv2.imread('Rachel.jpg', 0)  
rows, cols = img.shape         

M = np.float32([[1, 0, 200], [0, 1, 100]])  
dst = cv2.warpAffine(img, M, (cols, rows))       

cv2.imshow('img', dst)  
k = cv2.waitKey(0)  
if k == ord('s'):  
    cv2.imwrite('Rachel3.jpg', dst)  
    cv2.destroyAllWindows()

        得到经过仿射变换后的点的坐标是(x+200,y+100),即将整个图像平移(200,100)

        旋转图像的代码:

import cv2  
      
img = cv2.imread('Rachel.jpg', 0)  
rows, cols = img.shape
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)  
dst = cv2.warpAffine(img, M, (cols, rows)) # 仿射变换 
cv2.imshow('Rachel', dst)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

        第一个参数是中心点的坐标,以(cols / 2, rows / 2)为中心点,逆时针旋转90度(若是正值,则顺时针旋转)。

        那么如何通过仿射变换任意变换图形呢?我们需要源图像和目标图像上分别一一映射的三个点来定义仿射变换

img = cv2.imread('Rachel.jpg')
rows, cols, ch = img.shape
 
pts1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])  #原始的三个点
pts2 = np.float32([[cols * 0.2, rows * 0.1], [cols * 0.9, rows * 0.2], [cols * 0.1, rows * 0.9]])  #新的三个点
 
M = cv2.getAffineTransform(pts1, pts2)   #计算仿射变换矩阵
dst = cv2.warpAffine(img, M, (cols, rows))   #生成仿射变换
 
cv2.imshow('image', dst)
k = cv2.waitKey(0)
if k == ord('s'):
    cv2.imwrite('Rachel1.jpg', dst)
    cv2.destroyAllWindows()

3.通过仿射变换进行人脸对齐

现在呢,我们通过特征提取器获得了两张人脸的68*2landmark矩阵,每一行都都表征不同面部特征,接下来,我们要计算通过什么样的仿射变换(旋转、缩放、平移),使得第一个矢量的点尽可能的匹配第二个矢量的点。

        一个想法是使用仿射变换将第一个图像变换覆盖第二个图像。如何判断这种对齐的效果呢?使用最小二乘法,使得变化后所有点与目标点距离和最小。

        T:平移 (区别于小T转置)    R:旋转     S:缩放 。两个形状矩阵分别为p和q,矩阵的每一行代表一个特征点的x,y坐标,

假设有68个特征点坐标,则p\in R^{68*2},写成数学形式:

        pi就是p矩阵的第i行,写成矩阵形式:

        \left \| · \right \|_{F}代表Frobenius范数,就是每一项的平方和。

     求解

       形如(1):

        根据维基百科的定义,这个最小值问题是有解析解的。只需将下式(2)进行变化,写成(1)式的样子。这里的变化就需要对原始点集p和q进行一些处理:

这里给出了对原始点集的变化步骤。结合代码来看:

#消除平移T的影响
    c1 = numpy.mean(points1, axis=0)
    c2 = numpy.mean(points2, axis=0)
    points1 -= c1
    points2 -= c2
#消除缩放系数S的影响
    s1 = numpy.std(points1)
    s2 = numpy.std(points2)
    points1 /= s1
    points2 /= s2

        这两步处理以后,R就可以变成求解下面的式子:

        这里的A,B不再是原始的数据点集,而是变成了处理以后点集。根据维基百科的求解方法:

        确切的说,应该是特征值分解(针对m*m的矩阵A),为什么用特征值分解呢?前面提到,这个R是一个正交矩阵(如果AAT=E(E为单位矩阵)或ATA=E,则n阶实矩阵A称为正交矩阵),我查了奇异值分解的定义,就比较明了了:

        这样就解出了R:

    U, S, Vt = numpy.linalg.svd(points1.T * points2)
    R = (U * Vt).T

        总结这个过程的步骤如下:

  1. 将输入矩阵转换为浮点数。 这是后续操作所必需的。
  2. 减去每个点集的质心。 一旦找到了针对所得点集的最佳缩放比例和旋转度,就可以使用质心c1和c2来找到完整的解。
  3. 同样,将每个点集除以其标准偏差。 这消除了问题的缩放分量。
  4. 使用奇异值分解计算旋转部分。 有关其工作原理的详细信息,请参见“正交前凸问题”上的Wikipedia文章。
  5. 返回完整的变换作为仿射变换矩阵。

最后通过openCV的cv2.warpAffine函数对第二个图进行变换,从而匹配第一个图。

def warp_im(im, M, dshape):
    output_im = numpy.zeros(dshape, dtype=im.dtype)
    cv2.warpAffine(im,
                   M[:2],
                   (dshape[1], dshape[0]),
                   dst=output_im,
                   borderMode=cv2.BORDER_TRANSPARENT,
                   flags=cv2.WARP_INVERSE_MAP)
    return output_im


4.颜色修正

        两个图像之间的肤色和光照差异导致重叠区域边缘周围的不连续性。 让我们尝试纠正该问题:

COLOUR_CORRECT_BLUR_FRAC = 0.6
LEFT_EYE_POINTS = list(range(42, 48))
RIGHT_EYE_POINTS = list(range(36, 42))

def correct_colours(im1, im2, landmarks1):
    blur_amount = COLOUR_CORRECT_BLUR_FRAC * numpy.linalg.norm(
                              numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) -
                              numpy.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
    blur_amount = int(blur_amount)
    if blur_amount % 2 == 0:
        blur_amount += 1
    im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)
    im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)

    # Avoid divide-by-zero errors.
    im2_blur += 128 * (im2_blur <= 1.0)

    return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /
                                                im2_blur.astype(numpy.float64))

        此函数尝试更改im2的颜色以匹配im1的颜色。 它通过将im2除以im2的高斯模糊,然后再乘以im1的高斯模糊来实现。 这里的想法是RGB缩放色彩校正,但是每个像素都有自己的局部缩放因子,而不是在整个图像中使用恒定的缩放因子。

        通过这种方法,可以在一定程度上解决两个图像之间的照明差异。 例如,如果从一侧照亮图像1,但是图像2具有均匀的照度,则颜色校正后的图像2在未照亮的一侧也会显得更暗。

        就是说,这是解决该问题的一个很粗略的解决方案,适当大小的高斯核是关键。 第一张图片中的面部特征太小,将在第二张图片中显示。 面部区域外有太大的内核杂散,无法覆盖像素,并且会发生变色。 在这里,使用0.6 *瞳孔距离的内核。

5.混合特征 

         建立一个蒙版。值为1的区域(此处显示为白色)与应显示图像2的区域对应,而值为0的区域(此处显示为黑色)与应显示图像1的区域对应。 0到1之间的值对应于图像1和image2的混合。

LEFT_EYE_POINTS = list(range(42, 48))
RIGHT_EYE_POINTS = list(range(36, 42))
LEFT_BROW_POINTS = list(range(22, 27))
RIGHT_BROW_POINTS = list(range(17, 22))
NOSE_POINTS = list(range(27, 35))
MOUTH_POINTS = list(range(48, 61))
OVERLAY_POINTS = [
    LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,
    NOSE_POINTS + MOUTH_POINTS,
]
FEATHER_AMOUNT = 11

def draw_convex_hull(im, points, color):
    points = cv2.convexHull(points)   #寻找凸包
    cv2.fillConvexPoly(im, points, color=color)   #填充凸多边形

def get_face_mask(im, landmarks):
    im = numpy.zeros(im.shape[:2], dtype=numpy.float64)

    for group in OVERLAY_POINTS:
        draw_convex_hull(im,
                         landmarks[group],
                         color=1)

    im = numpy.array([im, im, im]).transpose((1, 2, 0))

    im = (cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) > 0) * 1.0
    im = cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0)

    return im

mask = get_face_mask(im2, landmarks2)
warped_mask = warp_im(mask, M, im1.shape)
combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask],
                          axis=0)

注意: 

img.shape[:2] 取彩色图片的长、宽。
如果img.shape[:3] 则取彩色图片的长、宽、通道。

关于img.shape[0]、[1]、[2]
img.shape[0]:图像的垂直尺寸(高度)
img.shape[1]:图像的水平尺寸(宽度)
img.shape[2]:图像的通道数

在矩阵中,[0]就表示行数,[1]则表示列数。

        get_face_mask()用来生成这个蒙版。

        它以白色绘制两个凸多边形:一个围绕眼睛区域,另一个围绕鼻子和嘴巴区域。 然后,它将蒙版的边缘向外羽化11个像素。 羽化有助于隐藏任何剩余的不连续性。对于两个图像都生成这样的面罩。 使用放射变换,将第二个遮罩转换为图像1的坐标空间。然后通过采用逐个元素的最大值将这些蒙版组合为一个蒙版。 组合两个遮罩可确保遮盖图像1中的特征,并确保图像2中的特征完整显示。

         最后,通过蒙版给出最终图片:

output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask

6.全部代码

#!/usr/bin/python


"""
This is the code behind the Switching Eds blog post:

    http://matthewearl.github.io/2015/07/28/switching-eds-with-python/

See the above for an explanation of the code below.

To run the script you'll need to install dlib (http://dlib.net) including its
Python bindings, and OpenCV. You'll also need to obtain the trained model from
sourceforge:

    http://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2

Unzip with `bunzip2` and change `PREDICTOR_PATH` to refer to this file. The
script is run like so:

    ./faceswap.py <head image> <face image>

If successful, a file `output.jpg` will be produced with the facial features
from `<head image>` replaced with the facial features from `<face image>`.

"""

import cv2 as cv
import dlib
import numpy

import sys

sys.path.append('/usr/local/lib/python3.6/site-packages')

PREDICTOR_PATH = "/Users/chenyan/Desktop/AI/googleAI/faceswap/shape_predictor_68_face_landmarks.dat"
SCALE_FACTOR = 1 
FEATHER_AMOUNT = 11

FACE_POINTS = list(range(17, 68))
MOUTH_POINTS = list(range(48, 61))
RIGHT_BROW_POINTS = list(range(17, 22))
LEFT_BROW_POINTS = list(range(22, 27))
RIGHT_EYE_POINTS = list(range(36, 42))
LEFT_EYE_POINTS = list(range(42, 48))
NOSE_POINTS = list(range(27, 35))
JAW_POINTS = list(range(0, 17))

# Points used to line up the images.
ALIGN_POINTS = (LEFT_BROW_POINTS + RIGHT_EYE_POINTS + LEFT_EYE_POINTS +
                               RIGHT_BROW_POINTS + NOSE_POINTS + MOUTH_POINTS)

# Points from the second image to overlay on the first. The convex hull of each
# element will be overlaid.
OVERLAY_POINTS = [
    LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,
    NOSE_POINTS + MOUTH_POINTS,
]

# Amount of blur to use during colour correction, as a fraction of the
# pupillary distance.
COLOUR_CORRECT_BLUR_FRAC = 0.6

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(PREDICTOR_PATH)

class TooManyFaces(Exception):
    pass

class NoFaces(Exception):
    pass

def get_landmarks(im):
    rects = detector(im, 1)    #返回人脸检测矩形
    
    if len(rects) > 1:       #如果返回多个矩形
        raise TooManyFaces
    if len(rects) == 0:      #如果没有返回矩形,没有检测到人脸
        raise NoFaces
    #返回人脸检测的特征点
    return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])

def annotate_landmarks(im, landmarks):
    im = im.copy()
    for idx, point in enumerate(landmarks):
        pos = (point[0, 0], point[0, 1])
        cv.putText(im, str(idx), pos,
                    fontFace=cv.FONT_HERSHEY_SCRIPT_SIMPLEX,
                    fontScale=0.4,
                    color=(0, 0, 255))
        cv.circle(im, pos, 3, color=(0, 255, 255))
    return im

def draw_convex_hull(im, points, color):
    points = cv.convexHull(points)
    cv.fillConvexPoly(im, points, color=color)

def get_face_mask(im, landmarks):
    im = numpy.zeros(im.shape[:2], dtype=numpy.float64)

    for group in OVERLAY_POINTS:
        draw_convex_hull(im,
                         landmarks[group],
                         color=1)

    im = numpy.array([im, im, im]).transpose((1, 2, 0))

    im = (cv.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) > 0) * 1.0
    im = cv.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0)

    return im
    
def transformation_from_points(points1, points2):
    """
    Return an affine transformation [s * R | T] such that:

        sum ||s*R*p1,i + T - p2,i||^2

    is minimized.

    """
    # Solve the procrustes problem by subtracting centroids, scaling by the
    # standard deviation, and then using the SVD to calculate the rotation. See
    # the following for more details:
    #   https://en.wikipedia.org/wiki/Orthogonal_Procrustes_problem

    points1 = points1.astype(numpy.float64)
    points2 = points2.astype(numpy.float64)

    c1 = numpy.mean(points1, axis=0)
    c2 = numpy.mean(points2, axis=0)
    points1 -= c1
    points2 -= c2

    s1 = numpy.std(points1)
    s2 = numpy.std(points2)
    points1 /= s1
    points2 /= s2

    U, S, Vt = numpy.linalg.svd(points1.T * points2)

    # The R we seek is in fact the transpose of the one given by U * Vt. This
    # is because the above formulation assumes the matrix goes on the right
    # (with row vectors) where as our solution requires the matrix to be on the
    # left (with column vectors).
    R = (U * Vt).T

    return numpy.vstack([numpy.hstack(((s2 / s1) * R,
                                       c2.T - (s2 / s1) * R * c1.T)),
                         numpy.matrix([0., 0., 1.])])

def read_im_and_landmarks(fname):
    im = cv.imread(fname, cv.IMREAD_COLOR)
    im = cv.resize(im, (im.shape[1] * SCALE_FACTOR,
                         im.shape[0] * SCALE_FACTOR))
    s = get_landmarks(im)

    return im, s

def warp_im(im, M, dshape):
    output_im = numpy.zeros(dshape, dtype=im.dtype)
    cv.warpAffine(im,
                   M[:2],
                   (dshape[1], dshape[0]),
                   dst=output_im,
                   borderMode=cv.BORDER_TRANSPARENT,
                   flags=cv.WARP_INVERSE_MAP)
    return output_im

def correct_colours(im1, im2, landmarks1):
    blur_amount = COLOUR_CORRECT_BLUR_FRAC * numpy.linalg.norm(
                              numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) -
                              numpy.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
    blur_amount = int(blur_amount)
    if blur_amount % 2 == 0:
        blur_amount += 1
    im1_blur = cv.GaussianBlur(im1, (blur_amount, blur_amount), 0)
    im2_blur = cv.GaussianBlur(im2, (blur_amount, blur_amount), 0)

    # Avoid divide-by-zero errors.
    im2_blur += (128 * (im2_blur <= 1.0)).astype(im2_blur.dtype)

    return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /
                                                im2_blur.astype(numpy.float64))

im1, landmarks1 = read_im_and_landmarks(sys.argv[1])
im2, landmarks2 = read_im_and_landmarks(sys.argv[2])

M = transformation_from_points(landmarks1[ALIGN_POINTS],
                               landmarks2[ALIGN_POINTS])

mask = get_face_mask(im2, landmarks2)
warped_mask = warp_im(mask, M, im1.shape)
combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask],
                          axis=0)

warped_im2 = warp_im(im2, M, im1.shape)
warped_corrected_im2 = correct_colours(im1, warped_im2, landmarks1)

output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask

cv.imwrite('output.jpg', output_im)

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NO.55——Face Swapping with Python,dlib,openCV(换脸) 的相关文章

  • 使用 OpenCV 进行图像模糊检测

    我正在研究图像的模糊检测 我已经用过拉普拉斯方法的方差在 OpenCV 中 img cv2 imread imgPath gray cv2 cvtColor img cv2 COLOR BGR2GRAY value cv2 Laplacia
  • 提取二值图像中的最中心区域

    我正在处理二进制图像 之前使用此代码来查找二进制图像中的最大区域 Use the hue value to convert to binary thresh 20 thresh thresh img cv2 threshold h thre
  • 我的 Opencv 应用程序处理速度非常慢

    我正在构建一个 OpenCV 应用程序 它从相机捕获视频 并在删除背景后将其覆盖在另一个视频上 我无法达到合理的速度 因为它以大约 1 fps 的速度播放输出 而我的背景去除以 3 fps 的速度工作 有没有办法以正常速度显示背景视频并以
  • 针对不同处理器架构的 Gradle android 构建

    我想使用 Gradle 为 4 个不同的 Android CPU 处理器架构 armeabi armeabi v7a x86 mips 构建 4 个单独的 apk 我有为 4 个 CPU 架构构建的本机 OpenCV 库libs folde
  • Alpha 混合可消除图像中的接缝

    我缝合了两张图像 但在最终图像中存在可见的接缝 我正在尝试使用阿尔法混合去除那条接缝 我知道 Alpha 混合是使用cvAddweight 函数 但在此函数参数是两个图像 alpha beta gamma和目的地 我正在服用gamma 0
  • 静态 OpenCV 库中未定义的引用

    我有一个使用 OpenCV 3 1 的 C 项目 并且使用共享库可以正常工作 但现在我想使用静态库 位于项目目录中的文件夹中 来编译它 因为我希望能够在未安装 OpenCV 的情况下导出它 如果需要还可以编辑和重新编译 这次我重新编译了 O
  • OpenCV 地板分割检测

    我正在研究一种检测图像中地板的方法 我试图通过将图像缩小为颜色区域然后假设最大区域是地板来实现此目的 我们对机器人的运行环境做出一些相当广泛的假设 我正在寻找一些关于适合这个问题的算法的建议 任何帮助将不胜感激 编辑 具体来说 我正在寻找一
  • 在Spyder(Python 3.6)中导入cv2时出现导入错误

    我已经在Windows操作系统中安装了opencv 3 0 0 我已运行该应用程序并已成功将其安装在C 驱动器并还复制了cv2 pyd文件输入C Python27 Lib site packages正如我在几个教程视频中看到的那样 在我的
  • opencv不失真图像有一个奇怪的圆圈

    我尝试使用 opencv 针孔模型来计算校准参数 然后使图像不失真 问题是 未失真的图像中有一个奇怪的圆圈 如下所示 代码 原始图像和结果图像是here https github com wennycooper A004 pinhole 任
  • 使用“const cv::Mat &”、“cv::Mat &”、“cv::Mat”或“const cv::Mat”作为函数参数的区别?

    我已经彻底搜索过 但没有找到一个简单的答案 传递 opencv 矩阵 cv Mat 作为函数的参数 我们传递一个智能指针 我们对函数内部的输入矩阵所做的任何更改也会改变函数范围之外的矩阵 我读到 通过将矩阵作为 const 引用传递 它不会
  • opencv cmake安装的python包路径错误

    我一直在尝试遵循 opencv 安装步骤pyimagesearch com http www pyimagesearch com 2015 06 15 install opencv 3 0 and python 2 7 on osx 与虚拟
  • 使用 Xcode 为 OS X Lion / Mountain Lion 编译 OpenCV (2.3.1+)

    谁能给我提供一些如何使用 Xcode 在 OS X Lion 上编译 OpenCV 2 3 1 的详细指南 我对此很生气 我得到了源代码 使用 cmake 创建 Xcode 模板并尝试构建它 但它失败并出现大约 200 个错误 提前致谢 多
  • 在OpenCV Python中编写4通道以上图像

    这对我来说是一个持续的挑战 我正在尝试使用 openCV 将两个 3 RGB 图像组合成一个 6 通道 TIFF 图像 到目前为止我的代码如下 import cv2 import numpy as np im1 cv2 imread im1
  • OpenCV 中更新窗口的 waitKey() 的替代方法

    到目前为止我见过的所有示例和书籍都建议使用 waitKey 1 来强制重新绘制 OpenCV 窗口 这看起来很奇怪而且太老套了 不必要的时候为什么还要等待 1 毫秒呢 还有其他选择吗 我尝试了 cv updateWindow 但它似乎需要
  • OpenCV:处理每一帧

    我想使用 OpenCV 编写一个跨平台应用程序进行视频捕获 在所有示例中 我发现来自相机的帧是使用抓取功能进行处理并等待一段时间 我想处理序列中的每一帧 我想定义自己的回调函数 每次当一个新帧准备好处理时都会执行该函数 例如直播对于 Win
  • 如何使用 Python 3 在 OpenCV 3 上正确加载 cv2.KeyPoint 和描述符?

    有一天 我不得不恢复一个使用 OpenCV 3 和 Python 2 7 的旧项目 在此代码中 要加载 cv2 KeyPoint 我执行以下操作 import numpy as np import cPickle import cv2 ke
  • ECC 导致多光谱图像的图像对齐失败

    我正在尝试将 RGB 图像与 IR 图像 单通道 对齐 目标是创建 4 通道图像 R G B IR 为了做到这一点 我正在使用cv2 findTransformECC如中所述这个非常简洁的指南 https learnopencv com i
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • 使用 K 均值聚类 OpenCV 进行交通标志分割

    I used K Means Clustering to perform segmentation on this traffic sign as shown below 这些是我的代码 读取图像并模糊 img cv imread 000
  • 针对不同相机(RGB 和红外)的 StereoCalibrate

    我在校准两个摄像头时遇到问题 第一个是 RGB 第二个是红外 它们有不同的分辨率 我调整了大小并裁剪了更大的图像 焦距等等 例子 RGB 1920x1080 Infrared 512x424 如何相互校准它们 我应该在stereoCalib

随机推荐

  • 解决ssh免密登录Enter passphrase for key问题

    该问题的出现是由于在生成秘钥过程 即ssh keygen t rsa P 后面的 P代表验证秘钥的密码 相当于第二层所 当不小心弄错了 就会让你输入这里的字符 解决方案 1 输入 P 后面需要输入的字符 2 删掉 ssh文件下的公钥和秘钥
  • android 使用OPENGL ES实现地月模型(3D)-纹理映射基础

    效果图 编写Dad java 在构造器中设置场景渲染器为主动渲染 并声明地球与月球的引用 在绘制changing方法中绘制地球 月球 浩瀚星空 通过线程控制地球 月亮的转动 创建纹理贴图 package com scout eeeeeee
  • Executors类中创建线程池的几种方法的分析

    Executors类中创建线程池的几种方法的分析 要配置一个线程池是比较复杂的 尤其是对于线程池的原理不是很清楚的情况下 很有可能配置的线程池不是较优的 因此在Executors类里面提供了一些静态工厂 生成一些常用的线程池 1 newFi
  • 2023备战金三银四,Python自动化软件测试面试宝典合集(五)

    接上篇 八 抓包与网络协议 8 1 抓包工具怎么用 我原来的公司对于抓包这块 在 App 的测试用得比较多 我们会使用 fiddler 抓取数据检查结果 定 位问题 测试安全 制造弱网环境 如 抓取数据通过查看请求数据 请求行 请求报头 请
  • HTML——label标签

    label标签 是什么 label标签是HTML中的一个标签 用于为表单元素 如文本框 复选框等 提供标签或说明文本 通常与input标签配合使用 label标签可以通过for属性与相应的表单元素建立联系 这样当用户点击标签时 相应的表单元
  • 三、Python基础(高级变量类型篇)

    三 Python基础 高级变量类型篇 目录 三 Python基础 高级变量类型篇 一 列表 list 1 列表的定义 2 列表的常用方法和操作 对象 方法名 参数 3 for in对列表迭代遍历 4 利用 for in 的输出技巧 5 se
  • CPU占用100%的一般原因及解决办法

    转自 微点阅读 https www weidianyuedu com content 2517683835639 html 电脑关机故障速解 经常出现cPU占用100 的情况 主要问题可能发生在下面的某些方面 cPU占用率高的九种可能 1
  • 有奖调研

    历经五载 FISCO BCOS开源联盟链生态圈已汇聚超过3000家机构与企业 7万多名个人成员 大家秉持共建共享的开源精神 一同建设出FISCO BCOS在技术 应用和生态上的累累硕果 在这片天地里 我们与志同道合的伙伴交流技术 也发现了区
  • 关于类,你真的掌握了吗?(详细代码解读以及详细图解)

    目录 一 类和对象 二 类和类的实例化 三 类的成员 四 封装 五 构造方法 六 代码块 今日良言 既然选择了远方 便只顾风雨兼程 一 类和对象 1 类 具有相同特性 属性 和行为的对象的抽象 类是一个模板 2 对象 对象是人们要进行研究的
  • 多元线性回归方差分析表理解

    1 单因素一元方差分析的方法和案例 例子 案例的代码 X 533 580 525 600 570 650 500 因数I A F 实验组 CK标准 565 600 500 615 575 661 510 525 575 510 590 56
  • 四个视角,讲透额温枪应用设计中的运放问题

    3 月 12 号 世界卫生组织宣布新冠肺炎为全球性流行病 抗疫正从中国的 人民战争 变成一场 世界大战 很多事情正在微妙和快速的变化 额温枪和口罩一样 成为抗疫以及复产复工必不可少的日常用品 额温枪成了市场上炙手可热的产品 很多厂家开始步入
  • Top n 开源物理仿真引擎

    物理仿真引擎可以做为强化学习用 也可以做游戏等 列举主要几个开源的 pybullet Webots 开源早的 用户也多 比如 pybullet提供Python API 学习曲线较平缓 Nvidia的isaac 新开源不久 GPU支持好 Mu
  • 微信能上但浏览器无法上网

    微信能上但浏览器无法上网 问题描述 微信能聊天传文件 但是浏览器一直显示 未链接到互联网 问题描述 网络诊断提示 远程计算机或设备将不接受链接 出现这类问题 一般都是电脑打开了SSR代理服务 关闭了代理服务基本上就可以恢复正常上网了 解决方
  • Unity的C#编程教程_47_函数和方法

    C Functions and Methods Overview 1 Functions vs Methods 函数和方法其实就是一个东西 在 C 中通常称之为方法 方法 就是一块打包的代码 比如我们最常见的 就是在 Unity 中初始化
  • Mac git 命令自动提示

    1 首先安装配置Homebrew 注 如果已经安装过就跳过 在终端输入如下命令 usr bin ruby e curl fsSL https raw githubusercontent com Homebrew install master
  • 【GitLab】docker部署个人代码私服(开源gitlab)

    文章目录 前期准备 安装部署 拉取Gitlab镜像文件 创建容器挂在卷轴目录 运行镜像 修改配置文件 重启容器 使用说明 初次登陆 更改语言模式 创建新用户 邮件转发服务 总结 前期准备 准备一台CentOS7 8 以上版本的服务器 标配2
  • 编程题目:求二叉树的叶子结点个数(涉及前中序遍历,建树,叶子节点个数)

    以二叉链表作为二叉树的存储结构 求二叉树的叶子结点个数 输入格式 输入二叉树的先序序列 提示 一棵二叉树的先序序列是一个字符串 若字符是 表示该二叉树是空树 否则该字符是相应结点的数据元素 输出格式 输出有两行 第一行是二叉树的中序遍历序列
  • 关注深度学习代码

  • 【DA 03】Exploring Categorical Regularization for Domain Adaptive Object Detection (CVPR 2020)

    摘要 解决目标检测的域自适应问题 其中主要是source和target域之间的巨大差异 前人的工作主要在对齐image level和Instance level shifts Bias 07 DA Faster RCNN 然而 他们忽略去了
  • NO.55——Face Swapping with Python,dlib,openCV(换脸)

    摘要 早前看过国外博主的一篇用200行代码实现图像换脸操作的文章 主要通过仿射变换和调色的方法 原理呢 晦涩难懂 具体效果呢 其实也并不是很理想 至少要比直接调用Face 的人脸融合接口要差很多 用于学习图像处理相关的知识还是不错的 下一篇