package com.iplatform.recvideo; import com.iplatform.model.po.Rc_video_t1; import com.walker.infrastructure.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 把一个原视频对应的多个相似视频集合,根据图像相似度数量归并排序。

* 最终返回排序后的相似视频列表,用于写入到数据库中。 * @author 时克英 * @date 2022-09-24 */ public class SimilarVideoOrder { // 参与运算的最大距离,超过该距离说明相似度很低,不再参与运算。 private double maxDistance = 1.0; // 计算多个相似视频id,综合距离平均值, key = 相似视频ID private Map> simiVideoDistanceMap = new HashMap<>(); // 最终排序用的相似视频集合结果, key = 相似视频ID private Map orderVideoList = new HashMap<>(); public SimilarVideoOrder(List list){ for(Rc_video_t1 e : list){ this.addSimiVideoDistance(e.getSim_video_id(), e.getDistance()); this.addOrderVideo(e.getSim_video_id()); } } public List calculateOrder(){ SimilarVideoInfo similarVideoInfo = null; double averageDistance = 0; for(Map.Entry> entry : this.simiVideoDistanceMap.entrySet()){ similarVideoInfo = this.orderVideoList.get(entry.getKey()); if(similarVideoInfo == null){ throw new IllegalArgumentException("similarVideoInfo不存在,这不科学:(" + entry.getKey()); } averageDistance = this.getAverageDistance(entry.getValue(), entry.getKey()); similarVideoInfo.setDistance(averageDistance); } // List resultList = new ArrayList<>(32); for(SimilarVideoInfo e : this.orderVideoList.values()){ e.getScore(); resultList.add(e); } Collections.sort(resultList); return resultList; } private double getAverageDistance(List list, String simiVideoId){ if(StringUtils.isEmptyList(list)){ return 0; } double total = 0; for(double d : list){ if(d > this.maxDistance){ // logger.debug("distance过大,不参与排序运算:" + d + ", simiVideoId = " + simiVideoId); continue; } total += d; } return total/list.size(); } private void addOrderVideo(String simiVideoId){ SimilarVideoInfo v = this.orderVideoList.get(simiVideoId); if(v == null){ v = new SimilarVideoInfo(simiVideoId, 0); this.orderVideoList.put(simiVideoId, v); } v.increase(); } private void addSimiVideoDistance(String videoId, double distance){ List v = this.simiVideoDistanceMap.get(videoId); if(v == null){ v = new ArrayList<>(16); this.simiVideoDistanceMap.put(videoId, v); } v.add(distance); } protected final transient Logger logger = LoggerFactory.getLogger(this.getClass()); }