使用Opencv绘制灰度直方图/对比
一.所需结构体
CvHistogram
结构体原型:
typedef struct CvHistogram {int type; /* 直方图类型 */CvArr* bins; /* 直方图数据 */ float thresh[CV-MAX-DIM][2]; /* 每一维的直方块边界数组 */float** thresh2; /* 非均匀直方图 */
CvMatND mat; /* 阵列柱状图的嵌入式矩阵头*/
} CvHistogram;
二.所需函数
1.cvCalcHist:
函数功能:用于计算图像直方图
函数原型:
void cvCalcHist( IplImage** image, CvHistogram* hist,int accumulate = 0,const CvArr* mask = NULL );
参数介绍:
IplImage** image: 要计算直方图的图像指针,如果要累加直方图输入图像颜色深度必须一致CvHistogram* hist: 输出参数,计算出来的直方图。int accumulate: 表示是否对传入的 hist 清零。不清零的话可以将多幅图像的直方图累加,0代表清零,非0代表不清零!const CvArr* mask: 掩码,如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和输入的图像的大小相同,值非 0 的点将用来计算直方图。
返回值:无
2.CvCreateHist:
函数功能:用于创建直方图
函数原型:
CvHistogram* cvCreateHist( int dims, int* sizes, int type,float** ranges = NULL,int uniform = 1);
参数介绍:
int dims: 表示图像是几维空间,即一般彩色图像是3通道的,dim=3;而灰度图是1通道的,dim=1,如果带有透明度的图像即RGBA则dim=4
int* sizes: //直方图维数尺寸,size数组的长度为dims,每个数表示分配给对应维数的bin的个数。如dims=3,则size中用[s1,s2,s3]分别指定每维bin的个数。
int type: 直方图的表示格式: CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组, CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组
float** ranges: 表示方块范围,假设该值设置为0-255意思就是说将像素点压缩到0-255个元素之间(压缩方法是叠加,列如像素点有1024个那么会将1024个像素点的每个值相加在一块放到size组中,比如将10个像素点的值叠加在一块,然后放到对应的size组中!),并将这0-255个元素分别分布到对应的size中!
int uniform: 归一化标识,如果不为0,bin均匀处理ranges的取值范围,为0,根据ranges的设置非均匀处理对应范围的直方块
返回值:成功返回一个指向堆中CvHistogram结构体的CvHistogram指针
3.cvGetMinMaxHistValue:
函数功能:用于统计直方图中最小值和最大值
函数原型:
void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value,int* min_idx = NULL,int* max_idx = NULL);
参数介绍:
const CvHistogram* hist: 要统计的直方图
float* min_value: 直方图最小值的指针
float* max_value: 直方图最大值的指针
int* min_idx: 数组中最小坐标的指针
int* max_idx: 数组中最大坐标的指针
返回值:无
4.cvConvertScale
函数功能:按比例缩放bin
函数原型:
void cvConvertScale( const CvArr* src, CvArr* dst,double scale = 1,double shift = 0);
参数介绍:
const CvArr* src: 输入数组
CvArr* dst: 输出数组
double scale: 比例因子
double shift: 该加数与输入元素相加并按比例缩放到输出数组的元素上
返回值:无
5.cvReleaseHist
函数功能:释放直方图
函数原型:
void cvReleaseHist( CvHistogram**hist);
参数介绍:
CvHistogram**hist : 直方图指针
返回值:无
二. 编写绘制灰度图像的直方图代码
准备工作已经完成,下面开始正式代码编写
2.1 准备工作
准备一张用于测试的图像文件,图像文件格式任意!
这里我的是jpg格式的图像文件
如需要可自行保存到本地
2.2 编写代码,加载测试图到内存
//打开测试图
IplImage * image = cvLoadImage("D:\\test.jpg",0); //将本地测试图导入到程序堆中
if (image == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}
2.2 创建一个直方图
//创建一个直方图
int arr_size = 255; //定义一个变量用于表示直方图行宽
float hranges_arr[] = { 0, 255 }; //图像方块范围数组
float *phranges_arr = hranges_arr; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
CvHistogram *hist = cvCreateHist(1, &arr_size, CV_HIST_ARRAY, &phranges_arr, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化
2.3 创建一个空白图像用来绘制直方图
//创建一个空白图像用于绘制直方图
IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(histimg); //清空histimag-imagedata数据
2.4 计算图像直方图
//计算图像直方图大小
cvCalcHist(&image, hist, 0, 0);
2.5 缩放直方图尺寸
//直方图根据size分组然后根据ranges取值范围来统计图像像素点范围,也就是说ranges为0-255则将图像中像素值叠加在一起(叠加成MIN:0、MIX:255)组并分组到对应的size维中,所以size维里的每个元素非常大,所以要按比例缩小
float max_val; //用于存储获取到的最大值cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0); //获取直方图最大值
cvConvertScale(hist->bins,hist->bins, max_val ? 255. / max_val : 0., 0); //按比例缩小直方图
2.6 绘制直方图
//开始绘制直方图
int bin_w;
bin_w = histimg->width / arr_size; //得到开始绘制点位置for (int i = 0; i < arr_size; i++){double val = (cvGetReal1D(hist->bins, i)*histimg->height / 255);//获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),cvPoint((i + 1)*bin_w, (int)(histimg->height - val)),color, 1, 8, 0);}
2.7 将直方图显示出来
//显示结果
cvShowImage("1", image); //原图
cvShowImage("2", histimg); //绘制出来的直方图
cvWaitKey(0); //消息循环
运行结果:
完整代码:
//打开测试图IplImage * image = cvLoadImage("D:\\3.jpg", 0); //将本地测试图导入到程序堆中if (image == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}//创建一个直方图int arr_size = 255; //定义一个变量用于表示直方图行宽float hranges_arr[] = { 0, 255 }; //图像方块范围数组float *phranges_arr = hranges_arr; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参CvHistogram *hist = cvCreateHist(1, &arr_size, CV_HIST_ARRAY, &phranges_arr, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化//创建一个空白图像用于绘制直方图IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(histimg);//清空histimag-imagedata数据//计算图像直方图大小cvCalcHist(&image, hist, 0, 0);//直方图根据size分组然后根据ranges取值范围来统计图像像素点范围,也就是说ranges为0-255则将图像中像素值叠加在一起(叠加成MIN:0、MIX:255)组并分组到对应的size维中,所以size维里的每个元素非常大,所以要按比例缩小float max_val; //用于存储获取到的最大值cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0); //获取直方图最大值cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0); //按比例缩小直方图//开始绘制直方图int bin_w; bin_w = histimg->width / arr_size;//得到开始绘制点位置for (int i = 0; i < arr_size; i++){double val = (cvGetReal1D(hist->bins, i)*histimg->height / 255); //获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),cvPoint((i + 1)*bin_w, (int)(histimg->height - val)),color, 1, 8, 0);}//显示结果cvShowImage("1", image); //灰度原图cvShowImage("2", histimg); //绘制出来的直方图cvWaitKey(0); //消息循环
三. 基于直方图颜色数据的对比
1. 所需函数
1.1cvCompareHist
函数功能:用于对比直方图bins数据,并将对比结果以double类型返回
函数原型:
double cvCompareHist( const CvHistogram* hist1,const CvHistogram* hist2,int method);
参数介绍:
const CvHistogram* hist1: 模板图
const CvHistogram* hist2: 要对比的图片
int method : 对比方法可取宏:
#define CV_COMP_CORREL 0 //值越大匹配度越高
#define CV_COMP_CHISQR 1 //值越小匹配度越高
#define CV_COMP_INTERSECT 2 //(归一化)值越大匹配度越高
#define CV_COMP_BHATTACHARYYA 3 //(归一化)值越小匹配度越高
返回值:根据method参数的值返回不同的匹配值!
2. 准备两张图片
3.开始编写代码
3.1 将比对图加载到内存
//加载比对图IplImage * image = cvLoadImage("D:\\1.jpg", 0); //将本地模板图导入到程序堆中if (image == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}IplImage * image1 = cvLoadImage("D:\\2.jpg", 0); //将本地对比图导入到程序堆中if (image1 == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}
3.2 创建两个直方图
//创建两个直方图用于存储模板和对比图的bin//创建模板直方图int arr_size = 255; //定义一个变量用于表示直方图行宽float hranges_arr[] = { 0, 255 }; //图像方块范围数组float *phranges_arr = hranges_arr; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参//创建对比图的直方图CvHistogram *hist = cvCreateHist(1, &arr_size, CV_HIST_ARRAY, &phranges_arr, 1);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化int arr_size1 = 255; //定义一个变量用于表示直方图行宽float hranges_arr1[] = { 0, 255 }; //图像方块范围数组float *phranges_arr1 = hranges_arr1; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参CvHistogram *hist1 = cvCreateHist(1, &arr_size1, CV_HIST_ARRAY, &phranges_arr1, 1);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化3.3 计算两张图像的直方图
3.3 计算直方图大小
//计算图像的直方图大小,并保存到hist与hist1结构体中
cvCalcHist(&image, hist, 0, 0);
cvCalcHist(&image1, hist1, 0, 0);
3.4 对比直方图
//将计算后图像直方图与对比图进行比较,并将比较结果保存到Copare变量中
double Compare = cvCompareHist(hist, hist1, 0); //使用CV_COMP_CORREL方法进行对比
3.5 将图像与对比结果显示出来
//将图像与对比结果显示出来
//创建窗口
cvNamedWindow("image_mode",0);//模板窗口
cvNamedWindow("image1",0);//对比图像窗口
//显示图像
cvShowImage("image_mode", image);
cvShowImage("image1", image1);
//打印对比结果:
printf("对比结果为:%lf", Compare);
cvWaitKey(0); //消息循环
运行结果:
可以看到相似度很高
完整代码:
//加载比对图IplImage * image = cvLoadImage("D:\\1.jpg", 0); //将本地模板图导入到程序堆中if (image == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}IplImage * image1 = cvLoadImage("D:\\2.jpg", 0); //将本地对比图导入到程序堆中if (image1 == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}
//创建两个直方图用于存储模板和对比图的bin//创建模板直方图int arr_size = 255; //定义一个变量用于表示直方图行宽float hranges_arr[] = { 0, 255 }; //图像方块范围数组float *phranges_arr = hranges_arr; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参//创建对比图的直方图CvHistogram *hist = cvCreateHist(1, &arr_size, CV_HIST_ARRAY, &phranges_arr, 1);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化int arr_size1 = 255; //定义一个变量用于表示直方图行宽float hranges_arr1[] = { 0, 255 }; //图像方块范围数组float *phranges_arr1 = hranges_arr1; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参CvHistogram *hist1 = cvCreateHist(1, &arr_size1, CV_HIST_ARRAY, &phranges_arr1, 1);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化3.3 计算两张图像的直方图
//计算图像的直方图大小,并保存到hist与hist1结构体中
cvCalcHist(&image, hist, 0, 0);
cvCalcHist(&image1, hist1, 0, 0);
//将计算后图像直方图与对比图进行比较,并将比较结果保存到Copare变量中
double Compare = cvCompareHist(hist, hist1, 0); //使用CV_COMP_CORREL方法进行对比
//将图像与对比结果显示出来
//创建窗口
cvNamedWindow("image_mode",0);//模板窗口
cvNamedWindow("image1",0);//对比图像窗口
//显示图像
cvShowImage("image_mode", image);
cvShowImage("image1", image1);
//打印对比结果:
printf("对比结果为:%lf", Compare);
cvWaitKey(0); //消息循环
试试看,修改以上代码,打印结果时将直方图也一并绘制出来
在cvWaitKey代码前加入如下代码:
//直方图根据size分组然后根据ranges取值范围来统计图像像素点范围,也就是说ranges为0-255则将图像中像素值叠加在一起(叠加成MIN:0、MIX:255)组并分组到对应的size维中,所以size维里的每个元素非常大,所以要按比例缩小
//缩小模板直方图bin
float max_val; //用于存储获取到的最大值
cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0); //获取直方图最大值
cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0); //按比例缩小直方图
//缩小对比直方图bin
float max_val1; //用于存储获取到的最大值
cvGetMinMaxHistValue(hist1, 0, &max_val1, 0, 0); //获取直方图最大值
cvConvertScale(hist1->bins, hist1->bins, max_val1 ? 255. / max_val1 : 0., 0); //按比例缩小
IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3); //模板图的直方图
IplImage *histimg1 = cvCreateImage(cvSize(320, 200), 8, 3); //对比图的直方图
//绘制模板直方图int bin_w; bin_w = histimg->width / arr_size;//得到开始绘制点位置for (int i = 0; i < arr_size; i++){double val = (cvGetReal1D(hist->bins, i)*histimg->height / 255); //获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),cvPoint((i + 1)*bin_w, (int)(histimg->height - val)),color, 1, 8, 0);}//绘制对比图直方图int bin_w1; bin_w1 = histimg1->width / arr_size1;//得到开始绘制点位置for (int i = 0; i < arr_size1; i++){double val = (cvGetReal1D(hist1->bins, i)*histimg1->height / 255); //获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg1, cvPoint(i*bin_w1, histimg1->height),cvPoint((i + 1)*bin_w1, (int)(histimg1->height - val)),color, 1, 8, 0);}
//将直方图显示出来
cvShowImage("1", histimg); //显示模板直方图
cvShowImage("2", histimg1);//显示对比直方图
运行结果:
修改后的完整代码:
//加载比对图IplImage * image = cvLoadImage("D:\\1.jpg",0); //将本地模板图导入到程序堆中if (image == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}IplImage * image1 = cvLoadImage("D:\\2.jpg",0); //将本地对比图导入到程序堆中if (image1 == NULL){ //判断是否打开成功printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}//创建两个直方图用于存储模板和对比图的bin//创建模板直方图int arr_size = 255; //定义一个变量用于表示直方图行宽float hranges_arr[] = { 0, 255 }; //图像方块范围数组float *phranges_arr = hranges_arr; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参//创建对比图的直方图CvHistogram *hist = cvCreateHist(1, &arr_size, CV_HIST_ARRAY, &phranges_arr, 3);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化int arr_size1 = 255; //定义一个变量用于表示直方图行宽float hranges_arr1[] = { 0, 255 }; //图像方块范围数组float *phranges_arr1 = hranges_arr1; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参CvHistogram *hist1 = cvCreateHist(1, &arr_size1, CV_HIST_ARRAY, &phranges_arr1, 3);//创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化3.3 计算两张图像的直方图//计算图像的直方图大小,并保存到hist与hist1结构体中cvCalcHist(&image, hist, 0, 0);cvCalcHist(&image1, hist1, 0, 0);//将计算后图像直方图与对比图进行比较,并将比较结果保存到Copare变量中double Compare = cvCompareHist(hist, hist1, 0); //使用CV_COMP_CORREL方法进行对比//将图像与对比结果显示出来//创建窗口cvNamedWindow("image_mode",0);cvNamedWindow("image1",0);//显示图像cvShowImage("image_mode", image);cvShowImage("image1", image1);//打印对比结果:printf("对比结果为:%lf", Compare);//直方图根据size分组然后根据ranges取值范围来统计图像像素点范围,也就是说ranges为0-255则将图像中像素值叠加在一起(叠加成MIN:0、MIX:255)组并分组到对应的size维中,所以size维里的每个元素非常大,所以要按比例缩小//缩小模板直方图binfloat max_val; //用于存储获取到的最大值cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0); //获取直方图最大值cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0); //按比例缩小直方图//缩小对比直方图binfloat max_val1; //用于存储获取到的最大值cvGetMinMaxHistValue(hist1, 0, &max_val1, 0, 0); //获取直方图最大值cvConvertScale(hist1->bins, hist1->bins, max_val1 ? 255. / max_val1 : 0., 0); //按比例缩小IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3); //模板图的直方图IplImage *histimg1 = cvCreateImage(cvSize(320, 200), 8, 3); //对比图的直方图//绘制模板直方图int bin_w;bin_w = histimg->width / arr_size;//得到开始绘制点位置for (int i = 0; i < arr_size; i++){double val = (cvGetReal1D(hist->bins, i)*histimg->height / 255); //获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg, cvPoint(i*bin_w, histimg->height),cvPoint((i + 1)*bin_w, (int)(histimg->height - val)),color, 1, 8, 0);}//绘制对比图直方图int bin_w1;bin_w1 = histimg1->width / arr_size1;//得到开始绘制点位置for (int i = 0; i < arr_size1; i++){double val = (cvGetReal1D(hist1->bins, i)*histimg1->height / 255); //获取矩阵元素值,并转换为对应高度CvScalar color = CV_RGB(255, 255, 0); cvRectangle(histimg1, cvPoint(i*bin_w1, histimg1->height),cvPoint((i + 1)*bin_w1, (int)(histimg1->height - val)),color, 1, 8, 0);}cvShowImage("1", histimg); //显示模板直方图
cvShowImage("2", histimg1);//显示对比直方图cvWaitKey(0); //消息循环
使用Opencv绘制灰度直方图/对比相关推荐
- [Python图像处理] 三十七.OpenCV直方图统计两万字详解(掩膜直方图、灰度直方图对比、黑夜白天预测)
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- opencv python matplotlib.pyplot.hist() 如何绘制灰度直方图,如何根据灰度直方图确定最优二值化值
什么是灰度直方图? 图像直方图(histogram)是图像的统计学特征,常用于了解图像的基本特征以便分析.不过图像的直方图不具有空间特征. 图像的灰度直方图(histogram),就是将图像转化成灰度 ...
- [Python从零到壹] 五十一.图像增强及运算篇之图像灰度直方图对比分析万字详解
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- 【 OpenCV】——灰度直方图
[ OpenCV]--灰度直方图 前言 本文介绍了灰度直方图的基础内容. 对函数参数的解释 void calcHist { const Mat*images,//输入的矩阵数组或数据集 int nim ...
- 【python图像处理】python绘制灰度直方图
灰度直方图在数据统计分析.图像处理中有着比较广泛的应用,下面就介绍一下如何使用python来绘制灰度直方图. 下面直接看代码: import matplotlib.pyplot as plt impo ...
- python 灰度直方图_python3+opencv 使用灰度直方图来判断图片的亮暗操作
1.如何让计算机自动判断一张图是否偏暗?或是判断一张图是否是处于夜晚?我们可以先把图片转换为灰度图,然后根据灰度值的分布来判断,如: 我们可以从上图看到,晚上的图片的灰度值是集中在前段的,如0~30多 ...
- python绘制灰度直方图_python+opencv 灰度直方图及其二值化
图像直方图(histogram)是图像的统计学特征,常用于了解图像的基本特征以便分析.不过图像的直方图不具有空间特征. 图像的灰度直方图(histogram),就是将图像转化成灰度图像之后,统计各个像 ...
- C++OpenCV下绘制灰度直方图
C++OpenCV下绘制直方图 直方图的定义:灰度直方图是对一幅灰度图像素分布的统计.对于一幅8Bit量化的图像来说.就是统计在0~255各个灰度级上,像素点的个数或者密度. 在OpenCV库提供了c ...
- 【数字图像处理】四.MFC对话框绘制灰度直方图
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行回忆讲解,主要通过MFC单文档视图实现点击弹出对话框绘制BMP图片的灰度直方图, ...
最新文章
- 死猪脑”能复活吗?---评美国耶鲁大学医学院实验研究
- ajax java对象返回前台少了属性_AJAX常见提交数据的三种方式
- GIS坡度分析入门实例 - 使用SuperMap
- 数据库中char varchar nchar nvarchar的区别
- 【Redis学习笔记】2018-06-12 复制与传播
- CUDA学习(九十一)
- 有关PHP、HTML单引号、双引号转义以及转成HTML实体的那些事!
- Springboot遇到的问题
- java学完jdk后学什么_学完了javase之后要学什么?
- ffmpeg解码到opencv Mat中
- APT linux必知必会
- one list to muti list
- Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)
- 计算机机房需求调查表,机房建设需求调查表.doc
- redis php 使用实例
- mysql多个数据库查询_如何跨多个数据库查询
- uniapp点击复制文本
- Android文字转语音播报
- Spring Hibernate Validation
- python短信验证码登录_Python实现短信验证
热门文章
- vivado dds IP核笔记
- jdk下载安装并配置环境
- spring c3p0 mysql_spring boot整合mybatis使用c3p0数据源连接mysql
- activiti 解压zip java.lang.IllegalArgumentException: MALFORMED 错误
- 你真的理解a -- -- a a++ ++a 吗?
- 打印html文件都是空白页,我打印时的额外空白页面(IE中除外) – 是我的打印css吗?...
- java 内存分布_java的各类型数据在内存中分配情况详解_
- R语言作图之ggplot2作图2
- 这样找电子书,方法贴!
- python中0o10_Python中最常见的10个问题(列表)