1.输出图像深度与通道
IplImage* queryImg = cvLoadImage("x1.jpg");//输入图像
输出该图像的深度与通道:
cout << "图像深度:" << queryImg->depth << endl;
cout << "图像通道:" << queryImg->nChannels<< endl;
结果:
图像深度:8
图像通道:3
ps:彩色图像是3通道,灰度图像是单通道
2.图像不同位深度间的转换
depth 图像元素的位深度,可以是下面的其中之一:
位深度 取值范围
IPL_DEPTH_8U - 无符号8位整型 0--255
IPL_DEPTH_8S - 有符号8位整型 -128--127
IPL_DEPTH_16U - 无符号16位整型 0--65535
IPL_DEPTH_16S - 有符号16位整型 -32768--32767
IPL_DEPTH_32S - 有符号32位整型 0--65535
IPL_DEPTH_32F - 单精度浮点数 0.0--1.0
IPL_DEPTH_64F - 双精度浮点数 0.0--1.0
位深度转换原理
如上,给出图像的位深度及其取值范围后,要转换位深度本质上就是对原深度下的数据做线性变换,使原位深度下的最小值和最大值分别对应转换后位深度下的最小值和最大值。实现上述线性变换,我们可以用opencv库函数cvConvertScale。
cvConvertScale函数简介
cvConvertScale( const CvArr* src, CvArr* dst,double scale CV_DEFAULT(1),double shift CV_DEFAULT(0) );
功能:使用线性变换转换数组
参数说明: src 输入数组,dst 输出数组,scale 比例因子,shift 偏移量。
对应的线性变换公式: dst(I)=src(I)*scale + (shift,shift,...)。
示例1:
将IPL_DEPTH_8U 转换成 IPL_DEPTH_32F,我们需要用线性变换将[0 255] 映射为 [0 1]。不难求出线性变换的参数scale=1/255, shift=0。即通过如下代码可实现位深度间转换(注,函数最后一个参数为0,等于默认参数,可以不用写)。
cvConvertScale(img8, img32, 1.0/255, 0); //img8:8位。img32:32位
代码1:
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
//加载两张图片(彩色图,8位3通道)
IplImage* queryImg = cvLoadImage("x1.jpg");
IplImage* trainImg = cvLoadImage("x2.jpg");
//转换为灰度图(8位单通道)
IplImage* queryGrey = cvCreateImage(cvGetSize(queryImg), IPL_DEPTH_8U, 1);//创建目标图像
cvCvtColor(queryImg, queryGrey, CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
IplImage* trainGrey = cvCreateImage(cvGetSize(trainImg), IPL_DEPTH_8U, 1);//创建目标图像
cvCvtColor(trainImg, trainGrey, CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
//将8位灰度图(单通道)转为32位(单通道)
IplImage *queryImg32 = cvCreateImage(cvSize(queryImg->width, queryImg->height), IPL_DEPTH_32F, 1);
cvConvertScale(queryGrey, queryImg32, 1 / 255.);
IplImage *trainImg32 = cvCreateImage(cvSize(queryImg->width, queryImg->height), IPL_DEPTH_32F, 1);
cvConvertScale(trainGrey, trainImg32, 1 / 255.);
cvShowImage("图1", queryImg32);
cvShowImage("图2", trainImg32);
cvReleaseImage(&queryImg32);
cvReleaseImage(&trainImg32);
cvWaitKey(0);
return 0;
}
如果IPL_DEPTH_32F转换成IPL_DEPTH_8U,我们需要用线性变换将[0 1] 映射为 [0 255]。对应的参数为scale=255, shift=0。即可通过如下代码行实现两位深度间的转换。
cvConverScale(img32, img8, 255, 0);
示例2:
将IPL_DEPTH_8U 转换成 IPL_DEPTH_16U,我们需要用线性变换将[0 65535] 映射为 [0 1]。不难求出线性变换的参数scale=257, shift=0。即通过如下代码可实现位深度间转换(注,函数最后一个参数为0,等于默认参数,可以不用写)。
代码2:
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
//加载两张图片(彩色图,8位3通道)
IplImage* queryImg = cvLoadImage("x1.jpg");
IplImage* trainImg = cvLoadImage("x2.jpg");
//转换为灰度图(8位单通道)
IplImage* queryGrey = cvCreateImage(cvGetSize(queryImg), IPL_DEPTH_8U, 1);//创建目标图像
cvCvtColor(queryImg, queryGrey, CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
IplImage* trainGrey = cvCreateImage(cvGetSize(trainImg), IPL_DEPTH_8U, 1);//创建目标图像
cvCvtColor(trainImg, trainGrey, CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
//将8位灰度图(单通道)转为16位(单通道)
IplImage *queryImg16U = cvCreateImage(cvSize(queryImg->width, queryImg->height), IPL_DEPTH_16U, 1);
cvConvertScale(queryGrey, queryImg16U,257);
IplImage *trainImg16U = cvCreateImage(cvSize(queryImg->width, queryImg->height), IPL_DEPTH_16U, 1);
cvConvertScale(trainGrey, trainImg16U, 257);
cvShowImage("图1", queryImg16U);
cvShowImage("图2", trainImg16U);
cvReleaseImage(&queryImg16U);
cvReleaseImage(&trainImg16U);
cvWaitKey(0);
return 0;
}
怎么转换为有符号的还没有写:???
参考网站:
http://blog.youkuaiyun.com/breeze5428/article/details/30055391
http://blog.youkuaiyun.com/qq_18343569/article/details/47830503