2015-04-30 79 views
2

我有16位原始圖像(12有效位)。我把它轉換成rgb,現在我想改變動態範圍。我創建了2個地圖功能。你可以在下面看到它們。正如您所看到的,第一個函數將值0-500映射到0-100,第二個函數將其餘值映射到101-255。如何更改RGB圖像的動態範圍?

enter image description here

現在我想申請對RGB圖像的地圖功能。我正在做的是迭代每個像素,爲每個通道找到適當的函數並將其應用於通道。例如,像素是RGB = [100 2000 4000]。在R頻道上,我會應用第一個功能,因爲100在0-500範圍內。但是,在G和B頻道上,我將應用第二個函數,因爲它們的值在501-4095之間。

但是,通過這種方式,我實際上改變了像素的實際顏色,因爲我在像素的通道上應用了不同的函數。

你可以建議如何做或至少給我一個方向或顯示一些文章?

+0

我相信這被稱爲[亮度或色調曲線](http://en.wikipedia.org/wiki/Curve_(調性))。我首先想到的是,最好在[HSV](http://en.wikipedia.org/wiki/HSL_and_HSV)或[L \ * a \ * b \ *](http://en.wikipedia .org/wiki/Lab_color_space)而不是RGB。 – horchler

回答

2

你在做什麼是一個非常直接的成像操作,經常應用於圖像和視頻處理。有時它(不精確)稱爲查找表(LUT),即使它並不總是通過實際的查找表來實現。這方面的例子是伽瑪調整或日誌編碼。

例如,這種編碼的一個例子是sRGB,它是線性光線的伽馬編碼。你可以在這裏閱讀:http://en.wikipedia.org/wiki/SRGB。你會看到它有一個非線性調整。

LUT的名字暗示了一個很好的方法。如果可以將圖像設置爲uint8或uint16值,則可以爲任何輸入值創建所需輸出值的矢量。查找表具有與變量類型的可能範圍相同數量的元素。如果您使用的是uint8,則您將擁有一個包含256個值的查找表。然後,查找很容易,只需使用圖像值作爲LUT的索引即可獲取結果值。這種計算效率是LUTS被廣泛使用的原因。

對於您的情況,由於您在RGB空間中工作,因此將曲線以完全相同的方式應用於三個顏色通道中的每一個是可以接受的。這個原因,RGB空間很好。但是,由於各種原因,每個通道有時會執行不同的LUT。

所以,如果你有一個像(我們將使用一個包含在MATLAB和假裝這是12位通過縮放來):

someimage = uint16(imread('autumn.tif')).*16; 
image(someimage.*16); % Need to multiply again to display 16 bit data scaled properly 

Original image

爲了您的LUT,你會實現這個作爲:

lut = uint8([(0:500).*(1/5), (501:4095).*((255-101)/(4095-501)) + 79.5326]); 
plot(lut); %Take a look at the lut 

Plot of the LUT

此MA kes您在問題中描述的分段計算。

你可以做一個新的形象是這樣的:

convertedimage = lut(double(someimage)+1); 
image(convertedimage); 

enter image description here

注意,因爲MATLAB指標與雙打 - 一個基於 - 您需要正確施放再加一。這不會像你想象的那樣放慢速度。 MATLAB是做這個的。我已經使用MATLAB數十年了,這對我來說仍然很奇怪。

這種方法可以讓你看到LUT的創建(日誌,exp,無論),它仍然運行得非常快。

就你而言,你的LUT只需要4096個元素,因爲你的輸入數據只有12位。你可能想要小心一點,因爲uint16可能有更高的值。開往一個乾淨的方式,這是使用minend功能:

convertedimage = lut(min(double(someimage)+1, end)); 

現在,這已經實現你的功能,但也許你想要一個稍微不同的功能。例如,這種類型的通用功能是簡單的伽瑪調整。 2.2的伽瑪意味着輸入的圖像值通過將它們設置爲1/2.2的功率(如果在0和1之間縮放)來縮放。我們可以建立這樣的LUT如下:

lutgamma = uint8(256.*(((0:4095)./4095).^(1/2.2))); 
plot(lutgamma); 

Plot of a gamma LUT

同樣,我們應用LUT用一個簡單的索引:

convertedimage = lutgamma(min(double(someimage)+1, end)); 

而且我們獲得下面的圖片:

enter image description here

使用平滑的LUT將會使用y提高整體圖像質量。分段線性LUT將傾向於使得到的圖像在陰影區域中具有奇數不連續性。

這些在許多成像系統中非常普遍,LUT具有文件格式。看看我的意思,看看這個主要攝像機公司的LUT generator。 LUT是一件大事,看起來你在正確的軌道上。

+0

我有2個問題:1 - 什麼是'79.5326'數字? 2 - 即使在這個解決方案中,不同的功能將應用於每個通道。假設rgbPxl = [50,2000,3000]。第一個功能將應用於紅色通道,第二個功能將應用於綠色和藍色通道,不是嗎?因此,我們將更改實際顏色。我錯過理解的東西嗎? – theateist

+0

我說得對,即使在你的方法中,每個通道都會應用兩種不同的功能? – theateist

+0

常量'79.5326'就是分段線性函數第二部分的線性偏移值。它從'101 - 501 *(255-101)/(4095 - 501)'計算。所示的示例將相同的LUT應用於每個通道,這是RGB空間中所需的用於保存顏色的內容。如果我們想爲每個通道應用不同的函數,我們需要獨立地爲每個顏色通道編制索引,如'convertedimage(:,:1)= lut(double(someimage(:,:1))+ 1 );」紅色通道等。 – Tony

0

我想你指的東西,Photoshop中調用「增強單色對比度」,被描述here - 看「第3步:嘗試使用不同的算法」

基本上,我想你找到所有頻道的分鐘和最大距離在所有3個通道,並採用相同的縮放所有通道,而不是與自己的分單獨做每個通道和最大。

或者,你可以轉換到實驗室(亮度加ab)模式,並應用功能明度通道(不影響ab渠道持有的色彩信息),然後變換回RGB,您的顏色不受影響。