2021SC@SDUSC
目录
根据要求变化人脸识别的代码经历前后三次大的更新:
版本记录如下:
一.人脸识别---多人物目标
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;