如之前所說,我們需要將16位圖像轉換爲8位圖像;16位圖像的像素值一共有:
2^16=65536種顏色;
而8位位圖像只有:
2^8=256種顏色,傳統的位數轉換都是:像素值*256/65536,比如photoshop,以及matlab的im2uint8函數都是如此,在一般場景下是沒有問題的,我們姑且稱之爲“真轉換”,而如果是labelme得到的label.png標註圖像在進行轉換時,由於每個類別的像素值從0開始賦值,如0,1,2,3,4.......如果進行“真轉換”的話,由於這些值都太小,基本轉換後的像素值都是(0,1)之間,所以都變成了0,所以我們需要將16位轉換位8位的時候還保留住原來的像素值,這種只改變位數,而不改變具體數值的轉換方法,姑且稱之爲“僞轉換”;
而解決的思路也很簡單,圖像說白了也就是一個矩陣,像素值也就是一個數值而已,我們只需要把表示類別的像素值找出來,並且把他們的值投射到8位即可:
使用的軟件環境如下:
- Python 3.6.3
- VS2013
- OPENCV 2.4.11
- PIL
- Labelme 2.8.0
首先,C++使用opencv轉化,核心代碼如下:(完整代碼(批量轉換,速度最快,需要配置opencv):點擊打開鏈接)
for (int k = 0; k<src.rows; k++)
{
for (int kk = 0; kk<src.cols; kk++)
{
int n = src.at<ushort>(k, kk);
ff.at<uchar>(k, kk) = n;
}
}
python使用PIL進行轉換,更加簡單,核心語句就一行(完整代碼(推薦,批量轉化,速度也很快,但是少了配置opencv的麻煩):https://download.csdn.net/download/qq_15969343/10517176):
img = Image.fromarray(np.uint8(img))
轉換完成後,可以使用軟件查看時候變爲8位,但是打開圖片依然是一片黑:
如果需要提高類別之間的差異性,可以直接乘以一個較大的值:如下:
img = Image.fromarray(np.uint8(img)*20)
圖片就會有明顯的區分,如下: