XML-->视频-->人脸VOC

http://www.2cto.com/kf/201702/602665.html

1)先把视频保存成图片
(2)再获取每张中人脸的坐标信息,保存到output.txt中
(3)利用output.txt生成XML文件

第一步:从视频中获得包括人脸的图像

/*
获取视频的每一帧,
    如果检测到人脸,就把这一帧图像保存到本地
    如果没检测到人脸,就不保存
*/

#include
#include 
#include 
#include 
using namespace cv;//必须加入,否则无法检找到OPENCV的各个函数  
using namespace std;


int img_num = 1;
char img_name[60] = { 0 };
string face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "人脸识别";
void detectAndDisplay(Mat frame){
    std::vector faces;
    //Mat frame_gray;

    //cvtColor(frame, frame_gray, CV_BGR2GRAY);
    //equalizeHist(frame_gray, frame_gray);

    face_cascade.detectMultiScale(frame, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
//如果检测到人脸,就保存起来图片
    sprintf(img_name, "%d.jpg", img_num);
    img_num++;
    if (faces.size() >= 0)
    {
        imwrite(img_name, frame);
    }

    for (int i = 0; i < faces.size(); i++)
    {
        rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);
    }

    imshow(window_name, frame);
}

int main(int argc, int* argv[])
{
    VideoCapture cap("1.avi"); // open the default camera  
    if (!cap.isOpened())  // check if we succeeded  
        return -1;
    if (!face_cascade.load(face_cascade_name)){
        printf("[error] 无法加载级联分类器文件!\n");
        return -1;
    }
    int nTick = 0;
    for (;;)
    {
        if (!cap.isOpened())
        {//等等摄像头打开  
            continue;
        }
        Mat frame;
        nTick = getTickCount();
        cap >> frame; // get a new frame from camera  
        if (frame.data == NULL)
        {//等到捕获到数据  
            continue;
        }

        detectAndDisplay(frame);

        if (waitKey(24) >= 0) break;
    }
    return 0;
}

=====================================

第二步:获得output.txt文件

/*

依次读取本地中的图片,进行检测:
    如果检测到人脸,就保存到output.txt文件中
    如果检测不到人脸,就保存到no_face.txt文件中

*/

#include
#include 
#include 
#include 

using namespace std;
using namespace cv;


void detectAndDisplay(Mat frame);


String face_cascade_name = "haarcascade_frontalface_alt.xml";

CascadeClassifier face_cascade;   //定义人脸分类器

ofstream   file_write("output.txt", ios::app);  //output.txt文件
ofstream   file_no_face("no_face.txt", ios::app);  //output.txt文件
char buf[60] = { 0 };  //buf图片名称
char buf_path[60] = { 0 };
int i_img = 1; //遍历第i_img张图片

int main(void)
{

    int count_img = 100000; //输入图片的总数量
    //
    for (; i_img <= count_img; i_img++)
    {
        sprintf(buf, "%d.jpg", i_img);//格式化输出sprintf函数
        //sprintf(buf_path, "绝对路径\\%d.jpg", i_img);
        sprintf(buf_path, "G:\\img\\%d.jpg", i_img);
        Mat frame = imread(buf_path);
        if (frame.data == NULL)
        {
            printf("处理完成 | 第%d张图片加载失败\n", i_img);
            break;
        }

        if (!face_cascade.load(face_cascade_name))
        {
            printf("加载XML文件失败\n");
            return -1;
        };
        detectAndDisplay(frame);
    }
    waitKey(0);
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector faces;
    //检测人脸
    face_cascade.detectMultiScale(frame, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(100, 100));
    char no_face_buf[60] = { 0 };
    sprintf(no_face_buf, "%d.jpg\n", i_img);//格式化输出sprintf函数

    if (faces.size() <= 0)
    {
        file_no_face << no_face_buf;
    }


    for (size_t j = 0; j < faces.size(); j++)
    {
        rectangle(frame, faces[j], Scalar(255, 0, 0), 2, 8, 0);
        Mat faceROI = frame(faces[j]);
        //写入本地
        char name[60] = { 0 };
        sprintf(name, "img%d_face_%d.jpg", i_img, j);
        //imwrite(name, faceROI);
        char output[100] = { 0 };
        sprintf(output, "%s person %d %d %d %d\n", buf, faces[j].tl().x, faces[j].tl().y, faces[j].br().x, faces[j].br().y);
        //             图片名字  类别  矩形的两个顶点坐标
        printf("%s", output);
        file_write << output;
    }
    imshow("正在处理", frame);
    waitKey(300);
}

