📄 scanner.cpp
字号:
sclprms.scale_x, sclprms.scale_y, matches[m])); } matches.clear(); } scancnt++; } } m_max_scaled_template_width = sclprms.scaled_template_width; m_max_scaled_template_height = sclprms.scaled_template_height; NextScaleParams(sclprms); ASSERT(N!=sclprms.scaled_template_width*sclprms.scaled_template_height); N = sclprms.scaled_template_width * sclprms.scaled_template_height; } if (m_post_process) { PostProcess(posClsfd); return (int) posClsfd.size(); } else { return scancnt; }}bool intersect(const CScanMatch& a, const CScanMatch& b){ if (a.left<=b.left && b.left<=a.right || a.left<=b.right && b.right<=a.right || a.top<=b.top && b.top<=a.bottom || a.top<=b.bottom && b.bottom<=a.bottom || b.left<=a.left && a.left<=b.right || b.left<=a.right && a.right<=b.right || b.top<=a.top && a.top<=b.bottom || b.top<=a.bottom && a.bottom<=b.bottom) { return true; } else { return false; }}/** throw out some positives if they overlap, pick the average* of each coordinate for every overlapping set*/void CImageScanner::PostProcess(CScanMatchVector& posClsfd) const{ int num_matches = (int)posClsfd.size(); if (num_matches<2) return; // partition all matches into disjoint clusters CIntVector clustnums; clustnums.resize(num_matches); clustnums[0] = 0; int num_clusters = 1; for (int matchcnt=1; matchcnt<num_matches; matchcnt++) { clustnums[matchcnt] = -1; for (int prevcnt=0; prevcnt<matchcnt; prevcnt++) { if (intersect(posClsfd[prevcnt], posClsfd[matchcnt])) { if (clustnums[matchcnt]==-1) { // prevcnt is first rectangle that matchcnt intersects with clustnums[matchcnt] = clustnums[prevcnt]; } else { // prevcnt is not the first rectangle that matchcnt intersects with, // need to make sure that if prevcnt is from a different cluster // than the first one that we merge the two clusters if (clustnums[matchcnt]<clustnums[prevcnt]) { // need to merge cluster clustnums[prevcnt] int cluster clustnums[matchcnt] //int oldnum = clustnums[prevcnt]; for (int patchcnt=0; patchcnt<matchcnt; patchcnt++) { if (clustnums[patchcnt]==clustnums[prevcnt]) { clustnums[patchcnt] = clustnums[matchcnt]; } } /* if (oldnum!=num_clusters-1) { // we created a hole in the cluster numbering - fix it. for (int patchcnt=0; patchcnt<matchcnt; patchcnt++) { if (clustnums[patchcnt]>oldnum) { clustnums[patchcnt]--; } } } num_clusters--; */ } else if (clustnums[prevcnt]<clustnums[matchcnt]) { // need to merge cluster clustnums[matchcnt] into cluster clustnums[prevcnt] //int oldnum = clustnums[matchcnt]; for (int patchcnt=0; patchcnt<=matchcnt; patchcnt++) { if (clustnums[patchcnt]==clustnums[matchcnt]) { clustnums[patchcnt] = clustnums[prevcnt]; } } /* if (oldnum!=num_clusters-1) { // we created a hole in the cluster numbering - fix it. for (int patchcnt=0; patchcnt<matchcnt; patchcnt++) { if (clustnums[patchcnt]>oldnum) { clustnums[patchcnt]--; } } } num_clusters--; */ } else { // have the same cluster number already } } } } if (clustnums[matchcnt]==-1) { clustnums[matchcnt] = num_clusters; num_clusters++; } } // patch holes in cluster numbering CIntVector elements; elements.resize(num_clusters); for (int e=0; e<num_clusters; e++) elements[e] = 0; for (int mcnt=0; mcnt<num_matches; mcnt++) { elements[clustnums[mcnt]]++; } for (int ccnt=0; ccnt<num_clusters; ccnt++) { if (elements[ccnt]==0) { if (ccnt+1<num_clusters) { for (int mcnt=0; mcnt<num_matches; mcnt++) { if (clustnums[mcnt]>ccnt) { clustnums[mcnt]--; } else { ASSERT(clustnums[mcnt]!=ccnt); } } elements[ccnt] = elements[ccnt+1]; ccnt--; } num_clusters--; } } // calculate mean for each corner of each cluster, do this in // a single pass over the match vector ASSERT(num_clusters>0); int seen_clustnum = 0; for (int mtchcnt=1; mtchcnt<num_matches; mtchcnt++) { int clustnum = clustnums[mtchcnt]; if (clustnum<=seen_clustnum) { posClsfd[clustnum].left += posClsfd[mtchcnt].left; posClsfd[clustnum].top += posClsfd[mtchcnt].top; posClsfd[clustnum].right += posClsfd[mtchcnt].right; posClsfd[clustnum].bottom += posClsfd[mtchcnt].bottom; } else { // who knows what's in clustnum! put this one in posClsfd[clustnum].left = posClsfd[mtchcnt].left; posClsfd[clustnum].top = posClsfd[mtchcnt].top; posClsfd[clustnum].right = posClsfd[mtchcnt].right; posClsfd[clustnum].bottom = posClsfd[mtchcnt].bottom; seen_clustnum = clustnum; } } posClsfd.resize(num_clusters); for (int clustcnt=0; clustcnt<num_clusters; clustcnt++) { posClsfd[clustcnt].left /= elements[clustcnt]; posClsfd[clustcnt].top /= elements[clustcnt]; posClsfd[clustcnt].right /= elements[clustcnt]; posClsfd[clustcnt].bottom /= elements[clustcnt]; }}void CImageScanner::InitScaleParams(const CClassifierCascade& cascade, CScaleParams& params) const{ ASSERT(m_start_scale>=1.0); ASSERT(m_scale_inc_factor>1.0); ASSERT(m_translation_inc_x>=1); ASSERT(m_translation_inc_y>=1); // run cascade for each large enough sub-image params.template_width = cascade.GetTemplateWidth(); params.template_height = cascade.GetTemplateHeight(); double image_area_ratio = cascade.GetImageAreaRatio(); // depending on the size ratio of the image area to test, stretch template // in height or width double template_ratio = (double)params.template_width/(double)params.template_height; if (image_area_ratio<template_ratio) { // image area is narrower than template, stretch template in height params.scale_x = m_start_scale; params.scale_y = m_start_scale*template_ratio/image_area_ratio; } else { // stretch template width params.scale_x = m_start_scale*image_area_ratio/template_ratio; params.scale_y = m_start_scale; } ASSERT(params.scale_x>=1.0); ASSERT(params.scale_y>=1.0); params.base_scale = m_start_scale; params.scaled_template_width = (int) (params.scale_x*params.template_width); params.scaled_template_height = (int) (params.scale_y*params.template_height); params.actual_scale_x = (double) params.scaled_template_width/(double)params.template_width; params.actual_scale_y = (double) params.scaled_template_height/(double)params.template_height; params.translation_inc_x = m_translation_inc_x; params.translation_inc_y = m_translation_inc_y;}void CImageScanner::NextScaleParams(CScaleParams& params) const{ // floating point scaling double old_actual_scale_x = params.actual_scale_x; double old_actual_scale_y = params.actual_scale_y; do { params.scale_x *= m_scale_inc_factor; params.scale_y *= m_scale_inc_factor; params.base_scale *= m_scale_inc_factor; params.translation_inc_x *= m_scale_inc_factor; params.translation_inc_y *= m_scale_inc_factor; params.scaled_template_width = (int) (params.scale_x*params.template_width); params.scaled_template_height = (int) (params.scale_y*params.template_height); params.actual_scale_x = (double) params.scaled_template_width/(double)params.template_width; params.actual_scale_y = (double) params.scaled_template_height/(double)params.template_height; } while (old_actual_scale_x==params.actual_scale_x || old_actual_scale_y==params.actual_scale_y);}ostream& operator<<(ostream& os, const CImageScanner& scanner){ return scanner.output(os);}ostream& CImageScanner::output(ostream& os) const{ os << "start_scale " << m_start_scale << ", stop_scale " << m_stop_scale << ", scale_inc_factor " << m_scale_inc_factor << ", inc_x " << m_translation_inc_x << ", inc_y " << m_translation_inc_y << endl; os << "area: left " << m_scan_area.left << ", top " << m_scan_area.top << ", right " << m_scan_area.right << ", bottom " << m_scan_area.bottom << endl; os << (m_is_active? "active" : "inactive") << endl; return os;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -