Improvement of opencv meanshift fusion Rectangular Box

Source: Internet
Author: User
Tags svm


The Code improvements in opencv, of course, should be based on their own actual situation, opencv Pedestrian detection has two kinds of Rectangular Box fusion algorithm, here only to improve the meanshift Method

If you have a better method, I hope you can share it with me.

I have also made improvements for removing the coincidence part, and can add it to my own program.

Why do I need to perform local meanshift?


Figure 1. Global meanshift

: The two images are close to each other and have multiple rectangular frames. This result may be caused by global meanshift fusion.

This can be avoided if local fusion is used.


/* ---------------------------------- Score determination: begin ---------------------------------------------- * // normalize the region of interest and calculate the hog feature -- begin /////////// //////// cvsetimageroi (imageorigin, r); iplimage * test = cvcreateimage (cvgetsize (imageorigin), 8, 3); cvcopyimage (imageorigin, test); cvresetimageroi (imageorigin); iplimage * testtempimg = cvcreateimage (cvsize ), 8, 3); cvzero (testtempimg); cvresize (Test, test Tempimg); hog-> compute (testtempimg, descriptors, size (), size (); // hog feature calculation mat another (descriptors); descriptors. clear (); ////////// normalize the region of interest and calculate the hog feature -- end ///// ///Double RET = 0; ret = ssvm. get_calc_liner (vec_count, var_count, A, another, results, Alpha, 0)-rock; // calculate the SVM score // cvreleaseimage (& test ); cvreleaseimage (& testtempimg); // If (Ret <0) {continue; // remove the image whose SVM score is less than 0} RC _. push_back (RCC); weights. push_back (RET); double rate = max (RCC. width * 1.0/40, RCC. height * 1.0/40); // select the maximum length and width as the scale. The consideration is not thoughtful enough. Here we change and meanshift should all be changed. // here we can also improve foundscales. push_back (rate);/* -------------------------------- score determination: End -------------------------------------------------- * // The above should be a loop, add multiple points //////////////////////////////////// /// fusion process-begin /////////////// //////////// Vector <rect> RC _; // Rectangular Box // vector <double> weights; // weight, score // vector <double> foundscales; // scaled down grouprectangles_meanshift1 (RC _, weights, foundscales, 0.3, size (40, 40 )); // combine the rectangular box in the box. // grouprectangles_meanshift1 this function is defined at the end //////////////////////// /fusion process-end /////////////////////////////////// ///// // the first step of overlap deduplication: calculate the merged score // for (I = 0; I <RC _. size (); I ++) {// Add the rectangle frame rect r = RC _ [I]; Found_filtered.push_back (r);} vector <float> found_score (found_filtered.size (); // rectangular box score for (I = 0; I <found_filtered.size (); I ++) {rect r = found_filtered [I]; ///////////////////// cvsetimageroi (imageorigin, r); iplimage * test = cvcreateimage (cvgetsize (imageorigin), 8, 3); cvcopyimage (imageorigin, test); cvresetimageroi (imageorigin); iplimage * testtempimg = cvcreateimage (cvsize ), 8, 3); cvzero (Testtempimg); cvresize (test, testtempimg); hog-> compute (testtempimg, descriptors, size (1, 1), size (0, 0 )); // hog feature calculation mat another (descriptors); descriptors. clear (); double ret = 0; ret = ssvm. get_calc_liner (vec_count, var_count, A, another, results, Alpha, 0)-rock; cvreleaseimage (& Test); cvreleaseimage (& testtempimg); found_score [I] = ret; /// // step 2: the part in the rectangle frame, with the highest score /////////////////// ////// Found_filtered is the rectangular frame after the fusion ////////////////////////// for (I = 0; I <found_filtered.size (); I ++) {// deduplication is performed, and the rect r = found_filtered [I]; for (j = 0; j <RC _. size (); j ++) if (J! = I & (R & found_filtered [J]). area () = R. area () {// here is the overlapping part. The weight of the rectangle frame with a small score is set to-1. To obtain the maximum value if (found_score [I]> found_score [J]) {found_score [J] =-1; break;} else {found_score [I] =-1; break ;}}} ////// overlap deduplication Step 3: overlap, //////////////////////////////////// /// // for (I = 0; I <found_filtered.size (); I ++) {// rect r = found_filtered [I]; for (j = 0; j <RC _. size (); j ++) // determines Whether the coincidence rate is greater than 70% of the area (this ratio is to be tested) // The result is filtered in the previous step. If (J! = I & (R & found_filtered [J]). Area ()> = R. Area () * 0.7 & found_score [J]! =-1 & found_score [I]! =-1) {// here is the overlapping part. The weight of the rectangle frame with a small score is set to-1 If (found_score [I]> found_score [J]). {found_score [J] =-1; break;} else {found_score [I] =-1; break ;}}for (INT I = 0; I <found_filtered.size (); I ++) {If (found_score [I] =-1) // filter out {continue;} rect r = found_filtered [I]; R. x-= cvround (R. width * 0.05); R. width = cvround (R. width * 1.05); R. y-= cvround (R. height * 0.05); R. height = cvround (R. height * 1.05); rectangle (img_dst, R. tl (), R. BR (), CV: Scalar (0,255, 0), 2); // draw a rectangular box on the image}/* --------------------- meanshift for local (source program is global) ------------------------ * // meanshift integrates class meanshiftgrouping {public: // meanshiftgrouping msgrouping (smothing, hits, rectlist, hitweights, 1e-5, 100 ); // get ///////////////////////////////////// /// // msgrouping. getmodes (resulthits, resultweights, 1 ); ///////////////////////////////// /// // Meanshiftgrouping (const point3d & densker, const vector <point3d> & posv, const vector <rect> & list, const vector <double> & WV, double EPS, int maxiter = 20) {densitykernel = densker; weightsv = WV; positionsv = posv; positionscount = (INT) posv. size (); meanshiftv. resize (positionscount); distancev. resize (positionscount); itermax = maxiter; modeeps = EPS; For (unsigned I = 0; I <p Ositionsv. Size (); I ++) {meanshiftv [I] = getnewvalue (positionsv [I], list [I], list); // positionv only has the midpoint coordinate and does not have the length and width. Distancev [I] = movetomode (meanshiftv [I], list [I], list ); // The maximum itermax cycle // The meanshiftv [I]-= positionsv [I] value after the mean drift; /This step is not followed by} void getmodes (vector <point3d> & modesv, vector <double> & resweightsv, const double EPS) {for (size_t I = 0; I <distancev. size (); I ++) {bool is_found = false; For (size_t J = 0; j <modesv. size (); j ++) {If (getdistance (distancev [I], modesv [J]) <EPS) // The Euclidean distance is less than the threshold {is_found = true; break;} If (! Is_found) {modesv. push_back (distancev [I]); // Add a point with a large distance, that is, the distance between the two points is large, not the same rectangle.} resweightsv. resize (modesv. size (); For (size_t I = 0; I <modesv. size (); I ++) {resweightsv [I] = getresultweight (modesv [I]); // obtain the vertex weight} protected: vector <point3d> positionsv; vector <double> weightsv; point3d densitykernel; int positionscount; vector <point3d> meanshiftv; vector <point3d> distancev; int itermax; double modeeps; point3d getnewvalue (const point3d & inpt, const rect INR, const vector <rect> List) const {// The 3D coordinates of inpt input and the list of rectangles of INR input are all point3d respoint (. 0); point3d ratpoint (. 0); int value = 20; // only the points with the difference between the four corners of the rectangle box smaller than 20 can be set for (size_t I = 0; I <positionsv. size (); I ++) {point3d apt = positionsv [I]; // double rate = exp (apt. z); If (INR. x-list [I]. x> value | INR. y-list [I]. y> value | INR. width-list [I]. width> value | INR. height-list [I]. height> value) continue; // local judgment. If not near the same rectangle, the effect of the nearby rectangle on point3d BPT = inpt; point3d SPT = densitykernel will be excluded; // core ///////////////////////////////////// /// SPT. x * = exp (apt. z); // Z is the scale SPT. y * = exp (apt. z); apt. x/= SPT. x; apt. y/= SPT. y; apt. z/= SPT. z; BPT. x/= SPT. x; BPT. y/= SPT. y; BPT. z/= SPT. z; /// map the coordinates of the image to the corresponding scale ////// SPT is scale // inverse normalization ///////////// //// // double W = (weightsv [I]) * STD: exp (-(APT-BPT ). DOT (APT-BPT)/2)/STD: SQRT (SPT. DOT (point3d (, 1); // recalculates the weight. The original weight weightsv [I] is the linear SVM score respoint + = W * apt; // Add the corresponding weight based on the distance from the center. The closer the distance is, the greater the weight, the greater the ratpoint. X + = W/SPT. x; // divide the weight value here to reduce the scaled image weight by ratpoint. Y + = W/SPT. y; ratpoint. Z + = W/SPT. z;} respoint. x/= ratpoint. x; respoint. y/= ratpoint. y; respoint. z/= ratpoint. z; return respoint; // return the value affected by the surrounding vertex} double getresultweight (const point3d & inpt) const {double sumw = 0; // The final returned value int num = 0; size_t AA = positionsv. size (); // Number of position points int Len = int (AA); // Number of position points for (size_t I = 0; I <AA; I ++) {point3d apt = positionsv [I]; point3d SPT = densitykernel; SPT. x * = exp (apt. z); SPT. y * = exp (apt. z); Apt-= inpt; // tell the difference between coordinates apt. x/= SPT. x; apt. y/= SPT. y; apt. z/= SPT. z;/* ----------------- this item can also be optimized. For policy consideration, select the weight -- begin ----------------- */If (AA> 10) // if the number of AA exceeds the hour {double Mm = apt. DOT (APT); If (apt. DOT (APT) <= 0.5) // Euclidean distance between the two points {If (weightsv [I]> 0.6) // The weight of weightsv [I] is {sumw + = 0.35;} else if (weightsv [I]> 0.3) {sumw + = 0.3;} continue ;} /// // sumw + = (weightsv [I]) * STD: exp (-(apt. DOT (APT)/2)/STD: SQRT (SPT. DOT (point3d (1, 1 ))); //////////////////////////////////////// //} else {// sumw + = weightsv [I]; sumw + = (weightsv [I]) * STD: exp (-(apt. DOT (APT)/2) * 2.8;}/* --------- part to be optimized ----------------- * // * ------ this part can also be optimized and the policy is considered, select the weight -- end ------ */return sumw; // calculate the final weight} point3d movetomode (point3d apt, rect INR, const vector <rect> List) const {// position after Mean Shift point3d BPT; For (INT I = 0; I <itermax; I ++) {BPT = apt; Apt = getnewvalue (BPT, INR, list); If (getdistance (APT, BPT) <= modeeps) // If the returned value is smaller than the threshold, it indicates that the returned value is in the stable state {break ;}} return apt; // return the value of the stable state} double getdistance (point3d P1, point3d P2) const {// calculate the Euclidean distance point3d NS = densitykernel; NS. x * = exp (p2.z); NS. y * = exp (p2.z); P2-= p1; p2.x/= NS. x; p2.y/= NS. y; p2.z/= NS. z; return p2.dot (P2) ;}}; void grouprectangles_meanshift2 (vector <rect> & rectlist, double detectthreshold, vector <double> * foundweights, vector <double> & scales, size windetsize) // it is called by grouprectangles_meanshift1 {int detectioncount = (INT) rectlist. size (); // Number of rectangles vector <point3d> hits (detectioncount), resulthits; vector <double> hitweights (detectioncount), resultweights; point2d hitcenter; for (INT I = 0; I <detectioncount; I ++) {hitweights [I] = (* foundweights) [I]; hitcenter = (rectlist [I]. tl () + rectlist [I]. BR () * (0.5); // center of rectangleshits [I] = point3d (hitcenter. x, hitcenter. y, STD: log (scales [I]); // center coordinate X, Y, log (scale)} If (foundweights) foundweights-> clear (); double logz = STD: log (1.3); point3d smothing (8, 16, logz); meanshiftgrouping msgrouping (smothing, hits, rectlist, hitweights, 1e-5, 100 ); // get ///////////////////////////////////// //// // msgrouping. getmodes (resulthits, resultweights, 1 ); //////////////////////////////////////// /// // rectlist. clear (); For (unsigned I = 0; I <resulthits. size (); ++ I) {double scale = exp (resulthits [I]. z); // restore the hitcenter scale. X = resulthits [I]. x; // The Center Coordinate hitcenter. y = resulthits [I]. y; Size S (INT (windetsize. width * scale), INT (windetsize. height * scale); // restore the window size rect resultrect (INT (hitcenter. x-s.width/2), INT (hitcenter. y-s.height/2), INT (S. width), INT (S. height); // restore the position of the window if (resultweights [I]> detectthreshold) // output the weight value output when detectthreshold is greater than the threshold {// return the Rectangular Box and the rectlist of the weight value. push_back (resultrect); foundweights-> push_back (resultweights [I]) ;}} void grouprectangles_meanshift1 (vector <rect> & rectlist, vector <double> & foundweights, vector <double> & foundscales, double detectthreshold, size windetsize) {values (rectlist, records, & foundweights, foundscales, windetsize); // rectlist rectangular list, threshold, foundweights, score, foundscales scale, windetsize window size}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.