源码:

#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>
#include <direct.h>
#include <io.h> #include "tinyxml.h"
//#include "TransformEngine.h"
//#include "TransformEngine.cpp
using namespace std;
using namespace cv; int CropImageCount=;//裁剪出来的人体图片个数 /**
* 通过根节点和节点名查找所有指定节点,结果放到节点数组NodeVector中
* @param pRootEle xml文件的根节点
* @param strNodeName 要查询的节点名
* @param NodeVector 查询到的节点指针数组
* @return 找到至少一个相应节点,返回true;否则false
*/
bool GetAllNodePointerByName(TiXmlElement* pRootEle, string strNodeName, vector<TiXmlElement*> &NodeVector)
{
//如果NodeName等于根节点名,加入NodeVector数组
if(strNodeName == pRootEle->Value())
{
NodeVector.push_back(pRootEle);//添加到数组末尾
//这里根据VOC Annotation的XML文件格式,认为相同节点名的节点不会有父子关系,所以所有相同节点名的节点都在同一级别上
//只要找到第一个,剩下的肯定在它的兄弟节点里面
for(TiXmlElement * pElement = pRootEle->NextSiblingElement(); pElement; pElement = pElement->NextSiblingElement())
if(strNodeName == pElement->Value())
NodeVector.push_back(pElement);
return true;
}
TiXmlElement * pEle = pRootEle;
for(pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())
{
//递归处理子节点,获取节点指针
if(GetAllNodePointerByName(pEle,strNodeName,NodeVector))
return true;
}
return false;//没找到
} /**
* 根据目标名过滤目标节点数组,删除所有目标名不是objectName的元素
* @param NodeVector 要操作的TiXmlElement元素指针数组
* @param objectName 指定的目标名,删除所有目标名不是objectName的元素
* @return 过滤后目标数组为空,返回false;否则返回true
*/
bool FiltObject(vector<TiXmlElement*> &NodeVector, string objectName)
{
TiXmlElement * pEle = NULL;
vector<TiXmlElement *>::iterator iter = NodeVector.begin();//数组的迭代器
for(; iter != NodeVector.end();)
{
pEle = * iter;//第i个元素
//若目标名不是objectName,删除此节点
if( objectName != pEle->FirstChildElement()->GetText() )
{
//cout<<"删除的目标节点:"<<pEle->FirstChildElement()->GetText() <<endl;
iter = NodeVector.erase(iter);//删除目标名不是objectName的,返回下一个元素的指针
}
else
iter++;
}
if( == NodeVector.size())//过滤后目标数组为空,说明不包含指定目标
return false;
else
return true;
} bool createDirectory(const std::string folder) {
std::string folder_builder;
std::string sub;
sub.reserve(folder.size());
for (auto it = folder.begin(); it != folder.end(); ++it)
{
//cout << *(folder.end()-1) << endl;
const char c = *it;
sub.push_back(c);
if (c == '\\' || it == folder.end() - )
{
folder_builder.append(sub);
if ( != ::_access(folder_builder.c_str(), ))
{
// this folder not exist
if ( != ::_mkdir(folder_builder.c_str()))
{
// create failed
return false;
}
}
sub.clear();
}
}
return true;
} /**
* 根据每个目标的BoundingBox,剪裁图像,保存为文件
* @param img 图像
* @param NodeVector 目标节点数组
* @param objectName 目标名
*/
void CropImage(Mat img, vector<TiXmlElement*> NodeVector, string objectName)
{
int xmin,ymin,xmax,ymax;//从目标节点中读出的包围盒参数
char fileName[];//剪裁后的图片和其水平翻转图片的文件名 createDirectory(objectName);
//遍历目标数组
vector<TiXmlElement *>::iterator iter = NodeVector.begin();//数组的迭代器
for(; iter != NodeVector.end(); iter++)
{
//遍历每个目标的子节点
TiXmlElement *pEle = (*iter)->FirstChildElement();//第i个元素的第一个孩子
for(; pEle; pEle = pEle->NextSiblingElement())
{
//找到包围盒"bndbox"节点
if(string("bndbox") == pEle->Value())
{
TiXmlElement * pCoord= pEle->FirstChildElement();//包围盒的第一个坐标值
//依次遍历包围盒的4个坐标值,放入整型变量中
for(; pCoord; pCoord = pCoord->NextSiblingElement())
{
if(string("xmin") == pCoord->Value())
xmin = atoi(pCoord->GetText());//xmin
if(string("ymin") == pCoord->Value())
ymin = atoi(pCoord->GetText());//ymin
if(string("xmax") == pCoord->Value())
xmax = atoi(pCoord->GetText());//xmax
if(string("ymax") == pCoord->Value())
ymax = atoi(pCoord->GetText());//ymax
}
//cout<<"xmin:"<<xmin<<","<<"ymin:"<<ymin<<","<<"xmax:"<<xmax<<","<<"ymax:"<<ymax<<endl;;
//根据读取的包围盒坐标设置图像ROI
Mat imgROI = img(Rect(xmin,ymin,xmax-xmin,ymax-ymin));
//resize(imgROI,imgROI,Size(64,128));//缩放为64*128大小
objectName = objectName+"/"+ objectName+ "%06d.jpg"; sprintf(fileName, objectName.c_str(),++CropImageCount);//生成剪裁图片的文件名
imwrite(fileName,imgROI);//保存文件 //flip(imgROI,imgROI,1);//水平翻转
//memset(fileName,0x00,sizeof(fileName));
//sprintf(fileName,"person%06d.jpg",++CropImageCount);//生成剪裁图片的水平翻转图片的文件名
//imwrite(fileName,imgROI);//保存文件
}
}
}
} /**
* 根据XML文件,从图像中剪裁出objectName目标
* @param XMLFile XML文件名
* @param img 对应的图像
* @param objectName 目标名
* @return 若图像中包含objectName目标,返回true;否则返回false
*/
bool CropImageAccordingToXML(string XMLFile, Mat img, string objectName)
{
TiXmlDocument * pDoc = new TiXmlDocument();//创建XML文档
pDoc->LoadFile(XMLFile.c_str());//装载XML文件
vector<TiXmlElement*> nodeVector;//节点数组 //查找所有节点名是object的节点,即目标节点,结果放到节点数组nodeVector中
if( false == GetAllNodePointerByName(pDoc->RootElement(), "object", nodeVector) )//未找到指定目标
return false;
cout<<"所有目标个数:"<<nodeVector.size()<<endl; //过滤节点数组,删除所有节点名不是objectName的节点
if( false == FiltObject(nodeVector,objectName) )//目标数组中没有指定目标
return false;
//cout<<"过滤后的目标个数:"<<nodeVector.size()<<endl; //根据每个目标的BoundingBox,剪裁图像,保存为文件
CropImage(img,nodeVector, objectName);
} int main()
{
int fileCount=;//文件个数
Mat src;
string XMLName,ImgName;//XML文件名和对应的图片文件名
//ifstream fin("VOC2012AnnotationsXMLList.txt");//打开XML文件列表
//ifstream fin("subset.txt");
ifstream fin("test.txt"); //读取XML文件列表
while(getline(fin,XMLName))
{
cout<<"处理:"<<XMLName<<endl;
ImgName = "D:\\temp\\CropObjectFromVOC\\" + XMLName + ".jpg";
XMLName = "D:\\temp\\CropObjectFromVOC\\" + XMLName + ".xml";
src = imread(ImgName);
CropImageAccordingToXML(XMLName,src,"person");//根据XML标注文档,从图像src中剪裁出所有person目标,保存为文件
CropImageAccordingToXML(XMLName, src, "chair");
CropImageAccordingToXML(XMLName, src, "tvmonitor");
CropImageAccordingToXML(XMLName, src, "bottle");
} system("pause");
}

test.txt:

2007_000346
2009_000010

2009_000010.xml:

<annotation>
<filename>2009_000010.jpg</filename>
<folder>VOC2012</folder>
<object>
<name>tvmonitor</name>
<bndbox>
<xmax>124</xmax>
<xmin>36</xmin>
<ymax>241</ymax>
<ymin>153</ymin>
</bndbox>
<difficult>0</difficult>
<occluded>1</occluded>
<pose>Frontal</pose>
<truncated>0</truncated>
</object>
<object>
<name>chair</name>
<bndbox>
<xmax>164</xmax>
<xmin>72</xmin>
<ymax>286</ymax>
<ymin>205</ymin>
</bndbox>
<difficult>0</difficult>
<occluded>1</occluded>
<pose>Unspecified</pose>
<truncated>1</truncated>
</object>
<object>
<name>person</name>
<bndbox>
<xmax>346</xmax>
<xmin>157</xmin>
<ymax>267</ymax>
<ymin>57</ymin>
</bndbox>
<difficult>0</difficult>
<occluded>1</occluded>
<pose>Frontal</pose>
<truncated>1</truncated>
</object>
<segmented>0</segmented>
<size>
<depth>3</depth>
<height>375</height>
<width>500</width>
</size>
<source>
<annotation>PASCAL VOC2009</annotation>
<database>The VOC2009 Database</database>
<image>flickr</image>
</source>
</annotation>

2007_000346.xml:

<annotation>
<folder>VOC2012</folder>
<filename>2007_000346.jpg</filename>
<source>
<database>The VOC2007 Database</database>
<annotation>PASCAL VOC2007</annotation>
<image>flickr</image>
</source>
<size>
<width>500</width>
<height>375</height>
<depth>3</depth>
</size>
<segmented>1</segmented>
<object>
<name>bottle</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>124</xmin>
<ymin>107</ymin>
<xmax>230</xmax>
<ymax>343</ymax>
</bndbox>
</object>
<object>
<name>person</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>137</xmin>
<ymin>78</ymin>
<xmax>497</xmax>
<ymax>375</ymax>
</bndbox>
</object>
<object>
<name>person</name>
<pose>Unspecified</pose>
<truncated>1</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>89</xmin>
<ymin>202</ymin>
<xmax>129</xmax>
<ymax>247</ymax>
</bndbox>
</object>
<object>
<name>person</name>
<pose>Frontal</pose>
<truncated>1</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>72</xmin>
<ymin>209</ymin>
<xmax>111</xmax>
<ymax>259</ymax>
</bndbox>
</object>
</annotation>

