opencv 图像深度depth的理解

我们在创建mat的时候,可以选择的CvType中有很多的选项

CV_8UC1           CV_8SC1           CV_16U C1       CV_16SC1 
CV_8UC2           CV_8SC2           CV_16UC2        CV_16SC2 
CV_8UC3           CV_8SC3           CV_16UC3        CV_16SC3 
CV_8UC4           CV_8SC4           CV_16UC4        CV_16SC4 
CV_32SC1          CV_32FC1          CV_64FC1
CV_32SC2          CV_32FC2          CV_64FC2
CV_32SC3          CV_32FC3          CV_64FC3
CV_32SC4          CV_32FC4          CV_64FC4

其实组成都是CV_+深度+通道 其中里面的数字8 ,16,32 标识的是深度

什么是一个Mat的深度,mat的深度有什么意义

CV_8U is unsigned 8bit/pixel - ie a pixel can have values 0-255, this is the normal range for most image and video formats.

CV_32F is float - the pixel can have any value between 0-1.0, this is useful for some sets of calculations on data - but it has to be converted into 8bits to save or display by multiplying each pixel by 255.

CV_32S is a signed 32bit integer value for each pixel - again useful of you are doing integer maths on the pixels, but again needs converting into 8bits to save or display. This is trickier since you need to decide how to convert the much larger range of possible values (+/- 2billion!) into 0-255

 

大概的意思是说:

CV_8U是无符号8位/像素-即一个像素可以有0-255的值,这是大多数图像和视频格式的正常范围。

CV_32F是float-像素可以有0-1.0之间的任何值,这对于某些数据集的计算很有用-但必须将其转换为8位才能通过将每个像素乘以255来保存或显示。

CV_32S是每个像素的一个有符号32位整数值-同样有用的是,您正在对像素进行整数运算,但同样需要转换为8位才能保存或显示。因为您需要决定如何转换更大范围的可能值(+/-20亿!)变成0-255

其实在mat的属性中有个depth()这个函数,我以为这个求解的就是图片的深度,但是并不是,所以我们千万不能用这个depth()的值作为图片的 深度来理解,这个depth() 是我们在定义mat的时候CV_Type对应的值

CV_8U   0
CV_8S   1
CV_16U  2
CV_16S  3
CV_32S  4
CV_32F  5
CV_64F  6
CV_USRTYPE1 7

这些值和图片的深度还有一定的关联的,比如:

depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;

depth:深度,即每一个像素的位数(bits),那么我们创建的时候就可以知道根据类型也就可以知道每个像素的位数,也就是知道了创建mat的深度

图像深度的意义:

   图像深度是指存储每个像素所用的位数,也用于量度图像的色彩分辨率.图像深度确定彩色图像的每个像素可能有的颜色数,或者确定灰度图像的每个像素可能有的灰度级数.

  它决定了彩色图像中可出现的最多颜色数,或灰度图像中的最大灰度等级.比如一幅单色图像,若每个象素有8位,则最大灰度数目为2的8次方,即256.

在学习的过程中突然遇到图片的深度,上面是我的理解

不同的深度之间如何进行转换,我们以8UC3 转换为32FC3为例子

public static void main(String[] args) {
		try {
			ResourceBundle bundle = ResourceBundle.getBundle("opencv");
			String opencvDllName = bundle.getString("opencv.dllpath");
			System.load(opencvDllName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		String filename = "D:\\360MoveData\\Users\\lxn\\Desktop\\opencv\\xf.bmp";
		Mat mat = Imgcodecs.imread(filename);//首先是读取图片,默认是是CV_8UC2
		Mat submat = mat.submat(10, 200, 10, 200);  //为了方便展示我们,截取图片的一部分内容
		
		
		
		Mat mat_32F = new Mat(submat.size(), CvType.CV_32FC3);//创建一个32FC3的矩阵
		
		
		//将8UC3转换为32FC3
		for (int i = 0; i < submat.rows(); i++) {
			for (int j = 0; j < submat.cols(); j++) {
				double[] values = new double[] {};
				values = submat.get(i, j);
				mat_32F.put(i, j, new double[] { values[0] / 255.0, values[1] / 255.0,values[2] / 255.0 });
			}
		}

		
		//将32FC3 转换为32SC3
		Mat mat_32S = new Mat(submat.size(), CvType.CV_32SC3);
		mat_32F.convertTo(mat_32S,  CvType.CV_32SC3);
		
		
		
		
		//将32FC3 转换为CV_8UC3
		for (int i = 0; i < mat_32S.rows(); i++) {
			for (int j = 0; j < mat_32S.cols(); j++) {
				double[] values = new double[] {};
				values = mat_32F.get(i, j);
				mat_32S.put(i, j,new int[] { (int) (values[0] * 255.0), (int) (values[1] * 255.0), (int) (values[2] * 255.0) });
			}
		}
		Mat mat_s = new Mat();
		mat_32S.convertTo(mat_s, CvType.CV_8UC3);

		
		HighGui.imshow("测试", mat_s);
		HighGui.waitKey();

	}

covertTo 这个方法是实现了不同mat之间的类型转换,但是里面的具体的数值还是需要我们*255,或者/255 进行手动的转换

希望对你有所帮助

 

  • 15
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值