帮老师做了一个简单的基于行为(主要是步态)的ReID问题的Demo,效果例如以下图:
以下是提取的集中特征,前三个都是GEI系的,后几个是基于光流场的。然后右边是识别出的几个对象的排序,由于没有角度和衣服,书包等协变量改变的问题,所以识别比較准确,排第一的就是对的。事实上特征是之前提好的,由于对象也不多,识别序列对也是一次性计算的。右边识别出的几个人是显示的动态行走的序列图,所以预先把每一个人resize的剪影存储在vector中。
int main(int argc, char*argv[]){ string video_name(argv[1]); int video_height=240; int video_width=320; int window_height=video_height+feature_height; int window_width=video_width+feature_width; vector<vector<int> > pairs; process(pairs); vector<vector<Mat> > features; vector<vector<Mat> > images; readFeatures(features,images); Mat window=Mat::zeros(window_height,window_width,CV_8UC3); Rect rect; rect.x=rect.y=0;rect.width=video_width;rect.height=video_height; Mat window_video(window,rect); VideoCapture video(video_name); int frame_num=0; Mat frame; video>>frame; vector<Mat> frames; string people_num_str=video_name.substr(0,3); int people_num=atoi(people_num_str.c_str()); while(!frame.empty()||!frames.empty()){ frame_num++; if(!frame.empty()){ frame.copyTo(window_video); Mat tmp; frame.copyTo(tmp); frames.push_back(tmp); video>>frame; } else{ int show_num=frame_num%frames.size(); (frames[show_num]).copyTo(window_video); } if(frame_num>40){ for(int ci=0;ci<class_size;ci++){ Rect rect; rect.x=ci*feature_width; rect.y=video_height; rect.width=feature_width; rect.height=feature_height; Mat featre_mat(window,rect); if(frame_num>ci*10+40) features[ci][people_num-1].copyTo(featre_mat); } } if(frame_num>120){ for(int i=0;i<4;i++){ int recp=pairs[people_num-1][i+1]; Rect rect; rect.x=video_width; rect.y=i*feature_height; rect.width=feature_width; rect.height=feature_height; Mat rec_mat(window,rect); int recpnum=frame_num%40; images[recp-1][recpnum].copyTo(rec_mat); if(pairs[people_num-1][i+1]==people_num) rectangle(window,rect,Scalar(0,0,255)); } } Mat largeWinow(window_height*2,window_width*2,CV_8UC3); resize(window,largeWinow,Size(),2.0f,2.0f,INTER_LINEAR); imshow("Gait",largeWinow); waitKey(50); } return 0; }事实上基本的代码是process()和readFeatures(),一个用来计算识别排序的对组合,一个用来读取之前提取的特征和每一个人用来显示在右边的行走序列图,只是也比較好理解,这里不再贴了,有个计算前k个最小值的代码放一下把。
void getKMinScores(vector<float>&scores, vector<float>& k_scores,int KNN_K){ for(int k=0;k<KNN_K;k++){ k_scores[k] = FLT_MAX; } int people_size = scores.size(); for(int pi=0;pi<people_size;pi++){ int change_id = -1; for(int kk=0;kk<KNN_K;kk++){ if(scores[pi]<k_scores[kk]){ change_id = kk; } } if(change_id>=0){ if(change_id==(KNN_K-1)|| (change_id<(KNN_K-1)&&scores[pi]!=k_scores[change_id+1]) ){ for(int c=0;c<change_id;c++){ k_scores[c] = k_scores[c+1]; } k_scores[change_id] = scores[pi]; } } } return ; }抱歉,水文一篇~