【從零學習OpenCV 4】LUT查找表
- 2019 年 11 月 30 日
- 筆記
經過幾個月的努力,小白終於完成了市面上第一本OpenCV 4入門書籍《從零學習OpenCV 4》。為了更讓小夥伴更早的了解最新版的OpenCV 4,小白與出版社溝通,提前在公眾號上連載部分內容,請持續關注小白。
前面介紹的閾值比較方法中只有一個閾值,如果需要與多個閾值進行比較,就需要用到顯示查找表(Look-Up-Table,LUT)。LUT查找表簡單來說就是一個像素灰度值的映射表,它以像素灰度值作為索引,以灰度值映射後的數值作為表中的內容。例如我們有一個長度為5的存放字元的數組,LUT查找表就是通過這個數組將0映射成a,將1映射成b,依次類推,其映射關係為。在OpenCV 4中提供了LUT()函數用於實現影像像素灰度值的LUT查找表功能,在程式碼清單3-20中給出了該函數的原型。
程式碼清單3-20 LUT()函數原型 1. void cv::LUT(InputArray src, 2. InputArray lut, 3. OutputArray dst 4. )
- src:輸入影像矩陣,其數據類型只能是CV_8U。
- lut:256個像素灰度值的查找表,單通道或者與src通道數相同。
- dst:輸出影像矩陣,其尺寸與src相同,數據類型與lut相同。
該函數的第一個輸入參數要求的數據類型必須是CV_8U類型,但是可以是多通道的影像矩陣。第二個參數根據其參數說明可以知道輸入量是一個1×256的矩陣,其中存放著每個像素灰度值映射後的數值,其形式如圖3-17所示。如果第二個參數是單通道,則輸入變數中的每個通道都按照一個LUT查找表進行映射;如果第二個參數是多通道,則輸入變數中的第i個通道按照第二個參數的第i個通道LUT查找表進行映射。與之前的函數不同,函數輸出影像的數據類型不與原影像的數據類型保持一致,而是和LUT查找表的數據類型保持一致,這是因為將原灰度值映射到新的空間中,因此需要與新空間中的數據類型保持一致。

圖3-17 LUT查找表設置示例
為了體會LUT查找表處理影像後的效果,在程式碼清單3-21中給出通過LUT()函數將灰度影像和彩色影像分別處理的示常式序,程式中分別應用單通道和三通道的查找表對彩色影像進行映射,最終結果在圖3-18中給出。
程式碼清單3-21 myLUT.cpp對影像進行查找表映射 1. #include <opencv2opencv.hpp> 2. #include <iostream> 3. 4. using namespace std; 5. using namespace cv; 6. 7. int main(int agrc, char** agrv) 8. { 9. //LUT查找表第一層 10. uchar lutFirst[256]; 11. for (int i = 0; i<256; i++) 12. { 13. if (i <= 100) 14. lutFirst[i] = 0; 15. if (i > 100 && i <= 200) 16. lutFirst[i] = 100; 17. if (i > 200) 18. lutFirst[i] = 255; 19. } 20. Mat lutOne(1, 256, CV_8UC1, lutFirst); 21. 22. //LUT查找表第二層 23. uchar lutSecond[256]; 24. for (int i = 0; i<256; i++) 25. { 26. if (i <= 100) 27. lutSecond[i] = 0; 28. if (i > 100 && i <= 150) 29. lutSecond[i] = 100; 30. if (i > 150 && i <= 200) 31. lutSecond[i] = 150; 32. if (i > 200) 33. lutSecond[i] = 255; 34. } 35. Mat lutTwo(1, 256, CV_8UC1, lutSecond); 36. 37. //LUT查找表第三層 38. uchar lutThird[256]; 39. for (int i = 0; i<256; i++) 40. { 41. if (i <= 100) 42. lutThird[i] = 100; 43. if (i > 100 && i <= 200) 44. lutThird[i] = 200; 45. if (i > 200) 46. lutThird[i] = 255; 47. } 48. Mat lutThree(1, 256, CV_8UC1, lutThird); 49. 50. //擁有三通道的LUT查找表矩陣 51. vector<Mat> mergeMats; 52. mergeMats.push_back(lutOne); 53. mergeMats.push_back(lutTwo); 54. mergeMats.push_back(lutThree); 55. Mat LutTree; 56. merge(mergeMats, LutTree); 57. 58. //計算影像的查找表 59. Mat img = imread("lena.png"); 60. if (img.empty()) 61. { 62. cout << "請確認影像文件名稱是否正確" << endl; 63. return -1; 64. } 65. 66. Mat gray, out0, out1, out2; 67. cvtColor(img, gray, COLOR_BGR2GRAY); 68. LUT(gray, lutOne, out0); 69. LUT(img, lutOne, out1); 70. LUT(img, LutTree, out2); 71. imshow("out0", out0); 72. imshow("out1", out1); 73. imshow("out2", out2); 74. waitKey(0); 75. return 0; 76. }

圖3-18 myLUT.cpp程式運行結果