源码:

#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. VMware Workstation Pro14安装

    1. 下载VMware Workstation Pro14,注意,这个链接支持win7 64及以上系统 2.  点击进入安装 3. 接受许可协议 4. 选择安装目录,是否选择增强型键盘驱动程序 5. ...

  2. SaaS教父:我眼中最糟糕的9条SaaS建议(转)

    文章摘要:美国SaaS行业的教父级人物Jason Lemkin近日总结了在他眼里最糟糕的9条SaaS方面的建议,希望对SaaS行业的创业者有所启发. SaaS行业的创业者平时肯定会收到外界各种各样的建 ...

  3. linux检查系统CPU,内存,磁盘使用率

    #!/bin/bash CPU=`top -bn 1 -i -c | sed -n '3p' | awk -F ':' '{print$2}' | awk '{print$1}'` MEM=`free ...

  4. 基于opencv和QT的摄像头采集代码( GoQTtemplate3持续更新)

    在Linux操作系统上,编写带界面的图像处理程序,选择opencv+QT是一种很好的选择.GoQTtemplate3是我为编写Linux下图像处理程序实现的框架,希望能够为大家解决Linux环境下桌面 ...

  5. Codeforces 888G Xor-MST - 分治 - 贪心 - Trie

    题目传送门 这是一条通往vjudge的高速公路 这是一条通往Codeforces的高速公路 题目大意 给定一个$n$阶完全图,每个点有一个权值$a_{i}$,边$(i, j)$的权值是$(a_{i}\ ...

  6. Django模版语言的复用 1. include标签--模版导入 2.inclusion_tag自定义标签--模版导入 3.母版

    include标签--模版导入 ''' 前提:项目中,往往会出现多个页面拥有一个或几个相同的页面版块,或是一个页面多个页面版块是相同的 如何运用:可以将多个样式标签的集合进行封装,对外提供版块的名字( ...

  7. CSS的进一步深入(更新中···)

    在之前我们学了6种选择器和三种CSS样式的引入,学习选择器就是为了更好的选择文本,学习CSS的引入是为了使文本增加各种样式和属性, 下面我们简单来学习一下为文本加样式和一些属性和属性值: 1.文本的样 ...

  8. Java8 函数式接口-Functional Interface

    目录 函数式接口: JDK 8之前已有的函数式接口: 新定义的函数式接口: 函数式接口中可以额外定义多个Object的public方法一样抽象方法: 声明异常: 静态方法: 默认方法 泛型及继承关系 ...

  9. SpringBoot 读取properties配置文件 @Value使用 中文乱码问题

    一,idea中配置文件中文乱码问题 使用idea开发,读取properites配置文件 配置: #app 菜单 #没有限制,所有人都可访问的菜单 menu.unlimited=订单审批,现场尽调,合作 ...

  10. Sql 获取当前日期没有时分秒

    select convert(varchar(10),getdate(),120) 输出格式:2008-02-27 00:25:13 SELECT CONVERT(char(19), getdate( ...