图像与数据类型的对应,以及如何显示

news/2024/9/17 15:44:31

1、normalize函数

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)函数的作用

将输入图像src归一化。

注意:alpha、beta作为规范范围的上下限,代表的是输入图像数据类型的显示范围。

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)参数说明 

src               输入数组;
dst               输出数组,数组的大小和原数组一致;
alpha           1,用来规范值,2.规范范围,并且是下限;
beta             只用来规范范围并且是上限;
norm_type   归一化选择的数学公式类型;
dtype           当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方游dtype决定;
mark            掩码。选择感兴趣区域,选定后只能对该区域进行操作。

2、mat.type()函数

opencv中Mat存在各种类型,其中mat有一个type()的函数可以返回该Mat的类型。类型表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量。具体的有以下值:

通道数我们可以发现,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

一、显示数据类型

#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函数

imshow
opencv的imshow函数都只能对像素值处于0-255范围内的图像进行显示。也就是说,无法使用OpenCV提供的接口函数显示诸如CV_16S等非8位数据格式的视差图/深度图,只能转换成CV_8U格式进行操作。
其实,人眼对灰度级的敏感度比较低、根本无法分辨256级灰度值。而对视差图/深度图进行显示,也只是为了比较直观的验证视差图/深度图的准确性(如颜色随距离逐层变化),所以说完全没必要对216 =65536级灰度进行显示,转换成CV_8U格式就能完全满足需求,这也许就是为什么OpenCV没有提供这样接口的原因之一吧。

imwrite
而存储的话,imwrite函数在关于保存为不同深度格式时候的图像类型支持说明如下:

8位的图像(CV_8U),支持png/jpg/bmp/webp等各种常见图像格式
16位的图像(CV_16U),支持png/jpeg2000/TIFF格式
32位的图像(CV_32F),支持PFM/TIFF/OpenEXR/TIFF/HDR
在要保存为指定格式之前,可以通过convertTo或者cvtCOLOR进行图像类型或者通道转换之后,再调用imwrite进行保存。

OpenCV默认的图像格式为CV_8UC3,此时图像为3通道、8位RGB图像,每个通道所能表达的灰度阶为2^8=256。而视差图常为CV_16S或CV_32S等,如果直接使用cv::imwrite()保存视差图或深度图,则图像将被转成CV_8U格式,而像素值大于255将会被转成255。

OpenCV提供的接口函数:cv::imwrite()、cv::imshow()都只能对像素值处于0-255范围内的图像进行存储和显示,其他范围内的图像,则会被转成0-255范围进行存储、显示。也就是说,无法使用OpenCV提供的接口函数存储和显示诸如CV_16S格式的视差图/深度图,只能转换成CV_8U格式进行操作。

三、转换为CV_16U/CV_16S,以及如何显示16位图像

(1)转换

转换后的类型=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位转成8位,也就是低于255的不变,高于的全部转位255,数据的实际信息会丢失.如果设置为很大的值,数据丢失的会更大

方法二:进行归一化,数据类型依旧是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位数据后,直接保存,不会引起数据的丢失,但是保存的是原始的数据

imwrite( "1.png", dst);

方法二:归一化以后再保存
normalize(dst, dst, 0, 256* 256, NORM_MINMAX);

imwrite( "1.png", dst);//进行了0~255的归一化以后,可以显示

四、转换为CV_32F,以及如何显示32位图像 

(1)转换

转换后的类型=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位转成8位,也就是低于255的不变,高于的全部转为255,数据的实际信息会丢失.如果设置为很大的值,数据丢失的会更大

方法二:进行归一化,数据类型依旧是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的归一化以后,可以显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/18665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

C++:字符串流

C标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能&#xff0c;即单纯性、类型安全和可扩展性。 &#xff08;PS&#xff1a;自己解释的不知道准确不&#xff1f;&#xff09; str()成员函数的使用可以让stringstream对象返回一个string字符串。 c…

力扣(LeetCode)刷题,简单+中等题(第35期)

力扣(LeetCode)定期刷题&#xff0c;每期10道题&#xff0c;业务繁重的同志可以看看我分享的思路&#xff0c;不是最高效解决方案&#xff0c;只求互相提升。 第1题&#xff1a;解码异或后的排列 试题要求如下&#xff1a; 回答&#xff08;C语言&#xff09;&#xff1a; /…

main函数的argc与argv

int main(int argc, char** argv) 1、 argc与argv的默认值&#xff08;argv相当于数组&#xff0c;尺寸由argc控制&#xff09; argc默认为1&#xff0c;因此argv的默认是argv[0]—指向程序运行时的全路径名 #include <iostream> #include <opencv2/core/core.hpp>…

C++:文件操作2 文本文件和二进制文件的读写

文件读写的步骤&#xff1a; 1、包含的头文件&#xff1a;#include <fstream>//使用文件流进行操作 2、创建流 3、打开文件(文件和流关联) 4、读写 (写操作&#xff1a;<<,put( ), write( ) 读操作&#xff1a; >> , get( ),getline( ), read( )) 5、关…

JavaScript+TensorFlow.js让你在视频中瞬间消失

最近&#xff0c;一个实时人物删除&#xff08;Real Time Person removation&#xff09;的项目在GitHub上流行起来。 这个项目的神奇之处在于&#xff0c;只需要在网页浏览器中使用JavaScript&#xff0c;并使用200多行TensorFlow.js代码&#xff0c;就能让视频屏幕中的字符和…

PCB天线无线模组如何布局摆放?

随着物联网的高速发展&#xff0c;市面上涌现出越来越多的智慧产品&#xff0c;如智能家居&#xff0c;智能交通&#xff0c;智能城市等&#xff0c;这些终端设备大都靠无线收、发模块来实现信息的传递与接收。随着市场竞争的加剧&#xff0c;硬件设备正以集成化的方向发展&…

C++:while(getline())函数

首先说明getline&#xff08;&#xff09;的原型&#xff1a;getline&#xff08;istream &is,string &str,char delim&#xff09; istream &is表示一个输入流&#xff0c;譬如cin&#xff0c;string表示把从输入流读入的字符串存放在这个字符串中&#xff08;&am…

opencv隔点采样(下采样)

1、先验知识 对灰度图像来说&#xff0c;img.step[0]代表图像一行的的长度&#xff1a;img.step[0]img.cols; img.step[1]代表图像一个元素的数据大小&#xff1a;img.step[0]img.channels() ; img.data: uchar的指针&#xff0c;指向Mat数据矩阵的首地址。 2、验证&#xff1a…