OpenCV -- 將16位圖像映射到8位


現在有一張16bit深度的圖像,如果不使用PS或者其他工具的話,是很難直接獲取到圖像里儲存的信息的。如下。
直接在Window里打開一張16位tif格式的圖片


如果能將16位轉換成8位的話,就能正常顯示了。

原理
一張16位的圖像,意思是一張圖像的每個像素點的像素值都由16位的二進制數表示,每個像素點的顏色有 2^16 = 65536 種可能。
也就是說,圖像的顏色區間被划分成了2^16 = 65536份。
同理,8位圖像,圖像的顏色區間被划分成了2^8 = 256份。
那么,將16位轉換成8位,不就是將區間 [0,65535] 映射到 [0,255] 嗎?

軟件環境
VS2017
OPENCV 3.41

測試與分析
16位到8位,是高精度到低精度的轉換,必然造成信息的丟失。
在實際的測試中也是這樣。

下面是筆者直接將16位映射到8位的轉換結果

這實際上是一張失真很嚴重的圖像。
上面這種方法雖然道理是沒錯,但是這種轉換遺失了圖像中太多信息,不是我們想要的。然而當我在百度上搜索關於16位到8位圖像的轉換思路的時候,提供的卻大多是這種方法,這也是我寫這篇博客的原因。
問題的原因是我
錯誤地認為了16位的圖像像素值就是分布在 [0,65535] 的。

解決的方法是:

取圖像 像素值 最小值 到 最大值 區間映射到[0,255]。

最終處理結果如下:

是不是感覺細節層次豐富了很多呢?

代碼:

#include <iostream>
#include <opencv.hpp>
#include <opencv\highgui.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

using namespace cv;
using namespace std;

int main()
{
    DWORD Start_time = GetTickCount(); //計時開始
    Mat img = imread("task1.tif", CV_LOAD_IMAGE_UNCHANGED);//加載圖像;
    int width = img.cols;//圖片寬度
    int height = img.rows;//圖片高度
    Mat dst = Mat::zeros(height, width, CV_8UC1);//先生成空的目標圖片
    double minv = 0.0, maxv = 0.0;
    double* minp = &minv;
    double* maxp = &maxv;
    minMaxIdx(img, minp, maxp);  //取得像素值最大值和最小值

   //用指針訪問像素,速度更快
   ushort *p_img;
   uchar *p_dst;
   for (int i = 0; i < height; i++)
   {
	p_img = img.ptr<ushort>(i);//獲取每行首地址
	p_dst = dst.ptr<uchar>(i);
	for (int j = 0; j < width; ++j)
	{
		p_dst[j] = (p_img[j] - minv) / (maxv - minv) * 255;

		//下面是失真較大的轉換方法
		//int temp = img.at<ushort>(i, j);
		//dst.at<uchar>(i, j) = temp;
	}
}
DWORD End_time = GetTickCount(); //計時結束
cout << "Time used:" << End_time - Start_time << " ms"<<'\n';
imshow("8bit image", dst);
imwrite("task1_8bit.jpg", dst);
waitKey(0);
system("pause");
return 0;
}

不光是16位,24位圖像的轉換也是同樣的思路,感興趣的朋友可以自己試一試。
不過要另外多說一句,高精度到低精度,信息的丟失是不可避免的,上面提供的方法只是相對效果更好。

補充: 關於數據類型的說明
ushort 為無符號16位整數,占2個字節,取值范圍在0~65,535之間。
uchar 為無符號8位,占1個字節,取值范圍在0~255之間。

要轉換數據記得選擇合適的數據類型哦。

https://blog.csdn.net/qq_41342525/article/details/105124659


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM