帮老师做了一个简单的基于行为(主要是步态)的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 ;
}抱歉,水文一篇~【计算机视觉】基于行为的ReID演示,布布扣,bubuko.com
原文:http://blog.csdn.net/xiaowei_cqu/article/details/35985311