第三步:产生XML文件

将第2步得到的txt转成xml。格式如下:(注意folder字段)
<annotation>
    <folder>logosfolder>       
    <filename>000001.jpgfilename>
    <source>
        <database>The logs Databasedatabase>
        <annotation>The logs Databaseannotation>
        <image>flickrimage>
        <flickrid>0flickrid>
    source>
    <owner>
        <flickrid>I do not knowflickrid>
        <name>I do not knowname>
    owner>
    <size>
        <width>293width>
        <height>220height>
        <depth>3depth>
    size>
    <segmented>0segmented>
    <object>
        <name>光头name>
        <pose>Unspecifiedpose>
        <truncated>0truncated>
        <difficult>0difficult>
        <bndbox>
            <xmin>157xmin>
            <ymin>24ymin>
            <xmax>241xmax>
            <ymax>99ymax>
        bndbox>
    object>
annotation>

【matlab代码】
下载工具链接:http://pan.baidu.com/s/1nuRMOsD 密码:2z4g

%%
%该代码可以做voc2007数据集中的xml文件,
%txt文件每行格式为:000002.jpg dog 44 28 132 121
%即每行由图片名、目标类型、包围框坐标组成,空格隔开
%如果一张图片有多个目标,则格式如下:(比如两个目标)
%000002.jpg dog 44 28 132 121
%000002.jpg car 50 27 140 110
%包围框坐标为左上角和右下角
%作者:小咸鱼_
%CSDN:http://blog.csdn.net/sinat_30071459
%%
clc;
clear;
%注意修改下面四个变量
imgpath='F:\face\';%图像存放文件夹
txtpath='F:\face\output.txt';%txt文件
xmlpath_new='F:\Annotations\';%修改后的xml保存文件夹
foldername='VOC2007';%xml的folder字段名


fidin=fopen(txtpath,'r');
lastname='begin';

while ~feof(fidin)
     tline=fgetl(fidin);
     str = regexp(tline, ' ','split');
     filepath=[imgpath,str{1}];
     img=imread(filepath);
     [h,w,d]=size(img);
      imshow(img);
      rectangle('Position',[str2double(str{3}),str2double(str{4}),str2double(str{5})-str2double(str{3}),str2double(str{6})-str2double(str{4})],'LineWidth',4,'EdgeColor','r');
      pause(0.1);

        if strcmp(str{1},lastname)%如果文件名相等,只需增加object
           object_node=Createnode.createElement('object');
           Root.appendChild(object_node);
           node=Createnode.createElement('name');
           node.appendChild(Createnode.createTextNode(sprintf('%s',str{2})));
           object_node.appendChild(node);

           node=Createnode.createElement('pose');
           node.appendChild(Createnode.createTextNode(sprintf('%s','Unspecified')));
           object_node.appendChild(node);

           node=Createnode.createElement('truncated');
           node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
           object_node.appendChild(node);

           node=Createnode.createElement('difficult');
           node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
           object_node.appendChild(node);

           bndbox_node=Createnode.createElement('bndbox');
           object_node.appendChild(bndbox_node);

           node=Createnode.createElement('xmin');
           node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{3}))));
           bndbox_node.appendChild(node);

           node=Createnode.createElement('ymin');
           node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{4}))));
           bndbox_node.appendChild(node);

           node=Createnode.createElement('xmax');
           node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{5}))));
           bndbox_node.appendChild(node);

           node=Createnode.createElement('ymax');
           node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{6}))));
           bndbox_node.appendChild(node);
        else %如果文件名不等,则需要新建xml
           copyfile(filepath, 'JPEGImages');
            %先保存上一次的xml
           if exist('Createnode','var')
              tempname=lastname;
              tempname=strrep(tempname,'.jpg','.xml');
              xmlwrite(tempname,Createnode);   
           end


            Createnode=com.mathworks.xml.XMLUtils.createDocument('annotation');
            Root=Createnode.getDocumentElement;%根节点
            node=Createnode.createElement('folder');
            node.appendChild(Createnode.createTextNode(sprintf('%s',foldername)));
            Root.appendChild(node);
            node=Createnode.createElement('filename');
            node.appendChild(Createnode.createTextNode(sprintf('%s',str{1})));
            Root.appendChild(node);
            source_node=Createnode.createElement('source');
            Root.appendChild(source_node);
            node=Createnode.createElement('database');
            node.appendChild(Createnode.createTextNode(sprintf('My Database')));
            source_node.appendChild(node);
            node=Createnode.createElement('annotation');
            node.appendChild(Createnode.createTextNode(sprintf('VOC2007')));
            source_node.appendChild(node);

           node=Createnode.createElement('image');
           node.appendChild(Createnode.createTextNode(sprintf('flickr')));
           source_node.appendChild(node);

           node=Createnode.createElement('flickrid');
           node.appendChild(Createnode.createTextNode(sprintf('NULL')));
           source_node.appendChild(node);
           owner_node=Createnode.createElement('owner');
           Root.appendChild(owner_node);
           node=Createnode.createElement('flickrid');
           node.appendChild(Createnode.createTextNode(sprintf('NULL')));
           owner_node.appendChild(node);

           node=Createnode.createElement('name');
           node.appendChild(Createnode.createTextNode(sprintf('xiaoxianyu')));
           owner_node.appendChild(node);
           size_node=Createnode.createElement('size');
           Root.appendChild(size_node);

          node=Createnode.createElement('width');
          node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(w))));
          size_node.appendChild(node);

          node=Createnode.createElement('height');
          node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(h))));
          size_node.appendChild(node);

         node=Createnode.createElement('depth');
         node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(d))));
         size_node.appendChild(node);

          node=Createnode.createElement('segmented');
          node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
          Root.appendChild(node);
          object_node=Createnode.createElement('object');
          Root.appendChild(object_node);
          node=Createnode.createElement('name');
          node.appendChild(Createnode.createTextNode(sprintf('%s',str{2})));
          object_node.appendChild(node);

          node=Createnode.createElement('pose');
          node.appendChild(Createnode.createTextNode(sprintf('%s','Unspecified')));
          object_node.appendChild(node);

          node=Createnode.createElement('truncated');
          node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
          object_node.appendChild(node);

          node=Createnode.createElement('difficult');
          node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
          object_node.appendChild(node);

          bndbox_node=Createnode.createElement('bndbox');
          object_node.appendChild(bndbox_node);

         node=Createnode.createElement('xmin');
         node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{3}))));
         bndbox_node.appendChild(node);

         node=Createnode.createElement('ymin');
         node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{4}))));
         bndbox_node.appendChild(node);

        node=Createnode.createElement('xmax');
        node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{5}))));
        bndbox_node.appendChild(node);

        node=Createnode.createElement('ymax');
        node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{6}))));
        bndbox_node.appendChild(node);

       lastname=str{1};
        end
        %处理最后一行
        if feof(fidin)
            tempname=lastname;
            tempname=strrep(tempname,'.jpg','.xml');
            xmlwrite(tempname,Createnode);
        end
end
fclose(fidin);

file=dir(pwd);
for i=1:length(file)
   if length(file(i).name)>=4 && strcmp(file(i).name(end-3:end),'.xml')
    fold=fopen(file(i).name,'r');
    fnew=fopen([xmlpath_new file(i).name],'w');
    line=1;
    while ~feof(fold)
        tline=fgetl(fold);
        if line==1
           line=2;
           continue;
        end
        expression = '   ';
        replace=char(9);
        newStr=regexprep(tline,expression,replace);
        fprintf(fnew,'%s\n',newStr);
    end
    fprintf('已处理%s\n',file(i).name);
    fclose(fold);
    fclose(fnew);
    delete(file(i).name);
   end
end

【python代码】

/*
    把上一步得到的txt文档转换为XML文件,python代码如下,我的需要训练识别的物体只有一个,如果要识别多个目标,那需要略微修改一下如下代码。
*/

#encoding=utf-8

import sys
import os
import codecs
import cv2

root = r'F:\dataset\xml'
fp = open('F:\dataset\pos-all.txt')
fp2 = open('train.txt', 'w')
uavinfo = fp.readlines()

