Ejemplo n.º 1
0
    def __init__(self, 
        max_len=1000, logfile=None, isShow=False):
        BasicPart.__init__(self, logfile, isShow)
        self.imagename     = ''
        self.facerecog     = FaceRecog(logfile=logfile, isShow=isShow)
        self.objectdetect  = ObjectDet(logfile, single_pic_process=True,isShow=isShow, picShow=False)
        self.dbhandler     = DBHandler()
        self.searchfeature = FeatureIndex(logfile=logfile, isShow=isShow)
        self.personface    = PersonFace(logfile=logfile, isShow=isShow)
        self.solrobj       = MainSolr(logfile=logfile, isShow=isShow)

        self.max_len = max_len
        # 默认阈值
        self.setThreshold(800, 1000)      
Ejemplo n.º 2
0
    def __init_pipeline(self):
        s_time = time.time()
        process_line = []
        # 增加Merge模块
        from SceneMerge import SceneMerge
        process_line.append(SceneMerge(isShow=self.isShow))

        from ObjectDet import ObjectDet
        process_line.append(ObjectDet(isShow=self.isShow, picShow=False))

        from FaceRecog import FaceRecog
        process_line.append(FaceRecog(isShow=self.isShow, picShow=False))

        self.videosample = VideoSample(isShow=self.isShow,
                                       save_images=self.savepic)
        i_queue, i_lock = self.videosample.sample(self.videoinfo['name'])

        self.s_time = time.time()
        for processer in process_line:
            processer.startThread(i_queue, i_lock)
            i_queue, i_lock = processer.getOutputQueueAndLock()

        return i_queue, i_lock
