项目实训(十五)---视频多人物自适应人脸识别(版本更新)

2021SC@SDUSC

目录

一.人脸识别---多人物目标

1. 多人物目标

版本1  判断单双人模式

版本2 自适应人物数量---视频人脸识别

最终标志生成整理

2.人物上传

3.视频上传


根据要求变化人脸识别的代码经历前后三次大的更新:

版本记录如下:

一.人脸识别---多人物目标

1. 多人物目标

版本1  判断单双人模式

    #人脸特征128维
    head = []
    for i in range(128):
        fe = "feature_" + str(i + 1)
        head.append(fe)
    face_path = faceDB_path + "feature_all.csv"
    face_feature = pd.read_csv(face_path, names=head)
    # 特征向量
    face_feature_array = np.array(face_feature)

#目标对象

    # 待识别人物 这个序号和feature_all.csv的特征序号应该保持一致
    num = len(face_feature_array)
    people = []
    for i in range(num):
        people= people + [i]

视频帧提取


  r,frame = video.read()

检测人脸

 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            dets = detector(gray, 1)  # 检测帧图像中的人脸

计算人物所在帧位置

                   for j in range(people):
                       
                        if (compute_dst(v, face_feature_array[j]) < 0.56):
                          #对应人物计数
                            count = count + 1
                            dict[j] += [frame_count]

计算时间

     for i in dict:
            for j in range(len(dict[i])):
                dict[i][j] = dict[i][j] / frame_count * duration

保存

dict_json = json.dumps(dict)  # 转化为json格式文件
        # 将json文件保存为.json格式文件
        with open(result + 'time_relation.json', 'w+') as file:
            file.write(dict_json)

 

    #rueult是路径
    with open(result + name2+'_'+'gif_count.csv', 'a+')as f:
        f_csv = csv.writer(f)
        for i in dict:
            if len(dict[i]) > 0:
                l.append(1)
            else:
                l.append(0)
        f_csv.writerow(l)

版本2 自适应人物数量---视频人脸识别

自动判断人物

 统一处理入口

每个人物采用统一处理方式,不僵硬的区分单人双人,任意数量人物可以自由处理,相对于之前来言,更加自由方便。虽然前端约束单人或者双人,对后端这里进行了优化。

最终标志生成整理

try:
 
t = CalculateDistance('/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/ScenePhoto')

    df1 = pd.read_csv(
        '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv')

    df2 = pd.DataFrame({'scene': t})

    l = len(list(df1.keys()))

    if l == 4:

        pass

    else:

        if l == 3:

            df1.columns = ['videoPath', 'face1', 'face2']
            df2.columns = ['scene']
            dataframe = df1.join(df2)
            dataframe.to_csv(
                '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv',
                index=False, mode='w', sep=',')
        else:
            df1.columns = ['videoPath', 'face1']
            df2.columns = ['scene']
            a = len(df1['videoPath'])
            d = []
            for i in range(a):
                d.append(1)
            df3 = pd.DataFrame({'face2': d})
            dataframe = df1.join(df3)
            dataframe = dataframe.join(df2)
            dataframe.to_csv(
                '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv',
                index=False, mode='w', sep=',')

except:

    #场景照片补1
    df1 = pd.read_csv(
        '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv')

    l = len(list(df1.keys()))

    if l == 3:

        df1.columns = ['videoPath', 'face1', 'face2']
        a = len(df1['videoPath'])
        d = []
        for i in range(a):
            d.append(1)
        df3 = pd.DataFrame({'scene': d})
        dataframe = df1.join(df3)
        dataframe.to_csv(
            '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv',
            index=False, mode='w', sep=',')

    else:

        df1.columns = ['videoPath', 'face1']

        a = len(df1['videoPath'])
        d = []
        for i in range(a):
            d.append(1)
        df3 = pd.DataFrame({'face2': d})
        dataframe = df1.join(df3)


        d = []
        for i in range(a):
            d.append(1)
        df3 = pd.DataFrame({'scene': d})
        dataframe = dataframe .join(df3)

        dataframe.to_csv(
            '/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/' + id_video_name + "_" + 'gif_count.csv',
            index=False, mode='w', sep=',')


#文件读写成功
with open('/opt/data/private/xuyunyang/EasyCut/' + id + '/' + id_video_name + '/Resources/result/''success.txt','w') as f:
    f.write('success')

2.人物上传

package com.example.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.io.FilenameUtils;

import static com.example.demo.SSH.FileOperate.file_to_faces;

