精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

圖像增強的主要方法及其Python實現

zhKF_jqr_AI ? 來源:未知 ? 作者:李倩 ? 2018-06-30 10:07 ? 次閱讀

編者按:倫敦帝國學院計算成像PhD學生Rob Robinson介紹了圖像增強的主要方法及其Python實現。

進行有效的深度學習網絡訓練的最大限制因素是訓練數據。為了很好地完成分類任務,我們需要給我們的CNN等模型盡可能多的樣本。然而,并不是所有情況下都可能做到這一點,特別是處于一些訓練數據很難收集的情形,比如醫學影像數據。在本文中,我們將學習如何應用數據增強策略至n維圖像,以充分利用數量有限的樣本。

介紹

如果我們將任何圖像(比如下面的機器人)整體向右移動一個像素,視覺上幾乎毫無差別。然而,數值上這是兩張完全不同的圖像!想象一下有一組10張這樣的圖像,每張相對前一張平移一個像素。現在考慮圖像[20, 25]處的像素或某個任意的位置。聚焦到這一點,每個像素有不同的顏色,不同的周邊平均亮度,等等。一個CNN在進行卷積和決定權重時,會將這些考慮在內。如果我們將這組10張圖像傳給CNN,應該能夠有效地讓CNN學習忽略這類平移。

原圖

向右平移1像素

向右平移10像素

當然,平移不是在保證視覺上看起來一樣的前提下改動圖像的唯一方式。考慮下將圖片旋轉1度,或者5度。它仍然是機器人。用不帶平移和旋轉版本的圖像訓練CNN可能導致CNN過擬合,認為所有機器人的圖像都是不偏不倚的。

給深度學習模型提供平移、旋轉、縮放、改變亮度、翻轉的圖像,我們稱之為數據增強。

在本文中,我們將查看如何應用這些變換至圖像,包括3D圖像,及其對深度學習模型表現的影響。我們將使用flickr用戶andy_emcee拍攝的照片作為2D自然圖像的樣本。由于這是一幅RGB(彩色)圖像,因此它的形狀為[512, 640, 3],每層對應一個色彩頻道。我們可以抽掉一層,將圖像轉為灰度圖像(真2D),不過我們處理的大部分圖像都是彩色圖像,因此我們這里保留原樣。我們將使用3D MRI掃描圖作為3D圖像的樣本。

RGB圖像

增強

我們將使用python編寫數據增強函數(基于numpy和scipy)。

平移

在我們的函數中,圖像是一個2D或3D數組——如果它是一個3D數組,我們需要小心地在offset參數中指定方向。我們并不想在z方向上移動,原因如下:首先,如果這是一個2D圖像,第三維將是色彩頻道,如果我們在這一維度上移動了-2、2或更多,整個圖像將變成全紅、全藍或全黑;其次,在全3D圖像中,第三維常常是最小的,例如,在大多數醫學掃描圖像中。在下面的平移函數中,offset是一個長度為2的數組,定義了y和x方向的平移。我們硬編碼z方向為0,不過,根據你的具體情況,你可以加以改動。為了確保我們平移的像素是整數,我們強制使用int。

def translateit(image, offset, isseg=False):

order = 0if isseg == Trueelse5

return scipy.ndimage.interpolation.shift(image, (int(offset[0]), int(offset[1]), 0), order=order, mode='nearest')

當我們平移圖像時,會在圖像邊緣留下一條縫隙。我們需要找到填補這一縫隙的方式:shift默認將使用一個常量(0)。但在某些情況下,這可能無濟于事,所以最好將mode設為nearest,使用鄰近的像素值填充。平移值較小時,幾乎難以察覺這一點。不過平移值較大時,看起來就不對勁了。所以我們需要小心,僅對我們的數據應用較小的平移。

另外,我們提供了一個布爾值選項isseg,供選擇order參數的值。isseg為真時(處理分割圖),order為0,也就是直接使用最近的像素值填充;isseg為假時,order為5,也就是進行5次B樣條插值(綜合考量目標周圍的許多像素)。

原圖

右移5像素

右移25像素

原圖、分割圖

平移[-3, 1]像素

平移4, -5像素

縮放

我們根據一個特定的倍數(factor)縮放圖像。倍數大于1.0時,放大圖像;倍數小于1.0時,縮小圖像。注意我們需要為每個維度指定倍數:其中,最后一個維度(2D圖像中為色彩頻道)倍數為1.0。我們使用柵格(網格)來決定結果圖像每個像素的亮度(使用周圍像素的亮度進行插值)。scipy提供了一個方便的函數,稱為zoom。

定義大概要比你想象的復雜:

def scaleit(image, factor, isseg=False):

order = 0if isseg == Trueelse3

height, width, depth= image.shape

zheight = int(np.round(factor * height))

zwidth = int(np.round(factor * width))

zdepth = depth

if factor < 1.0:

newimg = np.zeros_like(image)

row = (height - zheight) // 2

col = (width - zwidth) // 2

layer = (depth - zdepth) // 2

newimg[row:row+zheight, col:col+zwidth, layer:layer+zdepth] = interpolation.zoom(image, (float(factor), float(factor), 1.0), order=order, mode='nearest')[0:zheight, 0:zwidth, 0:zdepth]

return newimg

elif factor > 1.0:

row = (zheight - height) // 2

col = (zwidth - width) // 2

layer = (zdepth - depth) // 2

newimg = interpolation.zoom(image[row:row+zheight, col:col+zwidth, layer:layer+zdepth], (float(factor), float(factor), 1.0), order=order, mode='nearest')

extrah = (newimg.shape[0] - height) // 2

extraw = (newimg.shape[1] - width) // 2

extrad = (newimg.shape[2] - depth) // 2

newimg = newimg[extrah:extrah+height, extraw:extraw+width, extrad:extrad+depth]

return newimg

else:

return image

我們需要考慮三種可能性——放大、縮小、不變。在每種情形下,我們想要返回與輸入圖像尺寸相等的數組??s小時,這牽涉創建一張大小形狀和輸入圖像一致的空圖像,并在當中相應的位置放入縮小后的圖像。放大時,不需要放大整張圖像,只需放大“縮放”的區域——因此我們只將數組的一部分傳給zoom函數。取整可能造成最終形狀中的一些誤差,所以我們在返回圖像前進行了一些修剪。不縮放時,我們返回原圖。

原圖

原圖、分割圖

縮放倍數1.07

縮放倍數0.95

重采樣

有時我們需要修改圖像,使其符合CNN的輸入格式要求。例如,對大多數圖像和照片而言,一個維度比另一個維度大,或者分辨率參差不齊。而大多數CNN需要尺寸一致的正方形輸入。我們同樣可以使用scipy函數interpolation.zoom辦到這一點:

def resampleit(image, dims, isseg=False):

order = 0if isseg == Trueelse5

image = interpolation.zoom(image, np.array(dims)/np.array(image.shape, dtype=np.float32), order=order, mode='nearest')

if image.shape[-1] == 3: # rgb圖像

return image

else:

return image if isseg else (image-image.min())/(image.max()-image.min())

這里的關鍵部分是我們將factor參數替換為類型為列表的dims參數。dims的長度應當和圖像的維度相等,即,2或3. 我們計算每個維度需要改變的倍數以將整個圖像變動到dims目標。

在這一步中,當圖像不是分割圖時,我們同時將圖像的亮度轉換至0.0至1.0區間,以確保所有圖像的亮度位于同一區間。

旋轉

我們利用了另一個scipy函數rotate。它的theta參數接受一個浮點數,用來指定旋轉的角度(負數表示逆時針旋轉)。我們想要返回和輸入圖像大小和形狀相同的圖像,因此使用了reshape = False。同樣,我們需要指定order決定插值方法。rotate函數支持3D圖像,使用相同的theta值旋轉每個切片。

def rotateit(image, theta, isseg=False):

order = 0if isseg == Trueelse5

return rotate(image, float(theta), reshape=False, order=order, mode='nearest')

原圖

theta = -10.0

theta = 10.0

原圖、分割圖

theta = 6.18

theta = -1.91