Ejemplo n.º 3
0
class MainSearch(BasicPart):
    def __init__(self, 
        max_len=1000, logfile=None, isShow=False):
        BasicPart.__init__(self, logfile, isShow)
        self.imagename     = ''
        self.facerecog     = FaceRecog(logfile=logfile, isShow=isShow)
        self.objectdetect  = ObjectDet(logfile, single_pic_process=True,isShow=isShow, picShow=False)
        self.dbhandler     = DBHandler()
        self.searchfeature = FeatureIndex(logfile=logfile, isShow=isShow)
        self.personface    = PersonFace(logfile=logfile, isShow=isShow)
        self.solrobj       = MainSolr(logfile=logfile, isShow=isShow)

        self.max_len = max_len
        # 默认阈值
        self.setThreshold(800, 1000)      

    def setThreshold(self, faceThreshhold, contentThreshold):
        """设置阈值,阈值越大搜索到的结果更多
        
        Arguments:
            faceThreshhold {int} -- 脸部搜索阈值
            contentThreshold {int} -- 内容搜索阈值
        """
        self.faceThreshhold = faceThreshhold
        self.contentThreshold = contentThreshold


    def load_index(self,prefixlist,person_prefix_list):
        self.searchfeature.load_index(prefixlist,person_prefix_list)
        self.personface.setFeatureIndex(self.searchfeature)

    def set_image(self,imagename):
        """设置要搜索的图片路径
        
        Arguments:
            imagename {string} -- 图片路径
        """
        self.imagename     = imagename

    def read_config(self):
        # TODO:配置文件
        self.thumb_prefix = self.config.get("search","thumb_prefix")
        self.thumb_web_prefix = self.config.get("search","thumb_web_prefix")
        self.thumb_size = self.config.get("search","thumb_size")  
        self.personinfo_dir  = self.config.get("datadir","person_info")
        self.thumb_info = (self.thumb_size, self.thumb_prefix, self.thumb_web_prefix)
         
    
    def __get_db_info(self, id_type, id_list):
        """根据id查询数据库
        id_type = 'face' or 'content'
        """
        results = []
        if id_type == 'face':
            for faceid in id_list:
                v_s_info = self.dbhandler.search_scene_video_info_by_faceid(int(faceid))
                results += [SceneInfo(v_s_item) for v_s_item in v_s_info]
        else:
            for picid in id_list:
                v_s_info = self.dbhandler.search_scene_video_info_by_picid(int(picid))
                results += [SceneInfo(v_s_item) for v_s_item in v_s_info]
        return set(results)
    
    def get_face_to_video_sceneinfo(self, faceidlist):
        results = self.__get_db_info('face', faceidlist)
        return results

    def get_content_to_video_sceneinfo(self, picidlist):
        results = self.__get_db_info('content', picidlist)
        return results
    
    def create_indexs(self, perfix, featidlist=[], isSave=True):
        """创建特征的索引文件
        """
        # 创建文件名:
        facefeatlist = [id + "_ff.pkl" for id in featidlist]
        contfeatlist = [id + "_sf.pkl" for id in featidlist]
        
        self.searchfeature.create_facefeat_index(perfix,isSave,facefeatlist)
        self.searchfeature.create_contentfeat_index(perfix,isSave,contfeatlist)

    def selectByDistance(self, distance, thresh):
        """按照阈值选择符合条件的结果
        
        Arguments:
            distance {list} -- 距离列表
            thresh {int} -- 距离阈值            
        """
        max_item = 0
        for index, dist in enumerate(distance):
            if dist >= thresh:
                max_item = index
                break
            else:
                max_item = index 
        # 截取
        return max_item

    def search_face(self):        
        pic_face_dic = self.facerecog.extract_image_face_feature(self.imagename)
        num_faces = len(pic_face_dic['feats'])
        if num_faces == 0:
            self.lg("Face not found")
            return [],[]
        
        # 只搜索第一个脸
        query_feat = pic_face_dic['feats'][0]
        # print(self.prefix)
        query_result,distance = self.searchfeature.queryFace(query_feat)
        # 选取
        max_index = self.selectByDistance(distance, self.faceThreshhold)
        query_result = query_result[:max_index]
        distance = distance[:max_index]
        sceenid_unique = set(query_result)
        return query_result, distance

    def search_pic(self):
        obj_ts = time.time()
        image_obj_dic = self.objectdetect.extract_image_feature(self.imagename)
        query_feat = image_obj_dic['feat']
        tag_name   = image_obj_dic['tag_name']        
        query_feat = np.array(query_feat)
        obj_te = time.time()
        
        feat_ts = time.time()        
        query_result,distance = self.searchfeature.queryContent(query_feat)
        feat_te = time.time()        
        
        # 选取
        max_index = self.selectByDistance(distance, self.contentThreshold)
        query_result = query_result[:max_index]
        distance = distance[:max_index]

        # TODO: 按照sceneid 去重
        query_result_unique = set(query_result)
        return query_result,tag_name,distance,feat_te-feat_ts,obj_te-obj_ts

        # print(result)
    def show_pics(self, results):
        image_names = []
        for list_index,re in enumerate(results):
            re = re.dic
            timestamp  = re['starttime']
            sceneid    = re['sceneid']    
            full_videoname  = re['videoname']       
            videoname  = full_videoname.split("/")[-1]
            image_name = 'Data/Tmp/%s_s%d.jpg'%(videoname,sceneid)
            timestamp = round(timestamp,1) + 0.3
            cmd = '''
            ffmpeg -ss %d -i %s -y -f image2 -vframes 1 -s 800x600 %s
            '''%(timestamp,full_videoname,image_name)
            a = subprocess.getoutput(cmd)
            Image.open(image_name).show()
            image_names.append(image_name)
        
        return image_names

    def searchKeywords(self, text):
        """使用solr搜索关键词
        Returns:
            result_json:
            {
                keywords{string}, 
                video_num{int}, 
                video_list{list[{'videoname','videopath','thumb'}]}
                scene_num{int}
                scene_list{list[{'videoname','videopath','thumb',starttime,sceneid,length}]}
            }
        """
        v_num, v_list, s_num, s_list = self.solrobj.queryKeywords(text)
        # 创建略缩图
        json_video_list = to_json_video(self.thumb_info, v_list)
        json_scene_list = to_json_scene(self.thumb_info, s_list,False)

        result_json = {}
        result_json['keywords'] = text
        result_json['video_num'] = len(json_video_list)  
        result_json['video_list'] = json_video_list

        result_json['scene_num'] = len(json_scene_list)  
        result_json['scene_list'] = json_scene_list
        return result_json

    def joinsearch(self, image, keywords):
        """图片文字联合搜索
        
        Arguments:
            image {string} -- 图片路径
            keywords {string} -- 关键词
        """
        keywords_json = self.searchKeywords(keywords)
        self.set_image(image)
        image_json = self.searchImage()
        

    def searchImage(self):
        """返回json格式的图片检索结果
        Returns:
            result_json:
            {
                keywords{string}, 
                video_num{int}, 
                video_list{list[{'videoname','videopath','thumb'}]},
                face_scene_num{int},
                face_scene_list{list[scene},
                face_dist_list{list[double]},

                content_scene_num{int},
                content_scene_list{list[scene]},
                content_dist_list{list[double]},

                both_video_num{int}
                both_scene_num{int}
                both_scene_list{list[scene]}

                personid,personname,personinfo
                object_num,object_list

            }
        TODO: 完成物体搜索结果
        """
        fs = time.time()
        face_idlist, face_distance = self.search_face()[:self.max_len]
        face_results = self.get_face_to_video_sceneinfo(face_idlist)
        self.lg('searchImage FACE:' + str(len(face_idlist)))
        fe = time.time()
        

        cont_idlist, object_list, cont_distance,ft,ot = self.search_pic()
        cont_idlist = cont_idlist[:self.max_len]
        cont_results = self.get_content_to_video_sceneinfo(cont_idlist)
        self.lg('searchImage CONT:' + str(len(cont_idlist)))


        ts = time.time()
        result_json = {}
        result_json['face_scene_num'] = len(face_idlist)  
        result_json['face_scene_list'] = to_json_scene(self.thumb_info, face_results)
        result_json['face_dist_list'] = list(face_distance)       

        result_json['content_scene_num'] = len(cont_idlist)  
        result_json['content_scene_list'] = to_json_scene(self.thumb_info, cont_results)
        result_json['content_dist_list'] = list(cont_distance)       
        
        # 交集
        fsids, fvids = extrace_ids(face_results)
        csids, cvids = extrace_ids(cont_results)
        both_scene_list = []
        # both_scene_list = set(face_results) & set(cont_results)
        both_video_list = set(fvids) | set(cvids)
        result_json['both_video_num']  = len(both_video_list)
        result_json['both_scene_num']  = len(both_scene_list)
        result_json['both_scene_list'] = to_json_scene(self.thumb_info, both_scene_list)

        te = time.time()     

        ps = time.time()   
        # 识别人物
        pid, pname = self.personface.identify_pic_person(self.imagename)
        # 读取存储的人物简介
        pinfo = ''
        if pid != -1:
            pinfo = read_person_info(self.personinfo_dir, pid)
        result_json['personid'] = pid
        result_json['personname'] = pname
        result_json['personinfo'] = pinfo
        # 物体集合
        result_json['object_num']  = len(object_list)
        result_json['object_list'] = object_list
        pe = time.time()
        print("%.4f, %.4f, %.4f, %.4f,%.4f"%(fe-fs, ot, ft, pe-ts, pe-fs))
        return result_json