@RestController
@SpringBootApplication
public class SendPhotoController {
    // 存放文件的临时目录
    private static final String DATA_DIR = System.getProperty("user.dir") + "/temp/photo/";
    // 文件MD5的缓存容器
    private static final ConcurrentMap<String, File> MD5_CACHE = new ConcurrentHashMap<>();
    /**
     * 大文件分片上传
     * @param name 文件名
     * @param md5 文件MD5值
     * @param size 文件大小
     * @param chunks 总的分片数
     * @param chunk 当前分片数
     * @param multipartFile 分片流
     * @throws IOException
     */
    @PostMapping("/chunk/photo")
    public boolean chunkUpload(String id,String name,String videoName,
                            String md5,
                            Long size,
                            Integer chunks,
                            Integer chunk,
                            @RequestParam("file") MultipartFile multipartFile) throws IOException {

        System.out.println("进入");

        // 是否生成了文件?
        File targetFile = MD5_CACHE.get(md5);

        System.out.println(FilenameUtils.getName(md5));
        System.out.println(name);
        System.out.println("共几片"+chunks);
        System.out.println("第几片"+chunk);


        if (targetFile == null) {

            // 没有生成的话就生成一个新的文件,没有做并发控制,多线程上传会出问题
            targetFile = new File(DATA_DIR, id+"_"+name);
            targetFile.getParentFile().mkdirs();
            MD5_CACHE.put(md5, targetFile);

        }


        // 可以对文件的任意位置进行读写
        RandomAccessFile accessFile = new RandomAccessFile(targetFile, "rw");
        boolean finished = chunk == chunks;//是否最后一片
        if (finished) {
            // 移动指针到指定位置
            System.out.println("最后一片"+chunk);
            System.out.println("片大小:"+multipartFile.getSize());
            accessFile.seek((chunk - 1) * (512*1024));

        }else {
            System.out.println("第几片"+chunk);
            System.out.println("片大小:"+multipartFile.getSize());
            accessFile.seek((chunk - 1) * multipartFile.getSize());
        }

        // 写入分片的数据
        System.out.println(multipartFile.getBytes());
        accessFile.write(multipartFile.getBytes());

        accessFile.close();

        if (finished) {
            System.out.println("success.");
            // 上传成功
            MD5_CACHE.remove(md5);
            //判断是否是人脸 照片上传
            videoName=videoName.substring(0,videoName.indexOf("."));
            String name2=name.substring(0,name.indexOf("."));
            file_to_faces("F:/demo/temp/photo/" + id + "_" + name, id, id + "_" + videoName, id + "_" + name2);

            return true;

        }

        return true;

    }

}

3.视频上传


    @PostMapping("/chunk/upload")
    public boolean chunkUpload(String id, String name,
                               String md5,
                               Long size,
                               int chunks,
                               int chunk,
                               @RequestParam("file") MultipartFile multipartFile) throws IOException {

        System.out.println("进入");
        // 是否生成了文件?
        File targetFile = MD5_CACHE.get(md5);

        if (targetFile == null) {
    
            targetFile = new File(DATA_DIR, id + "_" + name);
            targetFile.getParentFile().mkdirs();
            MD5_CACHE.put(md5, targetFile);

        }

        RandomAccessFile accessFile = new RandomAccessFile(targetFile, "rw");
        System.out.println("共几片" + chunks);
        System.out.println("第几片" + chunk);
        boolean finished = (chunk==chunks);//是否最后一片
        System.out.print(finished);
        if (finished) {
            // 移动指针到指定位置
            System.out.println("最后一片" + chunk);
            System.out.println("片大小:" + multipartFile.getSize());
            accessFile.seek((chunk - 1) * (512 * 1024));

        } else {
      
            accessFile.seek((chunk - 1) * multipartFile.getSize());
        }

        System.out.println(multipartFile.getBytes());
        accessFile.write(multipartFile.getBytes());

        accessFile.close();

        if (finished) {
            System.out.println("success.");
            MD5_CACHE.remove(md5);

           //压缩
            try {

                String[] args1 = new String[]{"python", "G://demo//temp//compress.py", String.valueOf(name)};

                Process proc = Runtime.getRuntime().exec(args1);// 执行py文件

                BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));


                String line = null;

                while ((line = in.readLine()) != null) {

                    System.out.println(line);

                }

                in.close();
                proc.waitFor();

                boolean b=true;
                while(b) {
                    System.out.println("G://demo//temp//deal_result//" + name);
                    File file = new File("G://demo//temp//deal_result//" +id+"_"+ name);
                    File file1 = new File("G://demo//temp//deal_result//" +id+"_"+ name);
                    if (!file.exists() || !file.isFile()) {
                        System.out.println("文件不存在");
                    }else{
                        System.out.println(b);
                        int a=49152*2;
                        if (file.length()>file1.length()/20){
                            System.out.println(b);
                            b=false;
                        }
                    }
                }
            } catch (IOException e) {

                e.printStackTrace();

            } catch (InterruptedException e) {

                e.printStackTrace();
            }
                }
            return true;
        }

文件建立

  //建立目录结构
                name=name.substring(0,name.indexOf("."));
                createDir(id, id + "_" + name);
                return true;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值