2016-11-30 61 views
6

如何勾勒matplotlib中的像素邊界?例如,對於一個半隨機數據集類似下面,matplotlib輪廓可以匹配像素邊緣嗎?

# the code block that follows is irrelevant 
import numpy as np 
k = [] 
for s in [2103, 1936, 2247, 2987]: 
    np.random.seed(s) 
    k.append(np.random.randint(0, 2, size=(2,6))) 
arr = np.hstack([np.vstack(k)[:, :-1], np.vstack(k).T[::-1].T ]) 
image = np.zeros(shape=(arr.shape[0]+2, arr.shape[1]+2)) 
image[1:-1, 1:-1] = arr 

這是很清楚的是匹配的image像素邊緣的輪廓將是優選的輪廓功能,其中的默認行爲等高線被有效地繪製在邊緣像素的對角線上。

import matplotlib.pyplot as plt 
plt.contour(image[::-1], [0.5], colors='r') 

binary_invader

如何使輪廓與像素對齊?我正在尋找numpymatplotlib庫中的解決方案。

+0

我想知道你是怎麼想出這些種子吸取這個特殊的圖片嗎? – Andyk

+0

@Andyk沒有什麼奇特的 - 只是重複隨機抽樣,直到找到所需的種子。 –

回答

5

如果圖像的分辨率爲每個單元1個像素,那麼您如何定義像素的「邊緣」? 「邊緣」的概念只有在與像素本身相比分辨率提高的框架中才有意義,如果它與圖像本身具有相同的解決方案,則不能繪製任何邊緣。

另一方面,當然可以增加分辨率,使得概念「邊緣」具有含義。假設我們將分辨率提高100倍,我們可以使用contour圖很容易地繪製邊緣。

import matplotlib.pyplot as plt 
import numpy as np 

k = [] 
for s in [2103, 1936, 2247, 2987]: 
    np.random.seed(s) 
    k.append(np.random.randint(0, 2, size=(2,6))) 
arr = np.hstack([np.vstack(k)[:, :-1], np.vstack(k).T[::-1].T ]) 
image = np.zeros(shape=(arr.shape[0]+2, arr.shape[1]+2)) 
image[1:-1, 1:-1] = arr 


f = lambda x,y: image[int(y),int(x) ] 
g = np.vectorize(f) 

x = np.linspace(0,image.shape[1], image.shape[1]*100) 
y = np.linspace(0,image.shape[0], image.shape[0]*100) 
X, Y= np.meshgrid(x[:-1],y[:-1]) 
Z = g(X[:-1],Y[:-1]) 

plt.imshow(image[::-1], origin="lower", interpolation="none", cmap="Blues") 

plt.contour(Z[::-1], [0.5], colors='r', linewidths=[3], 
      extent=[0-0.5, x[:-1].max()-0.5,0-0.5, y[:-1].max()-0.5]) 

plt.show() 

enter image description here

爲了便於比較,我們還可以使用imshow繪製圖像本身在同一個情節。

+0

不錯,我沒有想到在擴展電網上製作輪廓。爲什麼'imshow'和'contour'之間不匹配?它可以更好地顯示分辨率提高'10'而不是'100'。 –

+1

關於像素邊緣的定義 - 我想說,沒有什麼能夠阻止我們定義'x'和'y'等於'0.5,1.0,1.5,...'網格線的像素邊緣。這些線條可以用一個基本的'Line2d'繪製。 –