Ejemplo n.º 4
0
 def initFR(self):
     """初始化人脸特征提取模块
     """
     from FaceRecog import FaceRecog
     self.fr = FaceRecog(isShow = self.isShow, picShow = self.picShow)
Ejemplo n.º 5
0
class PersonFace(BasicPart):
    """PersonFace,人物人脸录入及比对模块
    Arguments:
        BasicPart {[type]} -- [description]
    """
    def __init__(self, 
        threshold = None, 
        logfile   = None,
        picShow   = False,          
        isShow    = False): 
        '''
            threshold: 人脸大小阈值
            logfile:   日志文件路径
            isShow:    显示图片处理过程
            
        '''
        BasicPart.__init__(self, logfile=logfile, isShow=isShow)
        self.picShow  = picShow
        from DBHandler import DBHandler
        self.handler = DBHandler()        
        self.initFR()
        # 缓存
        self.dbcache = {}
        # self.initFI()        

    def initFI(self):
        """初始化索引模块
        """
        from FeatureIndex import FeatureIndex
        prefixs = ['Person']
        self.fi = FeatureIndex(index_prefixs=prefixs,isShow = self.isShow)    
    
    def initFR(self):
        """初始化人脸特征提取模块
        """
        from FaceRecog import FaceRecog
        self.fr = FaceRecog(isShow = self.isShow, picShow = self.picShow)

    def read_config(self):
        """读配置文件
        """
        self.dir = {}
        self.maxdistance         = self.config.getint('facerecog','max_distance')
        self.thresh              = self.config.getint('facerecog','threshold')
        self.dir['faces']        = self.config.get('datadir','faces')
        self.dir['faces_feat']   = self.config.get('datadir','faces_feat')
        self.dir['faces_sample'] = self.config.get('datadir','faces_sample')
    
    def storePersonToDB(self):
        """将人物存到PersonInfo表,返回id
        """
        self.person_ids = self.handler.addmanyPerson(self.person_names)

    def index_person(self, person_list = [], prefix="Person"):
        """对sample文件夹下所有人物人脸图片建立索引
            或只建立某个人的索引
        """
        if len(person_list) == 0:
            self.person_names   = os.listdir(self.dir['faces_sample'])
        else:
            self.person_names   = person_list
        # 存数据库,获取id
        self.storePersonToDB()
        self.person_pic_feats = []
        self.person_pic_ids   = []
        
        for index, person_name in enumerate(self.person_names):
            # 每一个人物对应一个文件夹
            full_path = self.dir['faces_sample'] + '/' + person_name

            pic_list = os.listdir(full_path)
            num_faces = len(pic_list)
            for face_pic in pic_list:
                face_pic = full_path + '/' + face_pic
                pic_face_dic = self.fr.extract_image_face_feature(face_pic)
                feat = pic_face_dic['feats'][0]
                self.person_pic_feats.append(feat)
                self.person_pic_ids.append(self.person_ids[index])
        
        # 建立索引
        self.initFI()
        self.fi.create_person_index(self.person_pic_feats, self.person_pic_ids, prefix)

    def setFeatureIndex(self, fi):
        """设置FI对象,用于查询时,从外部导入已载入索引的索引对象
        
        Arguments:
            fi {FeatureIndex} -- 索引检索对象
        """
        self.fi = fi

    def identify_pic_person(self, imagename):
        """确定图片中人物名字以及id
        
        Arguments:
            imagename {string} -- 图片名
        
        Returns:
            personid, personname
        """
        face_dic = self.fr.extract_image_face_feature(imagename)
        if len(face_dic['feats']) > 0:
            personid, personname = self.idenity(face_dic['feats'][0])
        else:
            personid=-1
            personname="无人物"            
        return personid, personname
        # print(result)

    def idenity(self, facefeat):
        """确定人物身份,返回人物名及人物id
        
        Arguments:
            facefeat {data} -- 待确定的人脸特征
            -1, unknown 未识别人物
        """
        # 首先进行query
        results, distance = self.fi.queryPerson(facefeat)

        # 若高于最远距离,则为未知人物,返回None,''
        if distance[0] > self.maxdistance:
            personid = -1
            personname = 'unknown'
        else:            
            # 确定人物身份:
            # kmean
            max_count_id = pd.value_counts(results, sort=True).index[0]
            # 计算每个结果的得分
            personid = int(max_count_id)
            # 首先查询缓存,若miss后再查询数据库
            if personid in self.dbcache.keys():
                personname = self.dbcache[personid]
            else:
                personname = self.handler.queryPersonById(personid)[0][1]
                self.dbcache[personid] = personname
        return personid, personname
Ejemplo n.º 6
0
class MainSearch(BasicPart):
    def __init__(self, max_len=1000, logfile=None, isShow=False):
        BasicPart.__init__(self, logfile, isShow)
        self.imagename = ''
        self.facerecog = FaceRecog(logfile=logfile, isShow=isShow)
        self.objectdetect = ObjectDet(logfile,
                                      single_pic_process=True,
                                      isShow=isShow,
                                      picShow=False)
        self.dbhandler = DBHandler()
        self.searchfeature = FeatureIndex(logfile=logfile, isShow=isShow)
        self.personface = PersonFace(logfile=logfile, isShow=isShow)
        self.solrobj = MainSolr(logfile=logfile, isShow=isShow)
        self.max_len = max_len
        # 默认阈值
        # self.setThreshold(800, 1000) # nmslib
        self.setThreshold(800, 300000)  # faiss

    def setThreshold(self, faceThreshhold, contentThreshold):
        """设置阈值,阈值越大搜索到的结果更多
        
        Arguments:
            faceThreshhold {int} -- 脸部搜索阈值
            contentThreshold {int} -- 内容搜索阈值
        """
        self.faceThreshhold = faceThreshhold
        self.contentThreshold = contentThreshold

    def load_index(self, prefixlist, person_prefix_list):
        self.searchfeature.load_index(self.face_index_method,
                                      self.content_index_method, prefixlist,
                                      person_prefix_list)
        self.personface.setFeatureIndex(self.searchfeature)

    def set_image(self, imagename):
        """设置要搜索的图片路径
        
        Arguments:
            imagename {string} -- 图片路径
        """
        self.imagename = imagename

    def read_config(self):
        # TODO:配置文件
        self.thumb_prefix = self.config.get("search", "thumb_prefix")
        self.thumb_web_prefix = self.config.get("search", "thumb_web_prefix")
        self.thumb_size = self.config.get("search", "thumb_size")
        self.personinfo_dir = self.config.get("datadir", "person_info")
        self.thumb_info = (self.thumb_size, self.thumb_prefix,
                           self.thumb_web_prefix)
        self.content_distance_discount = self.config.getint(
            "search", "content_distance_discount")
        # 索引方法
        self.content_index_method = self.config.get("search",
                                                    "content_index_method")
        self.face_index_method = self.config.get("search", "face_index_method")

    def __get_db_info(self, id_type, id_list, distance):
        """根据id查询数据库
        id_type = 'face' or 'content'
        """
        results = []
        result_distance = []
        if id_type == 'face':
            for index, faceid in enumerate(id_list):
                v_s_info = self.dbhandler.search_scene_video_info_by_faceid(
                    int(faceid))

                # 字典中增加distance
                for i in range(len(v_s_info)):
                    v_s_info[i][id_type + '_distance'] = distance[index]

                results += [SceneInfo(v_s_item) for v_s_item in v_s_info]
                for i in range(len(v_s_info)):
                    result_distance.append(distance[index])
        else:
            for index, picid in enumerate(id_list):
                v_s_info = self.dbhandler.search_scene_video_info_by_picid(
                    int(picid))

                # 字典中增加distance
                for i in range(len(v_s_info)):
                    v_s_info[i][id_type + '_distance'] = distance[index]

                results += [SceneInfo(v_s_item) for v_s_item in v_s_info]
                for i in range(len(v_s_info)):
                    result_distance.append(distance[index])
        return results, result_distance

    def get_face_to_video_sceneinfo(self, faceidlist, distance):
        results, re_distance = self.__get_db_info('face', faceidlist, distance)
        return results, re_distance

    def get_content_to_video_sceneinfo(self, picidlist, distance):
        results, re_distance = self.__get_db_info('content', picidlist,
                                                  distance)
        return results, re_distance

    def create_indexs(self, perfix, featidlist=[], isSave=True):
        """创建特征的索引文件
        """
        # 创建文件名:
        facefeatlist = [id + "_ff.pkl" for id in featidlist]
        contfeatlist = [id + "_sf.pkl" for id in featidlist]

        self.searchfeature.create_facefeat_index(self.face_index_method,
                                                 perfix, isSave, facefeatlist)
        self.searchfeature.create_contentfeat_index(self.content_index_method,
                                                    perfix, isSave,
                                                    contfeatlist)

    def selectByDistance(self, distance, thresh):
        """按照阈值选择符合条件的结果
        
        Arguments:
            distance {list} -- 距离列表
            thresh {int} -- 距离阈值            
        """
        max_item = 0
        for index, dist in enumerate(distance):
            if dist >= thresh:
                max_item = index
                break
            else:
                max_item = index
        # 截取
        return max_item

    def search_face(self):
        pic_face_dic = self.facerecog.extract_image_face_feature(
            self.imagename)
        num_faces = len(pic_face_dic['feats'])
        if num_faces == 0:
            self.lg("Face not found")
            return [], []

        # 只搜索第一个脸
        query_feat = pic_face_dic['feats'][0]
        # print(self.prefix)
        query_result, distance = self.searchfeature.queryFace(
            self.face_index_method, ['all'], query_feat)
        # 选取
        max_index = self.selectByDistance(distance, self.faceThreshhold)
        query_result = query_result[:max_index]
        distance = distance[:max_index]
        return query_result, distance

    def search_pic(self):
        image_obj_dic = self.objectdetect.extract_image_feature(self.imagename)
        query_feat = image_obj_dic['feat']
        tag_name = image_obj_dic['tag_name']
        query_feat = np.array(query_feat)
        query_result, distance = self.searchfeature.queryContent(
            self.content_index_method, ['all'], query_feat)
        # print(len(distance))
        distance = [i / self.content_distance_discount for i in distance]
        # 选取
        max_index = self.selectByDistance(distance, self.contentThreshold)
        query_result = query_result[:max_index]
        distance = distance[:max_index]
        return query_result, tag_name, distance

        # print(result)
    def show_pics(self, results):
        image_names = []
        for list_index, re in enumerate(results):
            re = re.dic
            timestamp = re['starttime']
            sceneid = re['sceneid']
            full_videoname = re['videoname']
            videoname = full_videoname.split("/")[-1]
            image_name = 'Data/Tmp/%s_s%d.jpg' % (videoname, sceneid)
            timestamp = round(timestamp, 1) + 0.3
            cmd = '''
            ffmpeg -ss %d -i %s -y -f image2 -vframes 1 -s 800x600 %s
            ''' % (timestamp, full_videoname, image_name)
            a = subprocess.getoutput(cmd)
            Image.open(image_name).show()
            image_names.append(image_name)

        return image_names

    def searchKeywords(self, text, keepObjFormat=False):
        """使用solr搜索关键词
        Returns:
            result_dic:
            {
                keywords{string}, 
                video_num{int}, 
                video_list{list[{'videoname','videopath','thumb'}]}
                scene_num{int}
                scene_list{list[{'videoname','videopath','thumb',starttime,sceneid,length}]}
            }
        """
        v_num, v_list, s_num, s_list = self.solrobj.queryKeywords(text)
        # 创建略缩图
        json_video_list = make_video_thumb(self.thumb_info, v_list)
        ns_list = []
        for scene in s_list:
            scene['sceneid'] = int(scene['sceneid'])
            scene['videoid'] = int(scene['videoid'][0])
            ns_list.append(scene)
        s_list = ns_list
        if not keepObjFormat:
            json_scene_list = make_scene_thumb(self.thumb_info, s_list, False)
        else:
            # 转换为SceneInfo
            json_scene_list = [SceneInfo(dic) for dic in s_list]

        result_dic = {}
        result_dic['keywords'] = text
        result_dic['video_num'] = len(json_video_list)
        result_dic['video_list'] = json_video_list

        result_dic['scene_num'] = len(json_scene_list)
        result_dic['scene_list'] = json_scene_list
        return result_dic

    def searchJoint(self, image, keywords):
        """图片文字联合搜索
        
        Arguments:
            image {string} -- 图片路径
            keywords {string} -- 关键词
        Returns:
            result_dic:
            {
                keywords{string}, 
                face_scene_num{int},
                face_scene_list{list[scene},
                face_dist_list{list[double]},

                content_scene_num{int},
                content_scene_list{list[scene]},
                content_dist_list{list[double]},

                smart_scene_num{int},
                smart_scene_list{list[scene]},

                keywords_scene_num{int},
                keywords_scene_list{list[scene]},

                both_video_num{int}
                both_scene_num{int}
                both_scene_list{list[scene]}

                personid,personname,personinfo
                object_num,object_list

            }
        """
        keywords_scenes = self.searchKeywords(keywords, keepObjFormat=True)
        image_scenes = self.searchImage(image, keepObjFormat=True)
        # 结果综合 TODO
        smart_scene_list, both_scene_list = self.smartsort(
            keywords_scenes['scene_list'], image_scenes['content_scene_list'],
            image_scenes['face_scene_list'], image_scenes['content_dist_list'],
            image_scenes['face_dist_list'])

        result_dic = image_scenes

        # 更新both
        result_dic['both_scene_num'] = len(both_scene_list)
        result_dic['both_scene_list'] = make_scene_thumb(
            self.thumb_info, both_scene_list)

        result_dic['smart_scene_num'] = len(smart_scene_list)
        result_dic['smart_scene_list'] = make_scene_thumb(
            self.thumb_info, smart_scene_list)

        result_dic['keywords_scene_num'] = len(keywords_scenes['scene_list'])
        result_dic['keywords_scene_list'] = make_scene_thumb(
            self.thumb_info, keywords_scenes['scene_list'])

        result_dic['face_scene_list'] = make_scene_thumb(
            self.thumb_info, result_dic['face_scene_list'])
        result_dic['content_scene_list'] = make_scene_thumb(
            self.thumb_info, result_dic['content_scene_list'])

        result_dic['keywords'] = keywords_scenes['keywords']
        return result_dic

    def compute_score(self, list, keyname, decay):
        # 从前到后,按照100, 100-(100/size), 100-2*(100/size)...计算得分
        # 加权距离的指数 log(1/distance)
        # 总分 =
        list_size = len(list)
        if list_size > 0:
            delta = 100 / list_size
            delta = decay
            scores = [100 - i * delta for i in range(list_size)]
            for index, item in enumerate(list):
                item.dic[keyname] = scores[index]
        return list

    def smartsort(self, klist, clist, flist, cdistance, fdistance):
        """多来源结果智能排序
        
        Arguments:
            klist {list} -- 关键词搜索结果
            clist {list} -- content搜索结果
            flist {list} -- face搜索结果
            cdistance {list} -- content搜索距离
            fdistance {list} -- face搜索距离            
        Returns:
            list -- 智能排序结果
        """
        klist = self.compute_score(klist, 'keyword_scores', 0.44)
        clist = self.compute_score(clist, 'content_scores', 0.42)
        flist = self.compute_score(flist, 'face_scores', 0.4)

        Kset = set(klist)
        Cset = set(clist)
        Fset = set(flist)

        smart_list = []

        keyword_weight = 0.7
        content_weight = 0.78
        face_weight = 0.8

        for content_item in clist:
            sum_score_item = deepcopy(content_item)
            sum_score_item.dic[
                'sum_scores'] = content_weight * sum_score_item.dic[
                    'content_scores']
            if sum_score_item in Fset:
                face_score = flist[flist.index(
                    sum_score_item)].dic['face_scores']
                sum_score_item.dic['sum_scores'] += face_weight * face_score
            if sum_score_item in Kset:
                key_score = klist[klist.index(
                    sum_score_item)].dic['keyword_scores']
                sum_score_item.dic['sum_scores'] += keyword_weight * key_score
            smart_list.append(sum_score_item)

        Sset = set(smart_list)
        for face_item in flist:
            if face_item in Sset:
                continue

            sum_score_item = deepcopy(face_item)
            sum_score_item.dic[
                'sum_scores'] = face_weight * sum_score_item.dic['face_scores']
            if sum_score_item in Cset:
                content_score = clist[clist.index(
                    sum_score_item)].dic['content_scores']
                sum_score_item.dic[
                    'sum_scores'] += content_weight * content_score
            if sum_score_item in Kset:
                key_score = klist[klist.index(
                    sum_score_item)].dic['keyword_scores']
                sum_score_item.dic['sum_scores'] += keyword_weight * key_score
            smart_list.append(sum_score_item)

        Sset = set(smart_list)
        for key_item in klist:
            if key_item in Sset:
                continue

            sum_score_item = deepcopy(key_item)
            sum_score_item.dic[
                'sum_scores'] = keyword_weight * sum_score_item.dic[
                    'keyword_scores']
            if sum_score_item in Cset:
                content_score = clist[clist.index(
                    sum_score_item)].dic['content_scores']
                sum_score_item.dic[
                    'sum_scores'] += content_weight * content_score
            if sum_score_item in Fset:
                face_score = flist[flist.index(
                    sum_score_item)].dic['face_scores']
                sum_score_item.dic['sum_scores'] += face_weight * face_score
            smart_list.append(sum_score_item)
        # 对smart_list按照 sum_scores 排序
        smart_list = sorted(smart_list,
                            key=lambda x: x.dic['sum_scores'],
                            reverse=True)

        if len(klist) == 0:
            both_list = list(Cset & Fset)
        else:
            both_list = list(Kset & Cset & Fset)

        return smart_list, both_list

    def searchImage(self, imagename, keepObjFormat=False):
        """返回json格式的图片检索结果
        Returns:
            result_dic:
            {
                video_num{int}, 
                video_list{list[{'videoname','videopath','thumb'}]},
                face_scene_num{int},
                face_scene_list{list[scene},
                face_dist_list{list[double]},

                content_scene_num{int},
                content_scene_list{list[scene]},
                content_dist_list{list[double]},

                both_video_num{int}
                both_scene_num{int}
                both_scene_list{list[scene]}

                personid,personname,personinfo
                object_num,object_list

            }
        TODO: 完成物体搜索结果
        """
        self.imagename = imagename
        # 由于relate加入,所以需要对返回结果进行处理
        face_idlist, face_distance = self.search_face()
        face_results, face_distance = self.get_face_to_video_sceneinfo(
            face_idlist, face_distance)

        cont_idlist, object_list, cont_distance = self.search_pic()
        cont_idlist = cont_idlist
        cont_results, cont_distance = self.get_content_to_video_sceneinfo(
            cont_idlist, cont_distance)

        result_dic = {}
        # face
        result_dic['face_scene_num'] = len(face_results)
        if not keepObjFormat:
            result_dic['face_scene_list'] = make_scene_thumb(
                self.thumb_info, face_results)
        else:
            result_dic['face_scene_list'] = face_results
        result_dic['face_dist_list'] = list(face_distance)

        # content
        result_dic['content_scene_num'] = len(cont_results)
        if not keepObjFormat:
            result_dic['content_scene_list'] = make_scene_thumb(
                self.thumb_info, cont_results)
        else:
            result_dic['content_scene_list'] = cont_results
        result_dic['content_dist_list'] = list(cont_distance)

        # 交集
        _, fvids = extrace_ids(face_results)
        _, cvids = extrace_ids(cont_results)
        both_video_list = set(fvids) | set(cvids)
        result_dic['both_video_num'] = len(both_video_list)
        smart_scene_list, both_list = self.smartsort([], cont_results,
                                                     face_results,
                                                     cont_distance,
                                                     face_distance)

        result_dic['both_scene_num'] = len(both_list)
        if not keepObjFormat:
            result_dic['both_scene_list'] = make_scene_thumb(
                self.thumb_info, both_list)
        else:
            result_dic['both_scene_list'] = both_list

        result_dic['smart_scene_num'] = len(smart_scene_list)
        if not keepObjFormat:
            result_dic['smart_scene_list'] = make_scene_thumb(
                self.thumb_info, smart_scene_list)
        else:
            result_dic['smart_scene_list'] = smart_scene_list

        # 识别人物
        pid, pname = self.personface.identify_pic_person(self.imagename)
        # 读取存储的人物简介
        pinfo = ''
        if pid != -1:
            pinfo = read_person_info(self.personinfo_dir, pid)
        result_dic['personid'] = pid
        result_dic['personname'] = pname
        result_dic['personinfo'] = pinfo

        # 物体集合
        result_dic['object_num'] = len(object_list)
        result_dic['object_list'] = object_list
        return result_dic
Ejemplo n.º 7
0
def main():
    tk = Tk()
    database = Database()
    facerecog = FaceRecog("./opencv_data/haarcascade/haarcascade_frontalface_default.xml", "./opencv_data/haarcascade/haarcascade_frontalface_alt.xml", "./opencv_data/trainer/trainer.yml", "./user_image")
    app = App(tk, database, facerecog)
Ejemplo n.º 8
0
def main():
    db = Database()
    knn = KNN(db)
    fr = FaceRecog(db, knn)
    tg = Telegram(fr, db)
    tg.start()