2012-02-14 72 views
6

對於那些不熟悉Gimp的「Color to Alpha」功能的用戶,下面是Gimp文檔中的頁面:Color to Alpha。它做得非常好,我很想知道Gimp究竟是如何處理顏色操作的,無論顏色可能在哪個顏色空間中。感謝任何提示。Gimp的「Color to Alpha」功能背後有什麼算法?

編輯1:生成基於其相似性的關鍵色(你在「顏色爲Alpha」對話框中選擇一個)的像素透明度的信息,像一些民間除去他的回答出於某種原因才建議,聽起來像是一個很好的見解,但我認爲它比這更復雜。假設我們估計單位範圍從0.0到1.0的顏色相似性,並且我們獲得了一個像素,其顏色例如爲0.4,類似於白色的顏色(例如您將在「顏色至Alpha「對話框),因此像素獲得0.6的Alpha值,那麼如何改變像素的實際顏色以補償在Alpha像素爲0.6的白色背景下顯示所得像素時亮度/光度/飽和度的鬆散?

編輯2:其實更新:與第一編輯子問題已經回答How to change the alpha of a pixel without changing the resulting color?但它可能不完整的故事,因爲發生了什麼事在GIMP的來源爲「顏色爲Alpha」功能並不那麼簡單,似乎基於特定的算法而不是公式。

+0

相關問題:http://stackoverflow.com/questions/9282714/how-to-change-the-alpha-of-a-pixel-without-changing-the-resulting-color – 2012-02-16 21:00:43

+0

@MarkRansom我知道,你發佈了一個鏈接的問題是相關的,因爲問那個問題的人就是我! :)儘管你的公式可以達到這個Gimp特性的效果,但這個謎仍然存在,因爲我在Gimp的來源中看到的複雜程度高於你的公式。 – 2012-02-17 15:41:09

+0

@MarkRansom繼續:但是你的方法似乎比Gimp更靈活,因爲通過重寫方程組的解決方案,可以將圖像從一種顏色的背景中「剪切」出來,並將其放置在另一種顏色的背景上,圖像仍然看起來一樣。所以我想這個問題已經沒有太大的意義了,所以如果沒有人不介意的話,我會註冊這個問題進行刪除。 – 2012-02-17 15:42:34

回答

1

你需要想出一個比較顏色相似性的機制。有各種各樣的顏色空間可以做到這一點。 RGB通常不是這類事情的最佳選擇。但是你可以使用HSV,YCbCr或其他一些亮度/色度空間。通常在這些空間中的一個距離會給你比RGB中的歐幾里德距離更好的答案。一旦你有距離,你可以用最大距離除以得到一個百分比。作爲一種可能性,該百分比將與您想要使用的alpha值相反。

如果你想知道GIMP如何做,你可以看看源代碼。例如,該插件爲here's one recent code change

+0

謝謝,但我已經看到了源代碼,它不夠直接,並且記錄不完整。你在回答的第一部分所寫的內容已經在我的問題的版本中得到解決,簡單地說,這意味着不難估計兩種顏色之間的相似性,而是如何處理像素的顏色已從1.0更改爲其他值,實際上,這並不複雜:http://stackoverflow.com/questions/9282714/how-to-change-the-alpha-of-a-pixel-without-changing由此產生的顏色 – 2012-02-17 15:49:48

+0

