關(guān)于圖像處理和Python深度學(xué)習(xí)的教程:第二部分
我們將以對比度增強(qiáng)開始第二部分。
6、對比度增強(qiáng)
某些類型的圖像(如醫(yī)學(xué)分析結(jié)果)對比度較低,很難發(fā)現(xiàn)細(xì)節(jié),如下所示:
xray = imread("images/xray.jpg")
xray_gray = rgb2gray(xray)
compare(xray, xray_gray)
在這種情況下,我們可以使用對比度增強(qiáng)使細(xì)節(jié)更加清晰。有兩種對比度增強(qiáng)算法:
對比度拉伸
直方圖均衡化
我們將在這篇文章中討論直方圖均衡化,它又有三種類型:
標(biāo)準(zhǔn)直方圖均衡化
自適應(yīng)直方圖均衡化
對比度受限自適應(yīng)直方圖均衡化(CLAHE)
直方圖均衡化將圖像對比度最高的區(qū)域擴(kuò)展到亮度較低的區(qū)域,使其均衡。
你可以通過從最高的像素值中減去最低的像素值來計(jì)算圖像的對比度。
>>> xray.max() - xray.min()
255
現(xiàn)在,讓我們嘗試exposure模塊中的標(biāo)準(zhǔn)直方圖均衡化:
from skimage.exposure import equalize_h(yuǎn)ist
enhanced = equalize_h(yuǎn)ist(xray_gray)
>>> compare(xray, enhanced)
我們已經(jīng)可以更清楚地看到細(xì)節(jié)了。
from skimage.exposure import equalize_h(yuǎn)ist
enhanced = equalize_h(yuǎn)ist(xray_gray)
>>> compare(xray, enhanced)
接下來,我們將使用CLAHE,它為圖像中的不同像素鄰域計(jì)算許多直方圖,即使在最暗的區(qū)域也會得到更詳細(xì)的信息:
from skimage.exposure import equalize_adapthist
# Adjust clip_limit
enhanced_adaptive = equalize_adapthist(xray_gray, clip_limit=0.4)
compare(xray, enhanced_adaptive, "Image with contrast enhancement")
這個看起來好多了,因?yàn)樗梢栽诒尘爸酗@示細(xì)節(jié),在左下角顯示更多缺失的肋骨。你可以調(diào)整clip_limit以獲得更多或更少的細(xì)節(jié)。
7、變換
數(shù)據(jù)集中的圖像可能有幾個相互沖突的特征,如不同的比例、未對齊的旋轉(zhuǎn)等。ML和DL算法希望你的圖片具有相同的形狀和尺寸。因此,你需要學(xué)習(xí)如何修復(fù)它們。
旋轉(zhuǎn)
要旋轉(zhuǎn)圖像,請使用“transform”模塊中的“rotate”函數(shù)。
from skimage.transform import rotate
clock = imread("images/clock.jpg")
clockwise = rotate(clock, angle=-60)
compare(clock, clockwise, "Clockwise rotated image, use negative angles")
anti_clockwise = rotate(clock, angle=33)
compare(clock, anti_clockwise, "Anticlockwise rotated image, use positive angles")
縮放
另一個標(biāo)準(zhǔn)操作是縮放圖像。
我們對此操作使用rescale函數(shù):
butterflies = imread("images/butterflies.jpg")
>>> butterflies.shape
(720, 1280, 3)
from skimage.transform import rescale
scaled_butterflies = rescale(butterflies, scale=3 / 4, multichannel=True)
compare(
butterflies,
scaled_butterflies,
"Butterflies scaled down by a factor of 3/4",
axis=True,
)
當(dāng)圖像分辨率較高時,縮小可能會導(dǎo)致質(zhì)量損失或像素不協(xié)調(diào),從而產(chǎn)生意外的邊或角。要考慮這種影響,可以將anti_aliasing設(shè)置為True,它使用高斯平滑:
https://gist.github.com/f7ae272b6eb1bce408189d8de2b71656
與之前一樣,平滑效果并不明顯,但在更細(xì)粒度的級別上會更明顯。
調(diào)整大小
如果希望圖像具有特定的寬度和高度,而不是按系數(shù)縮放,可以通過提供output_shape來使用resize函數(shù):
from skimage.transform import resize
puppies = imread("images/puppies.jpg")
# Also possible to set anti_aliasing
puppies_600_800 = resize(puppies, output_shape=(600, 800))
compare(puppies, puppies_600_800,
"Puppies image resized 600x800 (height, width)")
圖像恢復(fù)和增強(qiáng)
在文件變換、錯誤下載或許多其他情況下,某些圖像可能會失真、損壞或丟失。
在本節(jié)中,我們將討論一些圖像恢復(fù)技術(shù),從修復(fù)開始。
1、修補(bǔ)
修復(fù)算法可以智能地填補(bǔ)圖像中的空白。我找不到損壞的圖片,因此我們將使用此鯨魚圖像并手動在其上放置一些空白:
whale_image = imread("images/00206a224e68de.jpg")
>>> show(whale_image)
>>> whale_image.shape
(428, 1916, 3)
以下函數(shù)創(chuàng)建四個變黑區(qū)域,以模擬圖像上丟失的信息:
def make_mask(image):
"""Create a mask to artificially defect the image."""
mask = np.zeros(image.shape[:-1])
# Make 4 masks
mask[250:300, 1400:1600] = 1
mask[50:100, 300:433] = 1
mask[300:380, 1000:1200] = 1
mask[200:270, 750:950] = 1
return mask.a(chǎn)stype(bool)
# Create the mask
mask = make_mask(whale_image)
# Apply the defect mask on the whale_image
image_defect = whale_image * ~mask[..., np.newaxis]
compare(whale_image, image_defect, "Artifically damaged image of a whale")
我們將使用inpaint模塊中的inpaint_biharmonic函數(shù)來填充空白,并傳遞我們創(chuàng)建的掩碼:
from skimage.restoration import inpaint
restored_image = inpaint.inpaint_biharmonic(
image=image_defect, mask=mask, multichannel=True
)
compare(
image_defect,
restored_image,
"Restored image after defects",
title_original="Faulty Image",
)
正如你所看到的,在看到故障圖像之前,很難判斷缺陷區(qū)域在哪里。
現(xiàn)在,讓我們制造一些噪聲
2、噪聲
如前所述,噪聲在圖像增強(qiáng)和恢復(fù)中起著至關(guān)重要的作用。
有時,你可能會有意將其添加到如下圖像中:
from skimage.util import random_noise
pup = imread("images/pup.jpg")
noisy_pup = random_noise(pup)
compare(pup, noisy_pup, "Noise puppy image")
我們使用random_noise函數(shù)向圖像噴灑隨機(jī)的顏色斑點(diǎn)。因此,這種方法被稱為“鹽和胡椒(salt和 pepper)”技術(shù)。
3、降噪-去噪
但是,大多數(shù)情況下,你希望從圖像中移除噪聲,而不是添加噪聲。有幾種類型的去噪算法:
TV濾波器
雙邊去噪
小波降噪
非局部均值去噪
在本文中,我們將只看前兩個。我們先試試TV濾波器
from skimage.restoration import denoise_tv_chambolle
denoised_pup_tv = denoise_tv_chambolle(noisy_pup, weight=0.2, multichannel=True)
compare(
noisy_pup,
denoised_pup_tv,
"Total Variation Filter denoising applied",
title_original="Noisy pup",
)
圖像的分辨率越高,去噪所需的時間就越長。可以使用權(quán)重參數(shù)控制去噪效果。
現(xiàn)在,讓我們嘗試denoise_bilateral:
from skimage.restoration import denoise_bilateral
denoised_pup_bilateral = denoise_bilateral(noisy_pup, multichannel=True)
compare(noisy_pup, denoised_pup_bilateral, "Bilateral denoising applied image")
它不如TV濾波器有效,如下所示:
compare(
denoised_pup_tv,
denoised_pup_bilateral,
"Bilateral filtering",
title_original="TV filtering",
)
4、分割
圖像分割是圖像處理中最基本和最日常的主題之一,它廣泛應(yīng)用于運(yùn)動和目標(biāo)檢測、圖像分類等許多領(lǐng)域。
我們已經(jīng)看到了分割的一個實(shí)例—對圖像進(jìn)行閾值化以從前景中提取背景。
本節(jié)將學(xué)習(xí)更多內(nèi)容,例如將圖像分割為類似區(qū)域。
要開始分割,我們需要了解超級像素的概念。
一個像素本身只代表一小部分顏色,一旦與圖像分離,單個像素將毫無用處。因此,分割算法使用對比度、顏色或亮度相似的多組像素,它們被稱為超級像素。
一種試圖找到超像素的算法是簡單線性迭代聚類(SLIC),它使用k均值聚類。讓我們看看如何在skimage庫中提供的咖啡圖像上使用它:
from skimage import data
coffee = data.coffee()
>>> show(coffee)
我們將使用segmentation模塊中的slic函數(shù):
from skimage.segmentation import slic
segments = slic(coffee)
>>> show(segments)
默認(rèn)情況下,slic會查找100個線段或標(biāo)簽。要將它們放回圖像中,我們使用label2rgb函數(shù):
from skimage.color import label2rgb
final_image = label2rgb(segments, coffee, kind="avg")
>>> show(final_image)
讓我們將此操作包裝在函數(shù)中,并嘗試使用更多段:
from skimage.color import label2rgb
from skimage.segmentation import slic
def segment(image, n_segments=100):
# Obtain superpixels / segments
superpixels = slic(coffee, n_segments=n_segments)
# Put the groups on top of the original image
segmented_image = label2rgb(superpixels, image, kind="avg")
return segmented_image
# Find 500 segments
coffee_segmented_2 = segment(coffee, n_segments=500)
compare(coffee, coffee_segmented_2, "With 500 segments")
分割將使計(jì)算機(jī)視覺算法更容易從圖像中提取有用的特征。
5、等高線
對象的大部分信息都存在于其形狀中。如果我們能夠檢測出物體的線條或輪廓形狀,我們就可以提取出有價(jià)值的數(shù)據(jù)。
讓我們看看如何在實(shí)踐中使用多米諾骨牌圖像來尋找輪廓。
dominoes = imread("images/dominoes.jpg")
>>> show(dominoes)
我們將看看是否可以使用skimage中的find_contours函數(shù)來隔離瓷磚和圓。此函數(shù)需要一個二進(jìn)制(黑白)圖像,因此我們必須先對圖像設(shè)置閾值。
from skimage.measure import find_contours
# Convert to grayscale
dominoes_gray = rgb2gray(dominoes)
# Find optimal threshold with treshold_otsu
thresh = threshold_otsu(dominoes_gray)
# Binarize
dominoes_binary = dominoes_gray > thresh
domino_contours = find_contours(dominoes_binary)
生成的數(shù)組是(n,2)個數(shù)組的列表,表示等高線的坐標(biāo):
for contour in domino_contours[:5]:
print(contour.shape)
[OUT]:
(371, 2)
(376, 2)
(4226, 2)
(177, 2)
(11, 2)
我們將把操作包裝在一個名為mark_contours的函數(shù)中:
from skimage.filters import threshold_otsu
from skimage.measure import find_contours
def mark_contours(image):
"""A function to find contours from an image"""
gray_image = rgb2gray(image)
# Find optimal threshold
thresh = threshold_otsu(gray_image)
# Mask
binary_image = gray_image > thresh
contours = find_contours(binary_image)
return contours
要在圖像上繪制等高線,我們將創(chuàng)建另一個名為plot_image_contours的函數(shù),該函數(shù)使用上述函數(shù):
def plot_image_contours(image):
fig, ax = plt.subplots()
ax.imshow(image, cmap=plt.cm.gray)
for contour in mark_contours(image):
ax.plot(contour[:, 1], contour[:, 0], linewidth=2, color="red")
ax.a(chǎn)xis("off")
>>> plot_image_contours(dominoes)
正如我們所看到的,我們成功地檢測到了大部分輪廓,但我們?nèi)匀豢梢钥吹街行牡囊恍╇S機(jī)波動。
在將多米諾骨牌圖像傳遞到輪廓查找函數(shù)之前,先進(jìn)行去噪:
dominoes_denoised = denoise_tv_chambolle(dominoes, multichannel=True)
plot_image_contours(dominoes_denoised)
就是這樣!我們消除了大部分噪聲,這些噪聲導(dǎo)致輪廓線不正確!
高級操作1、邊緣檢測
之前,我們使用Sobel算法來檢測對象的邊緣。在這里,我們將使用Canny算法,因?yàn)樗、更?zhǔn)確,所以得到了更廣泛的應(yīng)用。一如既往,函數(shù)canny需要灰度圖像。
這一次,我們將使用具有更多硬幣的圖像,因此需要檢測更多邊緣:
coins_3 = imread("images/coins_3.jpg")
# Convert to gray
coins_3_gray = rgb2gray(coins_3)
compare(coins_3, coins_3_gray)
要找到邊緣,我們只需將圖像傳遞給canny函數(shù):
from skimage.feature import canny
# Find edges with canny
canny_edges = canny(coins_3_gray)
compare(coins_3, canny_edges, "Edges detected with Canny algorithm")
該算法發(fā)現(xiàn)了幾乎所有硬幣的邊緣,但由于硬幣上的雕刻也被檢測到,因此噪聲非常大。我們可以通過調(diào)整sigma參數(shù)來降低canny的靈敏度:
canny_edges_sigma_2 = canny(coins_3_gray, sigma=2.5)
compare(coins_3, canny_edges_sigma_2, "Edges detected with less intensity")
正如你所見,Canny現(xiàn)在只找到了硬幣的大致輪廓。
2、角點(diǎn)檢測
另一種重要的圖像處理技術(shù)是角點(diǎn)檢測。角點(diǎn)可以是圖像分類中對象的關(guān)鍵特征。
為了找到角點(diǎn),我們將使用Harris角點(diǎn)檢測算法。讓我們加載一個示例圖像并將其轉(zhuǎn)換為灰度:
windows = imread("images/windows.jpg")
windows_gray = rgb2gray(windows)
compare(windows, windows_gray)
我們將使用corner_h(yuǎn)arris函數(shù)生成一個測量圖像,該圖像屏蔽了角點(diǎn)所在的區(qū)域。
from skimage.feature import corner_h(yuǎn)arris
measured_image = corner_h(yuǎn)arris(windows_gray)
>>> show(measured_image)
現(xiàn)在,我們將此蒙版度量圖像傳遞給corner_peaks函數(shù),該函數(shù)這次返回角點(diǎn)坐標(biāo):
from skimage.feature import corner_peaks
corner_coords = corner_peaks(measured_image, min_distance=50)
>>> len(corner_coords)
79
該函數(shù)找到79個角點(diǎn)。讓我們將操作包裝到函數(shù)中:
def find_corner_coords(image, min_distance=50):
# Convert to gray
gray_image = rgb2gray(image)
# Produce a measure image
measure_image = corner_h(yuǎn)arris(gray_image)
# Find coords
coords = corner_peaks(measure_image, min_distance=min_distance)
return coords
現(xiàn)在,我們將創(chuàng)建另一個函數(shù),該函數(shù)使用上述函數(shù)生成的坐標(biāo)繪制每個角點(diǎn):
def show_image_cornered(image):
# Find coords
coords = find_corner_coords(image)
# Plot them on top of the image
plt.imshow(image, cmap="gray")
plt.plot(coords[:, 1], coords[:, 0], "+b", markersize=15)
plt.a(chǎn)xis("off")
show_image_cornered(windows)
不幸的是,該算法沒有按預(yù)期工作。標(biāo)記放置在磚的交叉處,而不是找到窗角。
這些是噪音,使它們毫無用處。讓我們對圖像進(jìn)行去噪處理,并再次將其傳遞給函數(shù):
windows_denoised = denoise_tv_chambolle(windows, multichannel=True, weight=0.3)
show_image_cornered(windows_denoised)
現(xiàn)在,這好多了!它找到了大部分窗戶角。
結(jié)論
在真正的計(jì)算機(jī)視覺問題中,你不會同時使用所有這些。正如你可能已經(jīng)注意到的,我們今天學(xué)到的東西并不復(fù)雜,最多需要幾行代碼。棘手的部分是將它們應(yīng)用于實(shí)際問題,并實(shí)際提高模型的性能。
感謝閱讀!
原文標(biāo)題 : 關(guān)于圖像處理和Python深度學(xué)習(xí)的教程:第二部分
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-10.29立即報(bào)名>> 2024德州儀器嵌入式技術(shù)創(chuàng)新發(fā)展研討會
-
10月31日立即下載>> 【限時免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報(bào)名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月14日立即報(bào)名>> 2024工程師系列—工業(yè)電子技術(shù)在線會議
-
12月19日立即報(bào)名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報(bào)名中>> OFweek2024中國智造CIO在線峰會
推薦專題
- 1 Intel宣布40年來最重大轉(zhuǎn)型:年底前裁員15000人、拋掉2/3房產(chǎn)
- 2 因美封殺TikTok,字節(jié)股價(jià)骨折!估值僅Meta1/5
- 3 宏山激光重磅發(fā)布行業(yè)解決方案,助力智能制造產(chǎn)業(yè)新飛躍
- 4 國產(chǎn)AI芯片公司破產(chǎn)!白菜價(jià)拍賣
- 5 具身智能火了,但規(guī)模落地還需時間
- 6 國產(chǎn)英偉達(dá)們,抓緊沖刺A股
- 7 三次錯失風(fēng)口!OpenAI前員工殺回AI編程賽道,老東家捧金相助
- 8 英特爾賦能智慧醫(yī)療,共創(chuàng)數(shù)字化未來
- 9 英偉達(dá)的麻煩在后頭?
- 10 將“網(wǎng)紅”變成“商品”,AI“爆改”實(shí)力拉滿
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市