Python資料視覺化之密度圖的繪製
阿新 • • 發佈:2018-11-18
密度圖表現與資料值對應的邊界或域物件的一種理論圖形表示方法。一般用於呈現連續變數。
*摘自百度百科*
在電腦科學當中,資料的視覺化常常被提起。近日,在影象處理當中,需要統計圖片中的人流密度並繪製相應密度圖,於是小小研究一番。效果如下:
所有程式碼儲存在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))