Halcon中Image有多種像素表示方式,這方面網上找到的資料比較少,有一張大恆圖像培訓的文檔中提到過,感覺描述比較準確:
裏面有四種類型比較類似:uint2、int1、int2、int4。
區分起來很簡單,帶1表示8位,帶2表示16位,帶4表示32位,帶u表示無符號(即無“負號”這種符號)
我用Photoshop生成一張0-255黑白漸變的黑白bmp圖片(尺寸256*256),如下:
下面我想探究一下,看這幾種不同的圖像格式各自的灰度取值範圍是多少。
1 read_image (Image, '8bit.bmp') // byte: 0-255
2
3 *轉換格式觀察
4 convert_image_type(Image,Image_int1,'int1') // 0-127
5 convert_image_type(Image,Image_direction,'direction') // 0-179、255
通過convert_image_type轉換爲“int1”、“direction”格式時,圖片發生了很大變化(如上圖所示)。而轉換爲其他格式時,圖像樣子基本與原圖(byte格式)差異不大,這是爲什麼呢?
因爲“int1”是8位有符號數,如果類比計算機科學的話,取值範圍應該是-128-127,顯然無法兼容灰度範圍在0-255的byte類型圖像。“direction”應該也是類似原因。
而其他的“uint2”、“int2”、“int4”等,取值範圍都不比“byte”小,因此能兼容“byte”格式的圖片,所以轉換以後,圖像沒有發生什麼變化。
一般來說,從相機取出的圖像通常都是8位的bmp圖像,或者16位的bmp圖像,它們對應Halcon中的格式分別是“byte”(8bits無符號)和“uint2”(16bits無符號)。
16位的圖像雖然在Halcon中也能處理,但是用起來還是不太順手,並且有部分算子不兼容16位圖像(比如執行以後得不到預計中的結果)。並且16位的圖像在上位機軟件中處理、顯示可能也會遇到兼容性問題,所以經常有將16位圖像轉爲8位圖像的需求。
相機取出的16位圖像的灰度範圍一般是0-65535,如果將這種16位圖像直接通過convert_image_type轉換爲“byte”、“int1”、“direction”格式時,通常都會變成“全白”的一張圖,因爲容納不了那麼高的灰度值,超出範圍的灰度色階會被截斷。
爲了適應“byte”類型,一般情況下先調用scale_image算子對灰度值進行映射轉換(映射到0-255範圍內),然後再用convert_image_type算子進行轉換。
通過使用scale_image算子對圖像灰度值進行縮放映射。scale_image使用以下公式計算:
GMax和GMin可以通過min_max_gray算子計算。
代碼如下:(由於博客園不支持tif圖像,16位的tif就更不用說了,所以這裏就不放原圖Image了)
1 dev_set_draw ('margin')
2 read_image (Image, '0.tif')
3
4 *如果16位圖像非常暗的話,建議在這一步進行提亮,因爲後面8位圖像大幅度提亮易造成色階斷裂,出現不連續的像素塊
5 * scale_image (Image, Image, 25, 0)
6
7 get_domain (Image, rectangle)
8 * 獲取全圖中像素灰度值的最大和最小值
9 min_max_gray(rectangle, Image, 0, Min, Max,range)
10
11 *將16位圖的灰度值映射到0-255上
12 Mult := 255.0 / (Max - Min)
13 Add := -Mult * Min
14 scale_image (Image, Image_scaled, Mult, Add)
15
16 * 轉換爲'byte'類型
17 convert_image_type (Image_scaled, ImageConverted, 'byte')
18
19 *如果轉換以後圖像整體對比度太低的話,可以提高對比度(這裏是對8位圖像處理)
20 Min := 20
21 Max := 160
22 Mult := 255.0 / (Max - Min)
23 Add := -Mult * Min
24 scale_image (ImageConverted, ImageConverted_scaled, Mult, Add)
至於8位轉爲16位,以及彩色圖像中8位和16位的互相轉換,這裏就暫不分析了,感興趣的可以看一下第三篇參考資料文章。(注意參考資料中的內容僅供參考,其中是有一些訛誤的。)
參考資料: