2017-08-26 24 views
0

無法理解,表達Vxy和Vxy_nocastOpenCV中的saturate_cast如何工作?

uchar init_m0[] = {10,10,30}; 
cv::Mat m0(3,1,CV_8UC1,init_m0,sizeof(uchar)); 
uchar& Vxy = m0.at<uchar>(0); 
uchar& Vxy_nocast = m0.at<uchar>(1); 
std::cout << m0 << std::endl; 
Vxy = cv::saturate_cast<uchar>((Vxy-128)*2 + 128); 
Vxy_nocast = (Vxy_nocast-128)*2 + 128; 
std::cout << m0 << std::endl; 

結果

[ 10; 
    10; 
    30] 
[ 0; 
148; 
    30] 
+0

飽和轉換將確保沒有發生整數溢出或下溢。通常情況下,如果你有一個無符號字符變量值200,並添加56(+ X),你會得到一個溢出,變量將有值0(+ X),這是很多算法非常糟糕。 – Micka

+1

在這種情況下,我會說[code](https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/saturate.hpp#L102)是最好看的地方尋求答案。 –

回答

1

(10-128)*2 + 128 = -108的結果。 cv::saturate_cast<uchar>是對unsigned char的飽和轉換,而unsigned char只能是> = 0。正常的uchar轉換(如果不指定任何內容就會隱式發生)會通過重新解釋-108來將負值包裝爲正值在2的補碼二進制中是10010100,與148相同(並且它也將圍繞更大的值,例如257到1)。一個飽和的轉換會將負值轉換爲0,對於該類型的最小值爲0飽和(同樣正值將飽和最大值爲255)。

查看saturation arithmetic瞭解更多詳情。

+0

因此,在這種情況下,saturation_cast增加了一個步驟。它正在查找MSB,如果MSB爲1,則將結果設爲0.在正常的演員表中,它將從32位截斷爲8位,並以2s補碼顯示結果? – infoclogged

+0

這種類型,但它看起來超出了無符號字符的8位,以確定它是否太大或太小。如果在支持飽和算術的硬件上運行,這個額外的步驟可能不會比普通的添加更昂貴。 – hcs