密度图处理

在AI Stdio上碰到一个计算人流密度的项目,其中baseline使用的方法是将人像框变成密度函数。首先将人相框转化为点,即将方框标注变为点标注

''
图片操作:对图片进行resize、归一化,将方框标注变为点标注
返回:resize后的图片 和 gt
'''
def picture_opt(img,ann):
    size_x,size_y = img.size
    train_img_size = (640,480)
    img = img.resize(train_img_size,Image.ANTIALIAS)
    img = np.array(img)                  
    img = img / 255.0

    gt = []
    for b_l in range(len(ann)):
        # 假设人体是使用方框标注的,通过求均值的方法将框变为点
        if 'w' in ann[b_l].keys(): 
            x = (ann[b_l]['x']+(ann[b_l]['x']+ann[b_l]['w']))/2
            y = ann[b_l]['y']+20
            x = (x*640/size_x)/8
            y = (y*480/size_y)/8
            gt.append((x,y))   
        else:
            x = ann[b_l]['x']
            y = ann[b_l]['y']
            x = (x*640/size_x)/8
            y = (y*480/size_y)/8
            gt.append((x,y)) 
   
    return img,gt

上述代码实现将图片的框标注转化为点标注,返回的是点的二维坐标和归一化,resize之后的图片,再将图片和点标注进行密度图处理,代码如下


'''
使用高斯滤波变换生成密度图
'''
#gt为一些点的集合
def gaussian_filter_density(gt):
   
    # 初始化密度图
    density = np.zeros(gt.shape, dtype=np.float32)
    
    # 获取gt中不为0的元素的个数
    gt_count = np.count_nonzero(gt)
    
    # 如果gt全为0,就返回全0的密度图
    if gt_count == 0:
        return density
    
    pts = np.array(list(zip(np.nonzero(gt)[1].ravel(), np.nonzero(gt)[0].ravel())))
    

    for i, pt in enumerate(pts):
        pt2d = np.zeros(gt.shape, dtype=np.float32)
        pt2d[pt[1],pt[0]] = 1.
        if gt_count > 1:
            # sigma = (distances[i][1]+distances[i][2]+distances[i][3])*0.1
            sigma = 25
        else:
            sigma = np.average(np.array(gt.shape))/2./2. 
        
        density += scipy.ndimage.filters.gaussian_filter(pt2d, sigma, mode='constant')

    return density
'''
密度图处理
'''
def ground(img,gt):
    imgs = img
    x = imgs.shape[0]/8
    y = imgs.shape[1]/8
    k = np.zeros((int(x),int(y)))#定义一个大小与图片尺寸一样的矩阵

    for i in range(0,len(gt)):
        if int(gt[i][1]) < int(x) and int(gt[i][0]) < int(y):
            k[int(gt[i][1]),int(gt[i][0])]=1

    k = gaussian_filter_density(k)
    return k


ig_cv_img2 = cv2.imread(content['annotations'][1]['name'])
ig_img2 = Image.fromarray(cv2.cvtColor(ig_cv_img2,cv2.COLOR_BGR2RGB))   #cv2转PIL
ann = content['annotations'][1]['annotation']                    #把所有标注的信息读取出来
                                               
ig_im,gt = picture_opt(ig_img2,ann)
plt.figure(1)
plt.imshow(ig_im)
k = ground(ig_im,gt)
groundtruth = np.asarray(k)

plt.figure(2)
plt.imshow(groundtruth,cmap=CM.jet)
groundtruth = groundtruth.T.astype('float32')
ig_im = ig_im.transpose().astype('float32') 

处理之后得到的密度图如下:

在这里插入图片描述
密度图处理_第1张图片
密度图处理_第2张图片

你可能感兴趣的:(python,计算机视觉)