你似乎知道GIMP。你能足夠回答我的問題[這裏](http://stackoverflow.com/questions/29147244/gimp-colorization-technique)? – 2015-03-20 09:28:53

+0

看來問題已被刪除,所以我不知道實際問題是什麼。抱歉! – user1118321 2015-03-20 14:26:52

8

我看了一下源代碼,它的肉是colortoalpha函數。參數* a1至* a4分別是輸入/輸出紅色,綠色,藍色和阿爾法,而c1至c3是用於製作阿爾法的顏色。

當你將兩種顏色C1和C2與具體阿爾法A(0≤A≤1),其結果是

y = a * c1 + (1-a) * c2 

在這裏,我們正在做相反的操作:我們知道結局結果y和背景色c2,並且想知道c1和a。由於這是一個不足指定的方程,因此有無數的解決方案。然而,0≤c1≤255和0≤a≤1的範圍爲解決方案增加了界限。

Gimp插件的工作方式是爲每個像素最小化alpha值(即最大化透明度)。相反,這意味着對於不是完全透明的每個結果像素(即,不完全是背景顏色),其中一個RGB分量是0或255.

這產生一個圖像,當覆蓋在指定的顏色將產生原始圖像(不存在舍入誤差)並且對每個像素具有最大透明度。

值得注意的是,整個過程在RGB色彩空間中完成,但也可以在其他色彩空間中完成,只要組合操作在相同的色彩空間中完成即可。

1

所以我看着GIMP source code ......新!我使它具有通用性和可讀性。 雖然還是挺快的。 數學解釋見Sampo's answer。 這裏的C#實現(容易轉化爲C/C++):

static class PixelShaders { 

    /// <summary> 
    /// Generic color space color to alpha. 
    /// </summary> 
    /// <param name="pA">Pixel alpha.</param> 
    /// <param name="p1">Pixel 1st channel.</param> 
    /// <param name="p2">Pixel 2nd channel.</param> 
    /// <param name="p3">Pixel 3rd channel.</param> 
    /// <param name="r1">Reference 1st channel.</param> 
    /// <param name="r2">Reference 2nd channel.</param> 
    /// <param name="r3">Reference 3rd channel.</param> 
    /// <param name="mA">Maximum alpha value.</param> 
    /// <param name="mX">Maximum channel value.</param> 
    static void GColorToAlpha(ref double pA, ref double p1, ref double p2, ref double p3, double r1, double r2, double r3, double mA = 1.0, double mX = 1.0) { 
     double aA, a1, a2, a3; 
     // a1 calculation: minimal alpha giving r1 from p1 
     if (p1 > r1) a1 = mA * (p1 - r1)/(mX - r1); 
     else if (p1 < r1) a1 = mA * (r1 - p1)/r1; 
     else a1 = 0.0; 
     // a2 calculation: minimal alpha giving r2 from p2 
     if (p2 > r2) a2 = mA * (p2 - r2)/(mX - r2); 
     else if (p2 < r2) a2 = mA * (r2 - p2)/r2; 
     else a2 = 0.0; 
     // a3 calculation: minimal alpha giving r3 from p3 
     if (p3 > r3) a3 = mA * (p3 - r3)/(mX - r3); 
     else if (p3 < r3) a3 = mA * (r3 - p3)/r3; 
     else a3 = 0.0; 
     // aA calculation: max(a1, a2, a3) 
     aA = a1; 
     if (a2 > aA) aA = a2; 
     if (a3 > aA) aA = a3; 
     // apply aA to pixel: 
     if (aA >= mA/mX) { 
      pA = aA * pA/mA; 
      p1 = mA * (p1 - r1)/aA + r1; 
      p2 = mA * (p2 - r2)/aA + r2; 
      p3 = mA * (p3 - r3)/aA + r3; 
     } else { 
      pA = 0; 
      p1 = 0; 
      p2 = 0; 
      p3 = 0; 
     } 
    } 

} 

GIMP的實現(here)使用RGB顏色空間,使用α值作爲float用0至1米範圍內,並且R,G,B作爲float從0到255之間。

當圖像具有JPEG僞像時,RGB實現失敗,因爲它們意味着無法察覺的顏色偏差,但是相當顯着的絕對R,G,B偏差。使用LAB色彩空間應該可以解決這個問題。

如果您只是想從圖像中移除純色背景,則顏色轉換爲alpha算法不是最佳選擇。當使用LAB色彩空間計算每個像素的色彩空間距離時,我得到了很好的結果。計算出的距離然後應用於原始圖像的alpha通道。這和alpha顏色的主要區別是像素的色調不會改變。背景刪除只是設置阿爾法(不透明度)以色彩空間差異。如果在前景圖像中不出現背景顏色,則效果很好。如果它確實無法去除背景,或者必須使用BFS算法來僅行走外像素(就像在GIMP中使用魔術棒選擇,然後移除選區一樣)。

如果前景圖像同時具有類似於背景顏色的孔和像素顏色,則不能移除背景。這些圖像需要一些手動處理。

+0

我還沒有測試過它,但已經爲你的工作+1了;)我需要將算法應用於svg圖像,我還沒有找到解決方案在那裏做... – abimelex 2017-12-08 15:41:29

+0

我想知道它爲什麼可以與矢量圖形相關。順便說一句,現在看着它,我想知道'mA'和'mX'參數的意思。它缺少RGB到LAB色彩空間的轉換。如果有人有興趣從光柵圖像中移除純色背景,我在C#中實現了一些工作代碼,實現了我在這裏編寫的所有內容(LAB色彩空間和BFS算法在移除背景時保持對象完好無損)。再問一個問題,因爲它不僅僅是「顏色到alpha」的效果。我會稱之爲智能背景刪除。適合「綠屏」圖片。 – Harry 2017-12-08 19:53:26