2007_000346.jpg:

2009_000010.jpg:

免责声明:资源与源码皆来自网络的测试数据,如有侵权请联系本人删除

[原][源码][tinyxml][opencv]按照规格剪切所有的图片的更多相关文章

  1. win10 vs2015源码编译opencv、opencv_contrib、Tesseract

    1.软件包准备 opencv源码包地址:                官网  github opencv_contrib源码包地址:   github Tesseract源码包地址:        ...

  2. 从源码安装opencv

    操作系统为Debian9,由于使用apt-get安装在/usr/lib目录下的opencv可能会造成一些项目上的头文件错误问题,所以选择了从源码安装. 选择opencv3.4.1, 进入https:/ ...

  3. windows 10 上源码编译OpenCV并支持CUDA | compile opencv with CUDA support on windows 10

    本文首发于个人博客https://kezunlin.me/post/6580691f/,欢迎阅读! compile opencv with CUDA support on windows 10 Ser ...

  4. ubuntu 16.04源码编译OpenCV教程 | compile opencv on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/15f5c3e8/,欢迎阅读! compile opencv on ubuntu 16.04 Series Part 1: comp ...

  5. iOS源码之OC相册,可以循环查看图片

    #import "ViewController.h" #import "YZUIScrollView.h" #define kuan ([UIScreen ma ...

  6. OpenCV学习:OpenCV源码编译(vc9)

    安装后的OpenCV程序下的build文件夹中,只找到了vc10.vc11和vc12三种编译版本的dll和lib文件,需要VS2010及以上的IDE版本,而没有我们常用的VS2008版本. 于是,需要 ...

  7. OpenCV源码解析

    OpenCV K-means源码解析 OpenCV 图片读取源码解析 OpenCV 视频播放源码解析 OpenCV 追踪算法源码解析 OpenCV SIFT算法源码解析 OpenCV 滤波源码分析:b ...

  8. 树莓派学习笔记—— 源码方式安装opencv

    0.前言     本文介绍怎样在树莓派中通过编译源码的方式安装opencv,并通过一个简单的样例说明怎样使用opencv.     很多其它内容请參考--[树莓派学习笔记--索引博文] 1.下载若干依 ...

  9. Ubuntu16.04 + OpenCV源码 + Qt5.10 安装、配置

    在VMWare中配置安装Ubuntu16.04.没有什么特别的地方,正常安装即可. 安装最新版qt,此时5.10.按照普通QT教程安装(需要勾选gcc),无须sudo,此时不用管OpenCV.地址:h ...

随机推荐

  1. echarts报错Can't get dom width or height

    echarts图无法显示 一直报错Can't get dom width or height 原因:显示echarts图的div要设置宽高 报错前: <div class="left_ ...

  2. Ubuntu16.04+cuda8.0rc+opencv3.1.0+caffe+Theano+torch7搭建教程

    https://blog.csdn.net/jywowaa/article/details/52263711 学习中用到深度学习的框架,需要搭建caffe.theano和torch框架.经过一个月的不 ...

  3. to refactor for refactor

    v1.1 if all algorithm are in one function, it will expand. so each operate type should be separated. ...

  4. Python 内置函数sorted()在高级用法

    对于Python内置函数sorted(),先拿来跟list(列表)中的成员函数list.sort()进行下对比.在本质上,list的排序和内建函数sorted的排序是差不多的,连参数都基本上是一样的. ...

  5. linux 安装sqlite3

    python2个版本导致的问题. 网上找了好多方法都不行. 最后自己莫名其妙弄好了, 回想了一下大概是 安装sqlite3 重新安装python 最后 yum update 更新 就好了.

  6. Selenium+Headless Firefox

    背景 今天本地调试基于Selenium+PhantomJS的动态爬虫程序顺利结束后,着手部署到服务器上,刚买的热乎的京东云,噼里啪啦一顿安装环境,最后跑的时候报了这么个错误: UserWarning: ...

  7. elasticsearch配置文件详解

    来自:http://www.searchtech.pro/articles/2013/02/18/1361194291548.html elasticsearch的config文件夹里面有两个配置文 ...

  8. encodeURI、encodeURIComponent

    encodeURI是对整个uri进行编码的,而encodeURIComponent是对uri中部分内容进行编码. 在进行url的字符串拼接时,需要进行两次encodeURI. 只进行一次encodeU ...

  9. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录

    1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html   v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客 ...

  10. 02: djangorestframework使用

    1.1 djangorestframework登录.认证和权限 1.认证与权限相关模块 # -*- coding: utf-8 -*- from django.utils import six fro ...