图像与数据类型的对应,以及如何显示
1、normalize函數(shù)
void cv::normalize(InputArry src,InputOutputArray dst,double alpha=1,double beta=0,int norm_type=NORM_L2,int dtype=-1,InputArray mark=noArry())
(1)函數(shù)的作用
將輸入圖像src歸一化。
注意:alpha、beta作為規(guī)范范圍的上下限,代表的是輸入圖像數(shù)據(jù)類型的顯示范圍。
ex:對于32F位圖像,因為顯示范圍是0—1,所以alpha、beta為0、1,才能顯示與保存。
normalize(img,img, 0, 1, NORM_MINMAX);
imshow(img);
對于16U位圖像,因為顯示范圍是0—65535,所以alpha、beta為0、65535,才能顯示與保存。
normalize(img,img, 0, 65535, NORM_MINMAX);
normalize(img,img,-32768, 32767, NORM_MINMAX);//CV_16S的歸一化
imshow(img);
(2)參數(shù)說明?
src ? ? ? ? ? ? ? 輸入數(shù)組;
dst ? ? ? ? ? ? ? 輸出數(shù)組,數(shù)組的大小和原數(shù)組一致;
alpha ? ? ? ? ? 1,用來規(guī)范值,2.規(guī)范范圍,并且是下限;
beta ? ? ? ? ? ? 只用來規(guī)范范圍并且是上限;
norm_type ? 歸一化選擇的數(shù)學公式類型;
dtype ? ? ? ? ? 當為負,輸出在大小深度通道數(shù)都等于輸入,當為正,輸出只在深度與輸如不同,不同的地方游dtype決定;
mark ? ? ? ? ? ?掩碼。選擇感興趣區(qū)域,選定后只能對該區(qū)域進行操作。
2、mat.type()函數(shù)
opencv中Mat存在各種類型,其中mat有一個type()的函數(shù)可以返回該Mat的類型。類型表示了矩陣中元素的類型以及矩陣的通道個數(shù),它是一系列的預定義的常量。具體的有以下值:
通道數(shù)我們可以發(fā)現(xiàn),C4=C3+8、C3=C2+8、C2=C1+8
Unsigned 8bits uchar 0~255
Mat: CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4Signed 8bits char -128~127
Mat: CV_8SC1,CV_8SC2,CV_8SC3,CV_8SC4Unsigned 16bits ushort 0~65535
Mat: CV_16UC1,CV_16UC2,CV_16UC3,CV_16UC4Signed 16bits short -32768~32767
Mat: CV_16SC1,CV_16SC2,CV_16SC3,CV_16SC4Signed 32bits int -2147483648~2147483647
Mat: CV_32SC1,CV_32SC2,CV_32SC3,CV_32SC4Float 32bits float -1.18*10-38~3.40*10-38
Mat: CV_32FC1,CV_32FC2,CV_32FC3,CV_32FC4Double 64bits double
Mat: CV_64FC1,CV_64FC2,CV_64FC3,CV_64FC4
一、顯示數(shù)據(jù)類型
#include <iostream>
#include <sstream>
#include <time.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> using namespace cv;
using namespace std;
using namespace pcl;int main()
{Mat img = imread("12.bmp");cout << img.type() << endl;imshow("11", img);waitKey(0);system("pause");return 0;
}
?因為type()=16=0:所以是CV_8U類型,可以使用imshow直接顯示。
?二、imshow和imwrite函數(shù)
imshow
opencv的imshow函數(shù)都只能對像素值處于0-255范圍內(nèi)的圖像進行顯示。也就是說,無法使用OpenCV提供的接口函數(shù)顯示諸如CV_16S等非8位數(shù)據(jù)格式的視差圖/深度圖,只能轉(zhuǎn)換成CV_8U格式進行操作。
其實,人眼對灰度級的敏感度比較低、根本無法分辨256級灰度值。而對視差圖/深度圖進行顯示,也只是為了比較直觀的驗證視差圖/深度圖的準確性(如顏色隨距離逐層變化),所以說完全沒必要對216 =65536級灰度進行顯示,轉(zhuǎn)換成CV_8U格式就能完全滿足需求,這也許就是為什么OpenCV沒有提供這樣接口的原因之一吧。imwrite
而存儲的話,imwrite函數(shù)在關于保存為不同深度格式時候的圖像類型支持說明如下:8位的圖像(CV_8U),支持png/jpg/bmp/webp等各種常見圖像格式
16位的圖像(CV_16U),支持png/jpeg2000/TIFF格式
32位的圖像(CV_32F),支持PFM/TIFF/OpenEXR/TIFF/HDR
在要保存為指定格式之前,可以通過convertTo或者cvtCOLOR進行圖像類型或者通道轉(zhuǎn)換之后,再調(diào)用imwrite進行保存。OpenCV默認的圖像格式為CV_8UC3,此時圖像為3通道、8位RGB圖像,每個通道所能表達的灰度階為2^8=256。而視差圖常為CV_16S或CV_32S等,如果直接使用cv::imwrite()保存視差圖或深度圖,則圖像將被轉(zhuǎn)成CV_8U格式,而像素值大于255將會被轉(zhuǎn)成255。
OpenCV提供的接口函數(shù):cv::imwrite()、cv::imshow()都只能對像素值處于0-255范圍內(nèi)的圖像進行存儲和顯示,其他范圍內(nèi)的圖像,則會被轉(zhuǎn)成0-255范圍進行存儲、顯示。也就是說,無法使用OpenCV提供的接口函數(shù)存儲和顯示諸如CV_16S格式的視差圖/深度圖,只能轉(zhuǎn)換成CV_8U格式進行操作。
三、轉(zhuǎn)換為CV_16U/CV_16S,以及如何顯示16位圖像
(1)轉(zhuǎn)換
轉(zhuǎn)換后的類型=18=2:所以是CV_16U;因為imshow只能顯示CV_8U,所以顯示為全黑。
#include <iostream>
#include <sstream>
#include <time.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> using namespace cv;
using namespace std;
using namespace pcl;int main()
{Mat img = imread("12.bmp");cout << "before="<<img.type() << endl;img.convertTo(img, CV_16U);cout << "after=" << img.type() << endl;imshow("11", img);waitKey(0);system("pause");return 0;
}
(2)顯示
方法一:直接將16位轉(zhuǎn)成8位,也就是低于255的不變,高于的全部轉(zhuǎn)位255,數(shù)據(jù)的實際信息會丟失.如果設置為很大的值,數(shù)據(jù)丟失的會更大;
方法二:進行歸一化,數(shù)據(jù)類型依舊是CV_16U;
#include <iostream>
#include <sstream>
#include <time.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> using namespace cv;
using namespace std;
using namespace pcl;int main()
{Mat img = imread("12.bmp");cout << "before="<<img.type() << endl;img.convertTo(img, CV_16U);cout << "after=" << img.type() << endl;方法一//img.convertTo(img, CV_8U);//cout << "after=" << img.type() << endl;//方法二//進行了0~255的歸一化以后,可以顯示normalize(img,img, 0, 256 * 256, NORM_MINMAX);//normalize(img,img,-32768, 32767, NORM_MINMAX);//CV_16S的歸一化cout << "after=" << img.type() << endl;imshow("11", img);waitKey(0);system("pause");return 0;
}
(3)保存?
方法一://16位數(shù)據(jù)后,直接保存,不會引起數(shù)據(jù)的丟失,但是保存的是原始的數(shù)據(jù)
imwrite( "1.png", dst);
方法二:歸一化以后再保存
normalize(dst, dst, 0, 256* 256, NORM_MINMAX);imwrite( "1.png", dst);//進行了0~255的歸一化以后,可以顯示
四、轉(zhuǎn)換為CV_32F,以及如何顯示32位圖像?
(1)轉(zhuǎn)換
轉(zhuǎn)換后的類型=21=5:所以是CV_32F;因為imshow只能顯示CV_8U,所以顯示為全白。
#include <iostream>
#include <sstream>
#include <time.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> using namespace cv;
using namespace std;
using namespace pcl;int main()
{Mat img = imread("12.bmp");cout << "before="<<img.type() << endl;img.convertTo(img, CV_32F);cout << "after=" << img.type() << endl;imshow("11", img);waitKey(0);system("pause");return 0;
}
?(2)顯示
方法一:直接將32位轉(zhuǎn)成8位,也就是低于255的不變,高于的全部轉(zhuǎn)為255,數(shù)據(jù)的實際信息會丟失.如果設置為很大的值,數(shù)據(jù)丟失的會更大;
方法二:進行歸一化,數(shù)據(jù)類型依舊是CV_16U;
#include <iostream>
#include <sstream>
#include <time.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> using namespace cv;
using namespace std;
using namespace pcl;int main()
{Mat img = imread("12.bmp");cout << "before="<<img.type() << endl;img.convertTo(img, CV_32F);cout << "after=" << img.type() << endl;//方法一/*img.convertTo(img, CV_8U);cout << "after=" << img.type() << endl;*///方法二//進行了0~1的歸一化以后,可以顯示normalize(img,img, 0, 1, NORM_MINMAX);cout << "after=" << img.type() << endl;imshow("11", img);waitKey(0);system("pause");return 0;
}
(3)保存?
歸一化以后再保存
normalize(dst, dst, 0, 1, NORM_MINMAX);imwrite( "1.png", dst);//進行了0~1的歸一化以后,可以顯示
總結(jié)
以上是生活随笔為你收集整理的图像与数据类型的对应,以及如何显示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vector容器中erase(删除)的使
- 下一篇: opencv隔点采样(下采样)