14 2 2 實現和執行顏色濾鏡

2021-08-26 11:43:46 字數 2597 閱讀 6426

14.2.2 實現和執行顏色濾鏡

首先,我們將討論一種特殊效果的型別:顏色濾鏡。稍後,我們將擴充套件這個應用程式,處理任何效果,實現模糊的示例。彩色濾鏡只更改影象的色調,所以很簡單。這個濾鏡為每個畫素計算新的顏色,無需訪問影象的其他部分。正如我們在第 8 章中看到的,這是一種行為,自然表示為乙個函式。

調整顏色的濾鏡可以表示為函式,取原來的顏色,返回乙個新的顏色。f# 的型別簽名是 ******color-> ******color。在 c# 中,我們可以使用 func 委託,表示相同的事。執行這個濾鏡的**,將把這個函式應用到影象的每個畫素。當我們處理點陣圖時,把它表示為乙個二維陣列。

將位圖轉換為陣列

影象的 .net 表示形式是用來自 system.drawing 命名空間下的 bitmap 類,這個類可以使用 getpixel 和 setpixel 訪問畫素,但是,這兩個方法效率低下,當需要訪問大量的畫素時。當你每次想讀乙個位元組的資料,相當於重新開啟圖形檔案。這就是為什麼我們要用乙個二維陣列來表示點陣圖了。

濾鏡的實現在 c# 和 f# 中是類似的,但是,順序執行的濾鏡的**將會不同。f# 庫包括處理二維陣列的高階函式,但是,.net 中沒有,因此,我們就需要首先實現這些。我們不會使**像 f# 的 array2d 模組中的函式一樣完全通用的。讓我們首先實現 c# 中的幾個濾鏡。

在 c# 中建立並應用顏色濾鏡

雖然我們將使用 func 委託來表示顏色濾鏡,仍把它們實現為普通的方法,當我們需要時,可以將它轉換為委託,比如,能將它們儲存在濾鏡的集合中。清單 14.10 顯示了兩個簡單的顏色濾鏡。第乙個將顏色轉換為灰度,第二個使影象變亮。

listing 14.10 grayscale and lighten filters (c#)

class filters

public static ******color lighten(******color clr)

}若要計算灰度顏色,我們使用加權平均,因為人眼對綠色光比紅色或藍色更敏感。第二個濾鏡的實現是更簡單,但中,這一次它使用 ******color 型別的運算子的過載。它使用元件按位(component-wise)乘法,把顏色乘以 2。這樣,元件建立的顏色可能會超出正常範圍 0 至 255,所以,我們使用 clipcolor 方法,適當地限制每個元件。

現在,我們的濾鏡有了方法,把它們應用到表示影象的二維陣列。清單 14.11 通過在陣列型別上,實現擴充套件方法做到的。目前,我們仍將在單個執行緒中,執行所有計算。

public static ******color[,] runfilter

(this ******color[,] arr, funcf)

runfilter 方法首先建立乙個新的陣列,將返回作為結果。我們將以函式的方式寫應用程式,所以,不會修改作為輸入提供的陣列。在方法體中,我們以命令方式,迴圈訪問陣列中的所有畫素,並把這個顏色濾鏡函式,應用到每個畫素。注意,我們指定 y 作為陣列的第乙個座標。這可以使影象上的一些操作效率更高,因為,在這種設定中,乙個水平掃瞄線就是乙個記憶體塊。

鑑於我們以前對 parallel.for 的體驗,你可能已經可以看出,如何對這段**並行化。在我們進行之前,先完成單執行緒的版本,看一下 f# **。

在 f# 中建立並應用顏色濾鏡

第十章,當我們想要把乙個函式應用到陣列的所有元素,並把結果收集乙個新的陣列中時,使用了 array.map 函式。這正是我們清單 14.11 中的 runfilter 方法所做的,除了它是處理二維陣列之外。你可能不會驚奇,f# 庫包含了乙個用於處理二維陣列的模組 array2d,類似於一維陣列的 array 模組。這個模組也包含乙個 map 函式,使得 f# 的 runfilter 實現很簡單。你可以在清單 14.12 中看到它,連同兩個顏色濾鏡。

> let runfilter f arr = array2d.map f arr

module colorfilters =

let grayscale(clr:******color) =

let c = (clr.r*11 + clr.g*59 + clr.b*30) / 100

******color(c, c, c)

let lighten(clr:******color) =

(clr * 2).clipcolor()

;;val runfilter : ('a -> 'b) -> 'a [,] -> 'b [,]

module colorfilters =

val grayscale : ******color -> ******color

val lighten : ******color –> ******color

runfilter 函式呼叫 array2d.map 來完成這項工作。事實上,在後面的**中,我們可能只使用 array2d.map。把array2d.map 打包到另乙個函式,使**更具可讀性和自解釋(self-explanatory)。此外,如果我們最終決定改變點陣圖的表示,只需要更新 runfilter 函式,而不必接觸使用它的**。

我們還使用 f# 模組來組織**,使其更有結構化的風格。所有圖形濾鏡封裝在 colorfilters 模組中。這個清單顯示了可以在 f# interactive 中輸入整個模組,以看到推斷的型別簽名。我們的兩個示例濾鏡的實現幾乎與 c# 一樣,後但在面,我們可以看到,f# 允許我們做更多一些的自定義型別,提供標準的過載運算子。

CSS濾鏡實現的顏色漸變翻轉效果

一下是利用css濾鏡效果實現漸變翻轉的 有需要的朋友可以參考下。複製 如下 document class ddf 轉著好玩 c程式設計客棧ss中transform rotate 360deg 旋轉,預設順時針旋轉引數為度數例如 360deg transition property 過濾,後面接需要過...

OpenCV實現馬賽克和毛玻璃濾鏡效果

一 馬賽克效果 馬賽克的實現原理是把影象上某個畫素點一定範圍鄰域內的所有點用鄰域內隨機選取的乙個畫素點的顏色代替,這樣可以模糊細節,但是可以保留大體的輪廓。以下opencv程式實現馬賽克效果,通過滑鼠左鍵在影象上劃定馬賽克的矩形框。include include using namespace cv...

OpenCV總結 實現馬賽克和毛玻璃濾鏡效果

馬賽克的實現原理是把影象上某個畫素點一定範圍鄰域內的所有點用鄰域內隨機選取的乙個畫素點的顏色代替,這樣可以模糊細節,但是可以保留大體的輪廓。先來張倪美人的鎮樓照 以下opencv程式實現馬賽克效果,通過滑鼠左鍵在影象上劃定馬賽克的矩形框。include include using namespace...