亮度變動

我們還可以縮放像素的亮度,也就是加亮或壓暗圖像。我們指定一個倍數:倍數小于1.0將壓暗圖像;倍數大于1.0將加亮圖像。注意倍數不能為0.0,否則會得到全黑的圖像。

def intensifyit(image, factor):

return image*float(factor)

翻轉

對自然圖像(狗、貓、風景等)而言,最常見的圖像增強過程是翻轉。其依據是不管狗朝向哪一邊,始終是狗。不管樹在右邊還是在左邊,它仍然是一棵樹。

我們可以進行左右翻轉,也可以進行上下翻轉。有可能只有一種翻轉有意義(比如,我們知道狗不能通過它們的頭行走)。我們通過由2個布爾值組成的列表指定如何進行翻轉:如果每個值都是1,那么同時進行兩種翻轉。我們使用numpy函數fliplr和flipup。

def flipit(image, axes):

if axes[0]:

image = np.fliplr(image)

if axes[1]:

image = np.flipud(image)

return image

剪切

這可能是一個小眾的函數,但在我的案例中很重要。處理自然圖像時,常常在圖像上進行隨機剪切,以得到補丁——這些補丁常常包含大部分圖像數據,例如,基于299 x 299圖像得到的224 x 224補丁。這不過是另一種給網絡提供視覺上非常相似而數值上完全不同的圖像的方法。同時也進行中央剪切。我的案例有一個不同的需求,我希望提供給網絡的圖像中,分割永遠是完全可見的(我處理的是3D心臟MRI分割)。

所以下面的函數查找分割,然后創建一個包圍盒。我們將生成“正方形”分割,邊長等于圖像的寬度(最短邊之長,不計入深度)。在這一情形下,創建了包圍盒之后,如有必要,上下移動窗口以確保整個分割可見。函數同時確保輸出總是正方形的,即使包圍盒部分移出圖像數組的界限。

def cropit(image, seg=None, margin=5):

fixedaxes = np.argmin(image.shape[:2])

trimaxes = 0if fixedaxes == 1else1

trim = image.shape[fixedaxes]

center = image.shape[trimaxes] // 2

print image.shape

print fixedaxes

print trimaxes

print trim

print center

if seg isnotNone:

hits = np.where(seg!=0)

mins = np.argmin(hits, axis=1)

maxs = np.argmax(hits, axis=1)

