skimage例子學習(六)局部直方圖均衡化

skimage例子學習(六)局部直方圖均衡化

來自專欄 skimage圖像處理學習

小師弟揉著稀鬆的雙眼,晃晃悠悠朝練功房走去。

剛走到門口,裡面一幕讓小師弟睡意全無,裡面在做什麼呢?

房間里有人舞著從未見過的招式,而且每一招在擊中要害的同時也不失優雅。定睛一看,原來是大師兄。大師兄彷彿也看到了小師弟,放下手中的「傢伙」朝小師弟走來。

大,大,大……大師兄好。小師弟戰戰兢兢的說,不知是因為沒有睡好,還是被大師兄的霸氣所震懾到了。

大師兄摸著小師弟的頭,等等,大師兄為什麼要摸著小師弟的頭呢?因為小師弟矮啊,這點小師弟也很無奈啊。

大師兄:小師弟早啊,最近小師弟在做什麼呢?在練功房好像很少看到師弟啊。

雖然大師兄面帶微笑,但總覺得每一句話都帶著殺氣……

小師弟:大,大,大……大師兄,前段時間學習了skimage例子學習(五)exposure模塊介紹及直方圖均衡化,如果師兄方便的話還可以去指導下。

最近還和二師兄一起做了Carvana Image Masking Challenge的比賽,拖了師兄的後腿,最後只是top10%。

(顯然,小師弟還是有些怕大師兄的。)

大師兄:小師弟加油啊,做比賽的同時,還是不要忘記基礎哈,而且聽說你們又準備開始做Cdiscount』s Image Classification Challenge了,啊哈哈哈哈哈哈。

大師兄拂袖而去……

小師弟好似明白了大師兄的言外之意,這不,又開始練習局部直方圖均衡化了。

上節學習的直方圖均衡化是全局性的,在某種意義上,像素被基於整幅圖像的灰度分布的變換函數修改,雖然這種全局方法適用於整個圖像的增強,但存在增強圖像這小區域的細節的需要。

在這些區域中,一些像素的影響在全局變換的計算中可能被忽略,因為全局變換沒有必要保證期望的局部增強,解決辦法是從圖像中每個像素的鄰域中的灰度分布為基礎設計變換函數。

下面我們就來看下局部直方圖均衡化。

為了便於我們接下來的實現,我們首先定義一個函數,該函數主要為了顯示圖片、直方圖、累積分布函數。代碼如下:

matplotlib.rcParams[font.size] = 9 #修改配置文件中的參數def plot_img_and_hist(image, axes, bins=256): ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() # 顯示圖片 ax_img.imshow(image, cmap=plt.cm.gray) ax_img.set_axis_off() # 顯示直方圖 ax_hist.hist(image.ravel(), bins=bins) ax_hist.ticklabel_format(axis=y, style=scientific, scilimits=(0, 0)) ax_hist.set_xlabel(Pixel intensity) xmin, xmax = dtype_range[image.dtype.type] ax_hist.set_xlim(xmin, xmax) # 顯示累積分布函數 img_cdf, bins = exposure.cumulative_distribution(image, bins) ax_cdf.plot(bins, img_cdf, r) return ax_img, ax_hist, ax_cdf

配置文件的說明:

有心的讀者可以看到,上段代碼有行matplotlib.rcParams,這是對配置文件的修改。

這是因為matplotlib使用rcParams中的配置進行繪圖,用戶可以直接修改此字典中的配置,所做的改變會反映到此後所繪製的圖形中。

具體的說明和一些例子,可參考鏈接。

下面我們就來對比下全部均衡化處理和局部均衡化處理的直方圖和圖像的差異,這裡我們使用的是圓形濾波器來做局部均衡化處理。

在skimage庫中,主要通過filters,模塊進行濾波操作。

代碼如下:

img = img_as_ubyte(data.moon())#全局均衡化img_rescale = exposure.equalize_hist(img)#局部均衡化selem = disk(30)#結構化元素,用於設定濾波器,半徑為30的圓形濾波器img_eq = rank.equalize(img, selem=selem)#均衡化濾波。利用局部直方圖對圖像進行均衡化濾波#顯示結果fig = plt.figure(figsize=(8, 5))axes = np.zeros((2, 3), dtype=np.object)axes[0, 0] = plt.subplot(2, 3, 1, adjustable=box-forced)axes[0, 1] = plt.subplot(2, 3, 2, sharex=axes[0, 0], sharey=axes[0, 0], adjustable=box-forced)axes[0, 2] = plt.subplot(2, 3, 3, sharex=axes[0, 0], sharey=axes[0, 0], adjustable=box-forced)axes[1, 0] = plt.subplot(2, 3, 4)axes[1, 1] = plt.subplot(2, 3, 5)axes[1, 2] = plt.subplot(2, 3, 6)ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])ax_img.set_title(Low contrast image)ax_hist.set_ylabel(Number of pixels)ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])ax_img.set_title(Global equalise)ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])ax_img.set_title(Local equalize)ax_cdf.set_ylabel(Fraction of total intensity)# 防止y軸坐標溢出fig.tight_layout()plt.show()

結果如下:

看來小師弟還是沒有睡醒,這不,練到這裡就有點懈怠了。

想看小師弟看的是哪本秘籍?請參閱skimage官網例子


推薦閱讀:

圖片,還可以這樣玩兒
如果你的內存比較小
[計算機視覺論文速遞] 2018-04-23
數字圖像處理基礎:教你如何區分單色圖像、灰度圖像、偽彩色圖像、真彩色圖像
數字圖像處理入門學習筆記(綜述)

TAG:圖像處理 | 計算機視覺 | Python庫 |