for i in range(len(uavinfo)):
    line = uavinfo[i]
    line = line.strip().split('\t')   
    img = cv2.imread(line[0])
    sp = img.shape
    height = sp[0]
    width = sp[1]
    depth = sp[2]
    info1 = line[0].split('\\')[-1]
    info2 = info1.split('.')[0]

    l_pos1 = line[1]
    l_pos2 = line[2]
    r_pos1 = line[3]
    r_pos2 = line[4]
    fp2.writelines(info2 + '\n')
    with codecs.open(root +r'\\'+ info2 + '.xml', 'w', 'utf-8') as xml:
        xml.write('\n')
        xml.write('\t' + 'UAV_data' + '\n')
        xml.write('\t' + info1 + '\n')
        xml.write('\t\n')
        xml.write('\t\tThe UAV autolanding\n')
        xml.write('\t\tUAV AutoLanding\n')
        xml.write('\t\t加载中...flickr\n')
        xml.write('\t\tNULL\n')
        xml.write('\t\n')
        xml.write('\t\n')
        xml.write('\t\tNULL\n')
        xml.write('\t\tXuSenhai\n')
        xml.write('\t\n')
        xml.write('\t\n')
        xml.write('\t\t'+ str(width) + '\n')
        xml.write('\t\t'+ str(height) + '\n')
        xml.write('\t\t' + str(depth) + '\n')
        xml.write('\t\n')
        xml.write('\t\t0\n')
        xml.write('\t\n')
        xml.write('\t\tuav\n')
        xml.write('\t\tUnspecified\n')
        xml.write('\t\t0\n')
        xml.write('\t\t0\n')
        xml.write('\t\t\n')
        xml.write('\t\t\t' + l_pos1 + '\n')
        xml.write('\t\t\t' + l_pos2 + '\n')
        xml.write('\t\t\t' + r_pos1 + '\n')
        xml.write('\t\t\t' + r_pos2 + '\n')
        xml.write('\t\t\n')
        xml.write('\t\n')
        xml.write('')
fp2.close()

第四步:数据集分割–matlab代码

/*
    在实际训练过程中,需要四个文件,分别为test.txt是测试集,train.txt是训练集,val.txt是验证集,trainval.txt是训练和验证集。每个文件为对于图片的名字。在VOC2007中,trainval大概是整个数据集的50%,test也大概是整个数据集的50%;train大概是trainval的50%,val大概是trainval的50%。可参考以下代码:
*/

%%  
%该代码根据已生成的xml,制作VOC2007数据集中的trainval.txt;train.txt;test.txt和val.txt  
%trainval占总数据集的50%,test占总数据集的50%;train占trainval的50%,val占trainval的50%;  
%上面所占百分比可根据自己的数据集修改,如果数据集比较少,test和val可少一些  
%%  
%注意修改下面四个值  
xmlfilepath='E:\Annotations';  
txtsavepath='E:\ImageSets\Main\';  
trainval_percent=0.5;%trainval占整个数据集的百分比,剩下部分就是test所占百分比  
train_percent=0.5;%train占trainval的百分比,剩下部分就是val所占百分比  


%%  
xmlfile=dir(xmlfilepath);  
numOfxml=length(xmlfile)-2;%减去.和..  总的数据集大小  


trainval=sort(randperm(numOfxml,floor(numOfxml*trainval_percent)));  
test=sort(setdiff(1:numOfxml,trainval));  


trainvalsize=length(trainval);%trainval的大小  
train=sort(trainval(randperm(trainvalsize,floor(trainvalsize*train_percent))));  
val=sort(setdiff(trainval,train));  


ftrainval=fopen([txtsavepath 'trainval.txt'],'w');  
ftest=fopen([txtsavepath 'test.txt'],'w');  
ftrain=fopen([txtsavepath 'train.txt'],'w');  
fval=fopen([txtsavepath 'val.txt'],'w');  


for i=1:numOfxml  
    if ismember(i,trainval)  
        fprintf(ftrainval,'%s\n',xmlfile(i+2).name(1:end-4));  
        if ismember(i,train)  
            fprintf(ftrain,'%s\n',xmlfile(i+2).name(1:end-4));  
        else  
            fprintf(fval,'%s\n',xmlfile(i+2).name(1:end-4));  
        end  
    else  
        fprintf(ftest,'%s\n',xmlfile(i+2).name(1:end-4));  
    end  
end  
fclose(ftrainval);  
fclose(ftrain);  
fclose(fval);  
fclose(ftest);  

第五步:将得到的文件放置正确路径

1. 将训练图片放置于 
faster-rcnn/data/VOCdevkit2007/VOC2007/JPEGImages 中
2. 将得到的xml文件放置于 
faster-rcnn/data/VOCdevkit2007/VOC2007/Annotations 中
3. 将得到的test.txt,train.txt,val.txt,trainval.txt 放置于 
faster-rcnn/data/VOCdevkit2007/VOC2007/Annotations/ImageSets/Main

你可能感兴趣的:(VS2010+OpenCV)