本来是想把这个放在第三章里面的,后来想想这个还是很有用,还是单独开一个新章节吧。
在进行图片序列处理是,我们常常需要读取文件下的每一个图片,然后再进行分析处理,因此需要对文件名连续及无规则分开讨论。对于文件名连续的情况,文件读取就简单得多,可以利用sprintf函数实现在窗口连续读取同一文件夹下的图片序列,而对于无规则的情况则可以采用基于VC下WIN32_FIND_DATA文件的读取方式。
e.g:<1>文件名连续的情况下
#include<iostream>
#include<stdio.h>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
//定义相关参数
const int num = 100;
char fileName[50];
char windowName[50];
cv::Mat srcImage;
for(int i = 1; i <= num ; i++)
{
//sprintf读入指定路径下的图片序列
sprintf( fileName, "D:\\test\\1(%d).jpg" , i );
sprintf( windowName, "NO%d" , i );
// 按照图像文件名读取
srcImage = cv::imread(fileName);
if(!srcImage.data)
{
std::cout<<"No data!"<<std::endl;
return -1;
}
cv::nameWindow(windowName);
cv::imshow(WindowName,srcImage);
std::cout<<"NO"<<i<<std::endl;
}
cv::waitKey(0);
return 0;
}
PS:在这种文件名连续的时候可以选中文件夹所有的图像文件,然后用鼠标右键选定并重命名,键入1后,文件夹的所有文件自动命名为1(k)
<2>文件名无规则情况读取
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <windows.h>
using namespace std;
using namespace cv;
void readImgNamefromFile(char* filename, vector<string>&imgNames)
{
imgNames.clear();
WIN32_FIND_DATA file;
int i = 0;
char tempFilePath[MAX_PATH + 1];
char tempFileName[6];
sprintf(tempFilePath, "%s/*", filename);
HANDLE handle = FindFirstFile(tempFilePath);
if (handle != INVALID_HANDLE_VALUE)
{
FindNextFile(handle, &file);
do
{
sprintf(tempFileName, "%s", filename);
imgNames.push_back(file.cFileName);
imgNames[i].insert(0, tempFileName);
i++;
}
while (FindNextFile(handle,&file));
}
FindClose(handle);
}
int main()
{
char* filename = "C:\Users\Administrator\Desktop\test\ConsoleApplication1\ConsoleApplication1";
std::vector<string> imgNames;
readImgNamefromFile(filename,imgNames);
for (int i = 0;i<imgNames.size();i++)
{
cv::Mat img = imread(imgNames(i));
if (!img.data)
{
return -1;
}
imshow("im", img);
waitKey(0);
}
return 0;
}