你在做什麼是一個非常直接的成像操作,經常應用於圖像和視頻處理。有時它(不精確)稱爲查找表(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
爲了您的LUT,你會實現這個作爲:
lut = uint8([(0:500).*(1/5), (501:4095).*((255-101)/(4095-501)) + 79.5326]);
plot(lut); %Take a look at the lut
此MA kes您在問題中描述的分段計算。
你可以做一個新的形象是這樣的:
convertedimage = lut(double(someimage)+1);
image(convertedimage);
注意,因爲MATLAB指標與雙打 - 一個基於 - 您需要正確施放再加一。這不會像你想象的那樣放慢速度。 MATLAB是做這個的。我已經使用MATLAB數十年了,這對我來說仍然很奇怪。
這種方法可以讓你看到LUT的創建(日誌,exp,無論),它仍然運行得非常快。
就你而言,你的LUT只需要4096個元素,因爲你的輸入數據只有12位。你可能想要小心一點,因爲uint16可能有更高的值。開往一個乾淨的方式,這是使用min
和end
功能:
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);
同樣,我們應用LUT用一個簡單的索引:
convertedimage = lutgamma(min(double(someimage)+1, end));
而且我們獲得下面的圖片:
使用平滑的LUT將會使用y提高整體圖像質量。分段線性LUT將傾向於使得到的圖像在陰影區域中具有奇數不連續性。
這些在許多成像系統中非常普遍,LUT具有文件格式。看看我的意思,看看這個主要攝像機公司的LUT generator。 LUT是一件大事,看起來你在正確的軌道上。
我相信這被稱爲[亮度或色調曲線](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