OpenCV 中 imread cvtColor cv::IMREAD_GRAYSCALE與CV_BGR2GRAY得到灰度圖不一致問題

今天調個程序,源代碼輸入是PGM格式的灰度圖,方便起見,我直接用matlab批量轉的文件。然而,在程序中使用imread(filename, IMREAD_GRAYSCALE)時,驚奇發現,同一種圖片的兩種輸入,卻得到了不同的結果,儘管結果類似。我驚了!!彩色轉灰度這玩意還有不一樣的事,這個事坑了我好幾天,今天終於明白了,現在我把問題及解決方案整理如下。

問題引出

一張jpg彩色圖片file.jpg,一張由matlab - imread - rgb2gray得到相應的灰度pgm圖file.pgm。則由如下代碼得到的灰度圖imgG1和imgG2,值不完全一致。

cv::Mat imgG1 = cv::imread("file.pgm", 0);
cv::Mat imgG2 = cv::imread("file.jpg", 0);

問題分析

從一開始,我以爲是我程序問題,找了好久無頭緒,換了另一種計算灰度的代碼(如下),驚奇發現,得到的灰度與pgm對應數據一致。

cv::Mat imgC2 = cv::imread("file.jpg");
cv::Mat imgG2;
cv::cvtColor(imgC2, imgG2, CV_BGR2GRAY);

這讓我不禁陷入了人生與科研的大思考,我從6點搜百度搜到第二天1點,沒有得到任何有用信息。只能去GG搜下,結果發現有人跟我遇到了一樣的問題,只不過他是計算直方圖。但是似乎這些相關連接沒給出明確的方法。

最後,找到一個網址,上面說了這個問題的原因Grayscale conversion algorithm of OpenCV’s imread(),我翻譯如下。

在opencv3.0中,

  • cv::IMREAD_COLOR 解析jpg時候,由cv::JpegDecoder解碼得到一個RGB圖像,然後由icvCvt_RGB2BGR_8u_C3R() 函數交換R和B空間,得到BGR格式的彩色圖。
  • cv::IMREAD_GRAYSCALE 這個圖像由cv::JpegDecoder解碼得到一個灰度圖,所有的顏色轉換和其他預處理或後處理等相關細節都是由libjpeg處理的,最後,將解壓縮的數據複製到給定cv::Mat的內部緩衝區中。因此,在cv::IMREAD_GRAYSCALE中沒有調用opencv中的函數cv::cvtColor來進行顏色轉換。

解決方案

爲了保證與matlab生成數據保持一致,我們按照如下代碼來獲得灰度圖。切記,以後不要再指定imread的第二個參數爲0來獲得灰度圖了

cv::Mat imgC2 = cv::imread("file.jpg");
cv::Mat imgG2;
cv::cvtColor(imgC2, imgG2, CV_BGR2GRAY);

後話,好多問題我都是從github的issue和stackoverflow.com搜到的,如果百度不爬這兩個網站。

藥丸つ﹏⊂。

終於可以無憂無慮睡覺了(~﹃~)~zZ

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章