1. 程式人生 > >Python資料視覺化之密度圖的繪製

Python資料視覺化之密度圖的繪製

密度圖表現與資料值對應的邊界或域物件的一種理論圖形表示方法。一般用於呈現連續變數。

*摘自百度百科*

在電腦科學當中,資料的視覺化常常被提起。近日,在影象處理當中,需要統計圖片中的人流密度並繪製相應密度圖,於是小小研究一番。效果如下:


所有程式碼儲存在Github上。

首先需要一張顏色表,從上至下分別表示密度多少時顏色的深淺。在我的程式當中,顏色表儲存在map.mat當中。

接下來就是求密度了。當獲得了人頭的位置之後,我們可以假設光線從頭的四周向外發射,光強度分佈服從二維高斯分佈。這樣,某點的光強 T

= e k d i s
R
T=e^{k* \frac{dis}{R}}
其中,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))