if center - (trim // 2) > mins[0]:

while center - (trim // 2) > mins[0]:

center = center - 1

center = center + margin

if center + (trim // 2) < maxs[0]:

while center + (trim // 2) < maxs[0]:

center = center + 1

center = center + margin

top = max(0, center - (trim //2))

bottom = trim if top == 0else center + (trim//2)

if bottom > image.shape[trimaxes]:

bottom = image.shape[trimaxes]

top = image.shape[trimaxes] - trim

if trimaxes == 0:

image = image[top: bottom, :, :]

else:

image = image[:, top: bottom, :]

if seg isnotNone:

if trimaxes == 0:

seg = seg[top: bottom, :, :]

else:

seg = seg[:, top: bottom, :]

return image, seg

else:

return image

注意,即使在不給定分割的情況下,該函數仍能剪切出正方形圖像。

原圖

剪切后

原圖、分割圖

剪切后

應用

應用轉換函數時需要小心。例如,如果我們對同一圖像應用多種轉換,我們需要確保不在“改變亮度”后進行“重采樣”,否則將重置圖像的亮度區間,抵消“改變亮度”的效果。不過,由于我們通常希望數據處于同一區間,全圖亮度平移很少見。我們同時也希望確保我們對數據增強不過分狂熱——倍數和其他參數需要設定限制。

當我實現數據增強時,我將所有轉換函數放在一個腳本transform.py中,之后在其他腳本中調用該腳本的函數。

我們在一定范圍內隨機抽取增強參數(避免過于極端的增強參數),以及需要進行的增強類型(我們并不打算每次應用所有增強)。

np.random.seed()

numTrans = np.random.randint(1, 6, size=1)

allowedTrans = [0, 1, 2, 3, 4]

whichTrans = np.random.choice(allowedTrans, numTrans, replace=False)

我們每次分配一個新的random.seed,以確保每次運行和上次運行不同。共有5種可能的增強類型,所以numTrans是1到5之間的隨機整數。我們不想重復應用相同類型的增強,所以replace設為False。

經過一些試錯,我發現以下參數比較好:

旋轉theta ∈ [?10.0,10.0]度

縮放factor ∈ [0.9,1.1],即,10%的放大或縮小

亮度factor ∈ [0.8,1.2],即,20%的增減

平移offset ∈ [?5,5]像素

邊緣我傾向于設置為5到10個像素

來看一個例子吧。假設圖像為thisim,分割為thisseg:

if0in whichTrans:

theta = float(np.around(np.random.uniform(-10.0,10.0, size=1), 2))

thisim = rotateit(thisim, theta)

thisseg = rotateit(thisseg, theta, isseg=True) if withseg else np.zeros_like(thisim)

if1in whichTrans:

scalefactor = float(np.around(np.random.uniform(0.9, 1.1, size=1), 2))

thisim = scaleit(thisim, scalefactor)

thisseg = scaleit(thisseg, scalefactor, isseg=True) if withseg else np.zeros_like(thisim)

if2in whichTrans:

factor = float(np.around(np.random.uniform(0.8, 1.2, size=1), 2))

thisim = intensifyit(thisim, factor)

# 不改變分割圖的亮度

if3in whichTrans:

axes = list(np.random.choice(2, 1, replace=True))

thisim = flipit(thisim, axes+[0])

thisseg = flipit(thisseg, axes+[0]) if withseg else np.zeros_like(thisim)

if4in whichTrans:

offset = list(np.random.randint(-5,5, size=2))

currseg = thisseg

thisim = translateit(thisim, offset)

thisseg = translateit(thisseg, offset, isseg=True) if withseg else np.zeros_like(thisim)

在每種情形下,尋找一組隨機參數,傳給轉換函數。圖像和分割圖分別傳給轉換函數。在我的例子中,我只通過隨機選擇0或1進行水平翻轉,并附加[0]使轉換函數忽略第二軸。另外加入了一個布爾值變量withseg,其為真時增強分割圖,否則返回一張空圖像。

最后,我們剪切圖像為正方形,然后重采樣至所需dims。

thisim, thisseg = cropit(thisim, thisseg)

thisim = resampleit(thisim, dims)

thisseg = resampleit(thisseg, dims, isseg=True) if withseg else np.zeros_like(thisim)

將這些都放在同一腳本中,以便于測試增強。關于這個腳本,有一些需要說明的地方:

腳本接受一個必選參數(圖像文件名)和一個可選分割圖文件名

腳本中包含一點檢測錯誤的邏輯——文件能否加載?它是rgb圖像還是全3D圖像(第三維大于3)?

我們指定最終圖像的維度,例如[224, 224, 8]

我們同時為參數聲明了一些默認值……

……以便在最后打印出應用的轉換及其參數

定義了一個plotit函數,該函數創建一個2 x 2矩陣,其中上面兩張圖像是原圖,下面兩張為增強圖像

注釋掉的部分是我用來保存本文創建的圖像的代碼

在一個在線設定下,我們希望即時進行數據增強?;旧希覀儗⒄{用這一腳本,接受一些待增強的文件名或圖像矩陣,然后創建我們想要的增強。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 圖像增強
    +關注

    關注

    0

    文章

    54

    瀏覽量

    10026
  • python
    +關注

    關注

    56

    文章

    4782

    瀏覽量

    84456
  • 深度學習
    +關注

    關注

    73

    文章

    5493

    瀏覽量

    120979

原文標題:N維圖像的數據增強方法概覽

文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    labview 實現圖像增強

    labview 實現圖像增強該怎么做啊,是大概構思是labview調用matlabM文件,然后按下按鈕直接顯示處理圖片的結果。畢業設計要用,老師和我說很簡單,但是以前沒用過labview,很氣。有沒有大佬能幫幫我。。。。。。沒有
    發表于 05-12 19:47

    基于Matlab的圖像增強與復原技術在SEM圖像中的應用

    原來不清晰的圖片變得清晰,使之改善圖像質量和豐富信息量,提高圖像的視覺效果和圖像成分的清晰度,加強圖像判讀和識別效果的圖像處理的
    發表于 11-14 15:47

    增強技術的總結說明

    圖像數據增強方法一覽(附python代碼)
    發表于 08-23 14:35

    python圖像數據增強——imgaug

    python圖像數據增強——imgaug (三)
    發表于 05-18 10:06

    python圖像數據增強——imgaug

    python圖像數據增強——imgaug (一)
    發表于 06-02 11:13

    基于GFO算子的圖像增強算法如何去實現?

    基于GFO算子(廣義模糊算子)的圖像增強算法如何去實現?怎樣對圖像增強算法進行分析?
    發表于 06-04 06:24

    基于DSP的夜間圖像實時增強系統

    為了實現夜間圖像的實時增強,本文設計了基于DSP 的夜間圖像實時增強系統,然后對Ardely 提出的DADPEQU 夜間
    發表于 07-07 13:07 ?14次下載

    基于無抽樣Contourlet變換的圖像增強方法

    為了有效增強圖像的細節信息,研究了基于無抽樣Contourlet變換的圖象增強方法。首先將待增強圖像
    發表于 10-26 15:12 ?0次下載

    實時圖像增強算法改進及FPGA實現

    實時圖像增強算法改進及FPGA實現,下來看看
    發表于 09-17 07:28 ?14次下載

    改進的紅外圖像增強算法及其在FPGA上的實現

    細節的原理,以及其相對于經典直方圖增強的優勢,同時指出其迭代算法在硬件實現上的局限性,提出簡化后的平臺值直方圖增強算法。然后再結合基于背景中值的灰度映射,通過加權平均得到最后
    發表于 12-22 11:25 ?2次下載
    改進的紅外<b class='flag-5'>圖像</b><b class='flag-5'>增強</b>算法<b class='flag-5'>及其</b>在FPGA上的<b class='flag-5'>實現</b>

    MATLAB如何實現圖像增強灰度變換直方圖均衡匹配

    在MATLAB數字圖像處理領域,如何實現空間域圖像增強的灰度變換,以及圖像直方圖的均衡和匹配(配準)?本文通過大量的圖片
    發表于 01-13 21:56 ?1.1w次閱讀
    MATLAB如何<b class='flag-5'>實現</b><b class='flag-5'>圖像</b><b class='flag-5'>增強</b>灰度變換直方圖均衡匹配

    python中的字典(dict)對象以及其使用方法

    本文通過以英文的形式全面講解了python中的字典(dict)對象以及其使用方法
    發表于 05-15 10:00 ?1次下載

    利用模擬技術進行圖像增強方法設計詳解

    量化過程大量減少了圖像中低對比度信息,也會造成超出量化量程的圖像信息完全丟失。本文針對不能采用數字算法對以上圖像進行有效增強的問題,提出使用模擬技術進行
    發表于 08-09 16:20 ?2421次閱讀
    利用模擬技術進行<b class='flag-5'>圖像</b><b class='flag-5'>增強</b>的<b class='flag-5'>方法</b>設計詳解

    如何使用Python和Numpy等技術實現圖像處理

    本文檔的主要內容詳細介紹的是如何使用Python、Numpy、Scipy和matplotlib執行圖像處理任務。
    發表于 08-28 09:36 ?8次下載
    如何使用<b class='flag-5'>Python</b>和Numpy等技術<b class='flag-5'>實現</b><b class='flag-5'>圖像</b>處理

    如何使用FPGA實現實時圖像增強算法

    針對復雜背景的多目標圖像,提出了一種基于直方圖的實時自適應圖像增強方法。該方法根據自適應直方圖窗口選擇高低閾值,通過灰度線性變換及灰度級等間
    發表于 02-03 15:21 ?10次下載
    如何使用FPGA<b class='flag-5'>實現</b>實時<b class='flag-5'>圖像</b><b class='flag-5'>增強</b>算法