gpt4 book ai didi

python - 如何从具有许多不同前景的图像中提取任意背景矩形 block

转载 作者:行者123 更新时间:2023-12-02 16:58:00 24 4
gpt4 key购买 nike

  • 我正在处理 FDDB-DataSet从同一张图像中提取人脸和相同数量的背景。
  • 我能够得到面孔(从注释的坐标)。
  • 我的问题是:
    我想裁剪具有相同数量的面孔(不一定相同大小)的免费补丁,
    背景的限制是:
  • 任何背景图像的大小应不小于 20 x 20 像素。
  • 与面(其中任何一个)的最大重叠率(IOU:Intersection over Union)不应超过 20% (0.2)。
  • 背景补丁的数量应与同一图像中的人脸数量相同。

  • 示例图片:
    Sample
    Background
    注释数据:
    [Rmax Rmin theta Xc Yc]
    [[ 52  38   1 154  72]
    [ 57 38 -2 368 103]
    [ 14 9 -2 11 64]
    [ 11 8 1 29 16]
    [ 10 6 1 56 61]
    [ 10 6 -2 68 66]
    [ 14 9 1 46 126]
    [ 15 11 1 21 192]
    [ 22 12 1 11 157]
    [ 13 9 1 267 133]
    [ 19 13 1 312 186]
    [ 12 9 1 300 19]
    [ 11 9 -2 334 139]
    [ 14 10 -2 437 87]
    [ 11 8 1 232 27]]
    我的代码是:
    #--------------------
    # Import Libraies
    #====================
    import numpy as np
    import matplotlib.pyplot as plt
    import os
    import cv2

    datasetPath = "/home/myPath"
    #---------------------------------------------
    # Extract faces, and Backgrounds from an image
    #=============================================
    def extData(imgPath, annots, foldPath, index):
    '''
    Function to Extract faces, and Backgrounds from an image.

    Parameters:
    @Param: imgPath : the specified image path(inside the DB).
    @Param: annots : nd-array with shape m x 5, : m num of the detected faces in the image.
    (5): max_radius | min_radius | angle | center_x | center_y
    @Param: foldPath : the fold path where to save the extracted images.
    @Param: index : a number to start naming the faces, backgrounds from it.

    saves: m nd-array (m Faces), and m nd-array (m Background) in the foldPath
    '''
    fullImagePath = os.path.join(datasetPath, imgPath)
    img = cv2.imread(fullImagePath)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # Create Faces
    facesList = []
    for row in range(annots.shape[0]):
    # Initialize the Variables
    xc = annots[row][3]
    yc = annots[row][4]
    Rmax = annots[row][0]
    Rmin = annots[row][1]
    theta = annots[row][2]

    # Rectangle Borders
    # represents the top left corner of rectangle
    x0 = math.floor(xc - Rmin * math.sin(theta))
    y0 = math.floor(yc - Rmax * math.sin(theta))
    # represents the bottom right corner of rectangle
    x1 = math.floor(xc + Rmin * math.sin(theta))
    y1 = math.floor(yc + Rmax * math.sin(theta))
    # Crop the face in rectangular window
    face = img[y0:y1, x0:x1,:]
    # store the coordinates of the face
    facesList.append([x0, x1, y0, y1])
    # make a directory to save the faces inside.
    os.mkdir(os.path.join(foldPath,"/face/"))
    cv2.imwrite(os.path.join(foldPath,"/face/", "face_{}".format(str(index+row)),face))

    # Create Backgrounds
    for row, face in enumerate(facesList):

    # background = img[xb1:xb2,yb1:yb2,:]
    # make a directory to save the backgrounds inside.
    os.mkdir(os.path.join(foldPath,"/background/"))
    # cv2.imwrite(os.path.join(foldPath,"/background/", "background_{}".format(str(index+row)),background))
    #---------------------------------------------

    最佳答案

    您可以使用 cv2.distanceTransform 计算到人脸的 L1 距离,并根据距离对矩形中心进行采样,从而确保裁剪不会与“人脸”重叠:

    import numpy as np

    img = cv2.imread(fullImagePath)
    # create a mask with zeros in "faces" and bonudary
    mask = np.zeros(img.shape[:2], dtype=np.uint8)
    mask[1:-1, 1:-1] = 1
    for row in range(annots.shape[0]):
    # Initialize the Variables
    xc = annots[row][3]
    yc = annots[row][4]
    Rmax = annots[row][0]
    Rmin = annots[row][1]
    theta = annots[row][2]
    # in case of rotation angles more than 45 degrees swap radius
    if(theta > 45):
    R = Rmax
    Rmax = Rmin
    Rmin = R
    # Rectangle Borders
    # represents the top left corner of rectangle
    st = math.sin(theta)
    st = st if st > 0 else -st
    x0 = math.floor(xc - Rmin * st)
    y0 = math.floor(yc - Rmax * st)
    # represents the bottom right corner of rectangle
    x1 = math.floor(xc + Rmin * st)
    y1 = math.floor(yc + Rmax * st)
    # Crop the face in rectangular window
    mask[y0:y1, x0:x1] = 0

    # once we have a map we can compute the distance of each non-face pixel to the nearest face
    dst = cv2.distanceTransform(mask, cv2.DIST_L1, 3)

    # pixels that are closer than 10 pixels (20//2) to a face, cannot be considered as good candidates. If you allow for IoU > 0 this can be relaxed a little.
    dst[dst<10] = 0

    # linear indices of pixels
    idx = np.arange(np.prod(img.shape[:2]))

    # sample centers
    centers = np.random.choice(idx, size=annots.shape[0], replace=False, p=dst.flatten()/dst.sum())

    # create the rectangles
    windows = []
    for i, c in enumerate(centers):
    r = int(np.floor(dst.flat[c]))
    r = np.random.choice(range(10,r)) # sample possible R from 10 to max possible
    [y, x] = np.unravel_index(c, img.shape[:2])
    windows.append((y-r, x-r, y+r, x+r))

    此处显示了结果窗口的示例:
    enter image description here

    关于python - 如何从具有许多不同前景的图像中提取任意背景矩形 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64407310/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com