使用OpenCV进行批量图像缩放

来源:互联网 发布:ubuntu16如何安装软件 编辑:程序博客网 时间:2024/05/16 02:20
问题是这样子的,有好多个文件夹,希望对每个文件夹中的图像都缩放到同一个比例。

那么不可避免,需要读取每个文件夹中的图像名称:

<span style="font-size:14px;">void getFiles(string path, vector<string>& files){//文件句柄  long   hFile = 0;//文件信息  struct _finddata_t fileinfo;string p;if ((hFile = _findfirst(p.assign(path).append("\\*.jpg").c_str(), &fileinfo)) != -1){do{//如果是目录,迭代之  //如果不是,加入列表  if ((fileinfo.attrib &  _A_SUBDIR)){if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)getFiles(p.assign(path).append("\\").append(fileinfo.name), files);}else{files.push_back(p.assign(fileinfo.name));}} while (_findnext(hFile, &fileinfo) == 0);_findclose(hFile);}}</span>

图像缩放的库函数(参考:http://blog.csdn.net/morewindows/article/details/8239560):

void cvResize(

  const CvArr*src,

  CvArr*dst,

  int interpolation=CV_INTER_LINEAR

);

第一个参数表示输入图像。

第二个参数表示输出图像。

第三个参数表示插值方法,可以有以下四种:

CV_INTER_NN -最近邻插值,

CV_INTER_LINEAR -双线性插值 (缺省使用)

CV_INTER_AREA -使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN方法..

CV_INTER_CUBIC -立方插值.

这个函数在功能上与Win32 API中的StretchBlt()函数类似。


因为我这里是缩小,所以第3个参数选择:CV_INTER_AREA

//dataType == 1  train Data//dataType == 0  val Datavoid convert_im(int dataType){string pstrImageNameTrain = "Z:\\算法组\\****\\data\\newTrain\\";string pstrImageNameVal = "Z:\\算法组\\****\\data\\newVal\\";string pefix = "Z:\\算法组\\****\\data\\";char* imNametrain227[] = { "train227_1\\", "train227_2\\", "train227_3\\", "train227_4\\", "train227_5\\", "train227_6\\", "train227_7\\", "train227_8\\" };char* imNameval227[] = { "val227_1\\", "val227_2\\", "val227_3\\", "val227_4\\", "val227_5\\", "val227_6\\", "val227_7\\", "val227_8\\" };vector<string> files;if (dataType == 1)getFiles(pstrImageNameTrain, files);elsegetFiles(pstrImageNameVal, files);int fileNum = files.size();if (dataType == 1)printf("total files number in Train is %d\n", fileNum);elseprintf("total files number in Val is %d\n", fileNum);//创建8种尺寸的缩放图像大小CvSize im227[8];for (int i = 0; i < 8; i++){im227[i].width = 227 * (i + 1);im227[i].height = im227[i].width;}for (int i = 0; i < fileNum; i++){string pstrImageNameTrain = "Z:\\算法组\\****\\data\\newTrain\\";string pstrImageNameVal = "Z:\\算法组\\****\\data\\newVal\\";//从文件中读取图像 IplImage *pSrcImage = NULL;if (dataType == 1)pSrcImage = cvLoadImage(pstrImageNameTrain.append( files[i]).c_str(), CV_LOAD_IMAGE_UNCHANGED);elsepSrcImage = cvLoadImage(pstrImageNameVal.append(files[i]).c_str(), CV_LOAD_IMAGE_UNCHANGED);for (int j = 0; j < 8; j++){string pefix = "Z:\\算法组\\****\\data\\";//创建图像并缩放  IplImage *pDstImage = cvCreateImage(im227[j], pSrcImage->depth, pSrcImage->nChannels);;cvResize(pSrcImage, pDstImage, CV_INTER_AREA);//保存图片  if (dataType == 1){string pstrSaveImageName = pefix.append(imNametrain227[j]);cvSaveImage(pstrSaveImageName.append(files[i]).c_str(), pDstImage);}else{string pstrSaveImageName = pefix.append(imNameval227[j]);cvSaveImage(pstrSaveImageName.append(files[i]).c_str(), pDstImage);}cvReleaseImage(&pDstImage);}cvReleaseImage(&pSrcImage);if ((i+1) % 100 == 0 && i > 0)printf("finish %d files!\n", i + 1);}if (fileNum % 100 != 0)printf("finish %d files!\n", fileNum);}

因为我的数据分两种,每种图像数据都需要缩放到不同大小的图像(227×227, 454×454, 等等),所以我干脆对目标图像大小建立了一个数组。

最终的整个代码如下:

//批量缩放图像#include <opencv2/opencv.hpp>  #include <stdio.h>#include <io.h>#include <string.h>using namespace std;void getFiles(string path, vector<string>& files);void convert_im(int dataType);int main(){printf("convert im for train data\n");convert_im(1);printf("convert im for val data\n");convert_im(0);return 0;}//dataType == 1  train Data//dataType == 0  val Datavoid convert_im(int dataType){string pstrImageNameTrain = "Z:\\算法组\\****\\data\\newTrain\\";string pstrImageNameVal = "Z:\\算法组\\****\\data\\newVal\\";string pefix = "Z:\\算法组\\****\\data\\";char* imNametrain227[] = { "train227_1\\", "train227_2\\", "train227_3\\", "train227_4\\", "train227_5\\", "train227_6\\", "train227_7\\", "train227_8\\" };char* imNameval227[] = { "val227_1\\", "val227_2\\", "val227_3\\", "val227_4\\", "val227_5\\", "val227_6\\", "val227_7\\", "val227_8\\" };vector<string> files;if (dataType == 1)getFiles(pstrImageNameTrain, files);elsegetFiles(pstrImageNameVal, files);int fileNum = files.size();if (dataType == 1)printf("total files number in Train is %d\n", fileNum);elseprintf("total files number in Val is %d\n", fileNum);//创建8种尺寸的缩放图像大小CvSize im227[8];for (int i = 0; i < 8; i++){im227[i].width = 227 * (i + 1);im227[i].height = im227[i].width;}for (int i = 0; i < fileNum; i++){string pstrImageNameTrain = "Z:\\算法组\\****\\data\\newTrain\\";string pstrImageNameVal = "Z:\\算法组\\****\\data\\newVal\\";//从文件中读取图像 IplImage *pSrcImage = NULL;if (dataType == 1)pSrcImage = cvLoadImage(pstrImageNameTrain.append( files[i]).c_str(), CV_LOAD_IMAGE_UNCHANGED);elsepSrcImage = cvLoadImage(pstrImageNameVal.append(files[i]).c_str(), CV_LOAD_IMAGE_UNCHANGED);for (int j = 0; j < 8; j++){string pefix = "Z:\\算法组\\****\\data\\";//创建图像并缩放  IplImage *pDstImage = cvCreateImage(im227[j], pSrcImage->depth, pSrcImage->nChannels);;cvResize(pSrcImage, pDstImage, CV_INTER_AREA);//保存图片  if (dataType == 1){string pstrSaveImageName = pefix.append(imNametrain227[j]);cvSaveImage(pstrSaveImageName.append(files[i]).c_str(), pDstImage);}else{string pstrSaveImageName = pefix.append(imNameval227[j]);cvSaveImage(pstrSaveImageName.append(files[i]).c_str(), pDstImage);}cvReleaseImage(&pDstImage);}cvReleaseImage(&pSrcImage);if ((i+1) % 100 == 0 && i > 0)printf("finish %d files!\n", i + 1);}if (fileNum % 100 != 0)printf("finish %d files!\n", fileNum);}void getFiles(string path, vector<string>& files){//文件句柄  long   hFile = 0;//文件信息  struct _finddata_t fileinfo;string p;if ((hFile = _findfirst(p.assign(path).append("\\*.jpg").c_str(), &fileinfo)) != -1){do{//如果是目录,迭代之  //如果不是,加入列表  if ((fileinfo.attrib &  _A_SUBDIR)){if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)getFiles(p.assign(path).append("\\").append(fileinfo.name), files);}else{files.push_back(p.assign(fileinfo.name));}} while (_findnext(hFile, &fileinfo) == 0);_findclose(hFile);}}


0 0
原创粉丝点击