版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35406909/article/details/83548694
密度图表现与数据值对应的边界或域对象的一种理论图形表示方法。一般用于呈现连续变量。
*摘自百度百科*
在计算机科学当中,数据的可视化常常被提起。近日,在图像处理当中,需要统计图片中的人流密度并绘制相应密度图,于是小小研究一番。效果如下:
所有代码保存在Github上。
首先需要一张颜色表,从上至下分别表示密度多少时颜色的深浅。在我的程序当中,颜色表保存在map.mat当中。
接下来就是求密度了。当获得了人头的位置之后,我们可以假设光线从头的四周向外发射,光强度分布服从二维高斯分布。这样,某点的光强
其中,k是小于0的常数,R是高斯分布的半径,dis为人头到当前点的距离。当dis=0,也就是当前点处在人头中心时,T取最大值1.
将所有人头的密度累加,与颜色表一一对应,就得到了密度图。
奉上代码:
import numpy as np
import scipy.io as sio
import cv2
import os
path = 'D:\\OJ\\OpenCV_Projects\\2_crowd_density_map\\data\\test_data\\ground_truth\\GT_IMG_'
ipath = 'D:\\OJ\\OpenCV_Projects\\2_crowd_density_map\\data\\test_data\\images\\IMG_'
len = 182
R = 50
r = np.sqrt((R//2)**2*2)
mp = sio.loadmat('./map.mat')
mp = mp['c']
mp = mp[::-1]
out_path = './density_map/'
if not os.path.exists(out_path):
os.mkdir(out_path)
for i in range(1,len+1):
now_path = path+''+str(i)+'.mat'
data = sio.loadmat(now_path)
P = data['image_info']
n = P[0][0][0][0][1][0][0]
P = P[0][0][0][0][0]
image_path = ipath+str(i) + '.jpg'
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
N = img.shape[0]
M = img.shape[1]
den_map = np.zeros([N, M, 3], dtype=np.float)
tot = np.zeros([N, M], dtype=np.float)
for j in range(n):
y = int(P[j][0])
x = int(P[j][1])
for X in range(x-R//2,x+R//2+1):
if X < 0 or X >= N:
continue
for Y in range(y-R//2,y+R//2+1):
if Y < 0 or Y >= M:
continue
dis = np.sqrt((X-x) ** 2 + (Y-y) ** 2)
add = np.exp(dis*(-4)/r)
# if j == 1:
# print(add)
tot[X][Y] += add
max_den=tot.max()
for X in range(N):
for Y in range(M):
pixel = 255*tot[X][Y]/max_den
den_map[X][Y] = mp[int(pixel)] * 255
den_map[X][Y] = [int(ele) for ele in den_map[X][Y]]
cv2.imwrite(out_path + 'density_map_' + str(i) + '.jpg', den_map)
print(str(i)+'\\'+str(len))