//Main function int main(int argc, char* argv[]) { if (argc != 2) { std::cout << "Usage: colorcanny image" << std::endl; return(0); } //CImg for output cimg_library::CImg <unsigned char> image(argv[1]); cimg_library::CImg <unsigned char> image_copy(image.width(), image.height(), image.depth(), image.spectrum()); cimg_library::CImg <unsigned char> image_qwaf(image.width(), image.height(), image.depth(), image.spectrum()); cimg_library::CImg <unsigned char> sobel(image.width(), image.height(), image.depth(), image.spectrum()); cimg_library::CImg <unsigned char> sobel_dir(image.width(), image.height(), image.depth(), image.spectrum()); cimg_library::CImg <unsigned char> nms_image(image.width(), image.height(), image.depth(), image.spectrum()); cimg_library::CImg <unsigned char> nms_image_dir(image.width(), image.height(), image.depth(), image.spectrum()); //Do a copy for testing for (int x=0; x<image.width(); x++) { for (int y=0; y<image.height(); y++) { unsigned char col[] = {image(x,y,0,0), image(x,y,0,1), image(x,y,0,2)}; image_copy.draw_point(x,y,col); } } applyQWAF(image, image_qwaf); image_qwaf.save("image_qwaf.bmp"); //Copy to see if everything is working properly image_copy.save("image_copy.bmp"); //Apply a gaussian blur image.blur(1.6); //Vectors std::vector<unsigned char> magnitude; std::vector<unsigned char> nms; std::vector<float> direction; //Apply the sobel operator to the image and then non-maximum supression sobelOperator(image, magnitude, direction); NMS(nms, magnitude, direction, image.width(), image.height()); //Write the magnitude and direction out to images writeMagnitude(sobel, magnitude); writeMagnitudeDirection(sobel_dir, magnitude, direction); writeMagnitude(nms_image, nms); writeMagnitudeDirection(nms_image_dir, nms, direction); //Write the images out to files sobel.save("sobel.bmp"); sobel_dir.save("sobel_direction.bmp"); nms_image.save("non_maxima.bmp"); nms_image_dir.save("non_maxima_dir.bmp"); //Return successful return 0; }
void DetectMTCNN::Process_net_p(const float *data, const VecInt &in_shape, float threshold, float scale, VecBoxInfo *boxes) { std::map<std::string, float *> data_map; std::map<std::string, VecInt> shape_map; data_map[in_p_str_] = const_cast<float *>(data); shape_map[in_p_str_] = in_shape; net_p_.Forward(data_map, shape_map); const auto &loc_shape = net_p_.GetBlobShapeByName<float>(net_p_conv4_2_); const auto *loc_data = net_p_.GetBlobDataByName<float>(net_p_conv4_2_); const auto *conf_data = net_p_.GetBlobDataByName<float>(net_p_prob1_); int out_h = loc_shape[2], out_w = loc_shape[3]; int out_spatial_dim = out_h * out_w; boxes->clear(); for (int i = 0; i < out_spatial_dim; ++i) { int h = i / out_w, w = i % out_w; float conf = conf_data[out_spatial_dim + i]; if (conf > threshold) { float x_min = (net_p_stride_ * h) / scale; float y_min = (net_p_stride_ * w) / scale; float x_max = (net_p_stride_ * h + net_p_cell_size_ - 1) / scale; float y_max = (net_p_stride_ * w + net_p_cell_size_ - 1) / scale; BoxF box(x_min, y_min, x_max, y_max); BoxInfo box_info; box_info.box = box; box_info.box.score = conf; box_info.box.label = 1; for (int k = 0; k < 4; ++k) { box_info.box_reg[k] = loc_data[k * out_spatial_dim + i]; } boxes->push_back(box_info); } } *boxes = NMS(*boxes, 0.5); }
//! 使用非极大值抑制的车牌判断 int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, int maxPlates) { std::vector<CPlate> plateVec; int num = inVec.size(); bool outputResult = false; bool useCascadeJudge = true; bool useShirkMat = true; for (int j = 0; j < num; j++) { CPlate plate = inVec[j]; Mat inMat = plate.getPlateMat(); int result = plateSetScore(plate); if (result == 0) { if (0) { imshow("inMat", inMat); waitKey(0); destroyWindow("inMat"); } int w = inMat.cols; int h = inMat.rows; Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8)); Mat tmpDes = inMat.clone(); resize(tmpmat, tmpDes, Size(inMat.size())); plate.setPlateMat(tmpDes); if (useCascadeJudge) { int resultCascade = plateSetScore(plate); if (resultCascade == 0) { if (0) { imshow("inMat", inMat); waitKey(0); destroyWindow("inMat"); } plateVec.push_back(plate); } } else { plateVec.push_back(plate); } } //if (result == 0) { // plateVec.push_back(plate); // if (outputResult) { // std::stringstream ss(std::stringstream::in | std::stringstream::out); // ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_" // << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_" // << plate.getPlateScore() << ".jpg"; // imwrite(ss.str(), inMat); // } //} //else { // int w = inMat.cols; // int h = inMat.rows; // //再取中间部分判断一次 // Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8)); // Mat tmpDes = inMat.clone(); // resize(tmpmat, tmpDes, Size(inMat.size())); // plate.setPlateMat(tmpDes); // int resultCascade = plateSetScore(plate); // if (resultCascade == 0) { // plateVec.push_back(plate); // if (outputResult) { // std::stringstream ss(std::stringstream::in | std::stringstream::out); // ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_" // << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_" // << plate.getPlateScore() << ".jpg"; // imwrite(ss.str(), tmpDes); // } // } // else { // if (outputResult) { // std::stringstream ss(std::stringstream::in | std::stringstream::out); // ss << "resources/image/tmp/plate/no" << "/" << plate.getPlatePos().center << "_" // << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_" // << plate.getPlateScore() << ".jpg"; // imwrite(ss.str(), tmpDes); // } // } //} } std::vector<CPlate> reDupPlateVec; // 使用非极大值抑制来去除那些重叠的车牌 // overlap阈值设置为0.5 double overlap = 0.5; NMS(plateVec, reDupPlateVec, overlap); std::vector<CPlate>::iterator it = reDupPlateVec.begin(); int count = 0; for (; it != reDupPlateVec.end(); ++it) { resultVec.push_back(*it); if (0) { imshow("plateMat", it->getPlateMat()); waitKey(0); destroyWindow("plateMat"); } count++; if (count >= maxPlates) break; } return 0; }
void ncp_pathsearch(NonlinearComplementarityProblem* problem, double* z, double* F, int *info , SolverOptions* options) { /* Main step of the algorithm: * - compute jacobians * - call modified lemke */ unsigned int n = problem->n; unsigned int preAlloc = options->iparam[SICONOS_IPARAM_PREALLOC]; int itermax = options->iparam[SICONOS_IPARAM_MAX_ITER]; double merit_norm = 1.0; double nn_tol = options->dparam[SICONOS_DPARAM_TOL]; int nbiter = 0; /* declare a LinearComplementarityProblem on the stack*/ LinearComplementarityProblem lcp_subproblem; lcp_subproblem.size = n; /* do some allocation if required * - nabla_F (used also as M for the LCP subproblem) * - q for the LCP subproblem * * Then fill the LCP subproblem */ if (!preAlloc || (preAlloc && !options->internalSolvers)) { options->internalSolvers = (SolverOptions *) malloc(sizeof(SolverOptions)); solver_options_set(options->internalSolvers, SICONOS_LCP_PIVOT); options->numberOfInternalSolvers = 1; SolverOptions * lcp_options = options->internalSolvers; /* We always allocation once and for all since we are supposed to solve * many LCPs */ lcp_options->iparam[SICONOS_IPARAM_PREALLOC] = 1; /* set the right pivot rule */ lcp_options->iparam[SICONOS_IPARAM_PIVOT_RULE] = SICONOS_LCP_PIVOT_PATHSEARCH; /* set the right stacksize */ lcp_options->iparam[SICONOS_IPARAM_PATHSEARCH_STACKSIZE] = options->iparam[SICONOS_IPARAM_PATHSEARCH_STACKSIZE]; } assert(problem->nabla_F); lcp_subproblem.M = problem->nabla_F; if (!preAlloc || (preAlloc && !options->dWork)) { options->dWork = (double *) malloc(4*n*sizeof(double)); } lcp_subproblem.q = options->dWork; double* x = &options->dWork[n]; double* x_plus = &options->dWork[2*n]; double* r = &options->dWork[3*n]; NMS_data* data_NMS; functions_LSA* functions; if (!preAlloc || (preAlloc && !options->solverData)) { options->solverData = malloc(sizeof(pathsearch_data)); pathsearch_data* solverData = (pathsearch_data*) options->solverData; /* do all the allocation */ solverData->data_NMS = create_NMS_data(n, NM_DENSE, options->iparam, options->dparam); solverData->lsa_functions = (functions_LSA*) malloc(sizeof(functions_LSA)); solverData->data_NMS->set = malloc(sizeof(positive_orthant)); data_NMS = solverData->data_NMS; functions = solverData->lsa_functions; /* for use in NMS; only those 3 functions are called */ init_lsa_functions(functions, &FB_compute_F_ncp, &ncp_FB); functions->compute_H = &FB_compute_H_ncp; set_set_id(data_NMS->set, SICONOS_SET_POSITIVE_ORTHANT); /* fill ls_data */ data_NMS->ls_data->compute_F = functions->compute_F; data_NMS->ls_data->compute_F_merit = functions->compute_F_merit; data_NMS->ls_data->z = NULL; /* XXX to check -- xhub */ data_NMS->ls_data->zc = NMS_get_generic_workV(data_NMS->workspace, n); data_NMS->ls_data->F = NMS_get_F(data_NMS->workspace, n); data_NMS->ls_data->F_merit = NMS_get_F_merit(data_NMS->workspace, n); data_NMS->ls_data->desc_dir = NMS_get_dir(data_NMS->workspace, n); /** \todo this value should be settable by the user with a default value*/ data_NMS->ls_data->alpha_min = fmin(data_NMS->alpha_min_watchdog, data_NMS->alpha_min_pgrad); data_NMS->ls_data->data = (void*)problem; data_NMS->ls_data->set = data_NMS->set; data_NMS->ls_data->sigma = options->dparam[SICONOS_DPARAM_NMS_SIGMA]; /* data_NMS->ls_data->searchtype is set in the NMS code */ } else { pathsearch_data* solverData = (pathsearch_data*) options->solverData; data_NMS = solverData->data_NMS; functions = solverData->lsa_functions; } /* initial value for ref_merit */ problem->compute_F(problem->env, n, z, F); functions->compute_F_merit(problem, z, F, data_NMS->ls_data->F_merit); data_NMS->ref_merit = .5 * cblas_ddot(n, data_NMS->ls_data->F_merit, 1, data_NMS->ls_data->F_merit, 1); data_NMS->merit_bestpoint = data_NMS->ref_merit; cblas_dcopy(n, z, 1, NMS_checkpoint_0(data_NMS, n), 1); cblas_dcopy(n, z, 1, NMS_checkpoint_T(data_NMS, n), 1); cblas_dcopy(n, z, 1, NMS_bestpoint(data_NMS, n), 1); /* -------------------- end init ---------------------------*/ int nms_failed = 0; double err = 10*nn_tol; /* to check the solution */ LinearComplementarityProblem lcp_subproblem_check; int check_lcp_solution = 1; /* XXX add config for that */ double normal_norm2_newton_point; /* F is already computed here at z */ while ((err > nn_tol) && (nbiter < itermax) && !nms_failed) { int force_watchdog_step = 0; int force_d_step_merit_check = 0; double check_ratio = 0.0; nbiter++; /* update M, q and r */ /* First find x */ ncp_pathsearch_compute_x_from_z(n, z, F, x); pos_part(n, x, x_plus); /* update x_plus */ ncp_pathsearch_update_lcp_data(problem, &lcp_subproblem, n, x_plus, x, r); if (check_lcp_solution) { lcp_subproblem_check.size = n; lcp_subproblem_check.M = problem->nabla_F; lcp_subproblem_check.q = lcp_subproblem.q; //cblas_dcopy(n, x, 1, lcp_subproblem_check.q , 1); //prodNumericsMatrix(n, n, -1.0, problem->nabla_F, x_plus, 0.0, lcp_subproblem.q); } double norm_r2 = cblas_ddot(n, r, 1, r, 1); if (norm_r2 < DBL_EPSILON*DBL_EPSILON) /* ||r|| < 1e-15 */ { DEBUG_PRINTF("ncp_pathsearch :: ||r|| = %e < %e; path search procedure was successful!\n", norm_r2, DBL_EPSILON*DBL_EPSILON); (*info) = 0; ncp_compute_error(n, z, F, nn_tol, &err); /* XXX F should be up-to-date, we should check only CC*/ break; } /* end update M, q and r */ lcp_pivot_covering_vector(&lcp_subproblem, x_plus, x, info, options->internalSolvers, r); switch (*info) { case LCP_PIVOT_SUCCESS: DEBUG_PRINT("ncp_pathsearch :: path search procedure was successful!\n"); if (check_lcp_solution) { double err_lcp = 0.0; cblas_daxpy(n, 1.0, r, 1, lcp_subproblem_check.q, 1); lcp_compute_error(&lcp_subproblem_check, x_plus, x, 1e-14, &err_lcp); double local_tol = fmax(1e-14, DBL_EPSILON*sqrt(norm_r2)); printf("ncp_pathsearch :: lcp solved with error = %e; local_tol = %e\n", err_lcp, local_tol); //assert(err_lcp < local_tol && "ncp_pathsearch :: lcp solved with very bad precision"); if (err_lcp > local_tol) { printf("ncp_pathsearch :: lcp solved with very bad precision\n"); NM_display(lcp_subproblem.M); printf("z r q x_plus\n"); for (unsigned i = 0; i < n; ++i) printf("%e %e %e %e\n", z[i], r[i], lcp_subproblem.q[i], x_plus[i]); options->internalSolvers->iparam[SICONOS_IPARAM_PIVOT_RULE] = 0; lcp_pivot(&lcp_subproblem, x_plus, x, info, options->internalSolvers); options->internalSolvers->iparam[SICONOS_IPARAM_PIVOT_RULE] = SICONOS_LCP_PIVOT_PATHSEARCH; lcp_compute_error(&lcp_subproblem_check, x_plus, x, 1e-14, &err_lcp); printf("ncp_pathsearch :: lcp resolved with error = %e; local_tol = %e\n", err_lcp, local_tol); } /* XXX missing recompute x ?*/ /* recompute the normal norm */ problem->compute_F(problem->env, n, x_plus, r); cblas_daxpy(n, -1.0, x, 1, r, 1); normal_norm2_newton_point = cblas_ddot(n, r, 1, r, 1); if (normal_norm2_newton_point > norm_r2) { printf("ncp_pathsearch :: lcp successfully solved, but the norm of the normal map increased! %e > %e\n", normal_norm2_newton_point, norm_r2); //assert(normal_norm2_newton_point <= norm_r2); } else { printf("ncp_pathsearch :: lcp successfully solved, norm of the normal map decreased! %e < %e\n", normal_norm2_newton_point, norm_r2); //check_ratio = norm_r2/normal_norm2_newton_point; } if (50*normal_norm2_newton_point < norm_r2) { force_d_step_merit_check = 1; } else if (10*normal_norm2_newton_point < norm_r2) { // check_ratio = sqrt(norm_r2/normal_norm2_newton_point); } } break; case LCP_PIVOT_RAY_TERMINATION: DEBUG_PRINT("ncp_pathsearch :: ray termination, let's fastened your seat belt!\n"); break; case LCP_PATHSEARCH_LEAVING_T: DEBUG_PRINT("ncp_pathsearch :: leaving t, fastened your seat belt!\n"); DEBUG_PRINTF("ncp_pathsearch :: max t value = %e\n", options->internalSolvers->dparam[2]); /* XXX fix 2 */ /* try to retry solving the problem */ /* XXX keep or not ? */ /* recompute the normal norm */ problem->compute_F(problem->env, n, x_plus, r); cblas_daxpy(n, -1.0, x, 1, r, 1); normal_norm2_newton_point = cblas_ddot(n, r, 1, r, 1); if (normal_norm2_newton_point > norm_r2) { printf("ncp_pathsearch :: lcp successfully solved, but the norm of the normal map increased! %e > %e\n", normal_norm2_newton_point, norm_r2); //assert(normal_norm2_newton_point <= norm_r2); } else { printf("ncp_pathsearch :: lcp successfully solved, norm of the normal map decreased! %e < %e\n", normal_norm2_newton_point, norm_r2); check_ratio = 5.0*norm_r2/normal_norm2_newton_point; } if (options->internalSolvers->dparam[2] > 1e-5) break; memset(x_plus, 0, sizeof(double) * n); problem->compute_F(problem->env, n, x_plus, r); ncp_pathsearch_compute_x_from_z(n, x_plus, r, x); ncp_pathsearch_update_lcp_data(problem, &lcp_subproblem, n, x_plus, x, r); lcp_pivot_covering_vector(&lcp_subproblem, x_plus, x, info, options->internalSolvers, r); if (*info == LCP_PIVOT_SUCCESS) { DEBUG_PRINT("ncp_pathsearch :: Lemke start worked !\n"); double err_lcp = 0.0; cblas_daxpy(n, 1.0, r, 1, lcp_subproblem_check.q, 1); lcp_compute_error(&lcp_subproblem_check, x_plus, x, 1e-14, &err_lcp); double local_tol = fmax(1e-14, DBL_EPSILON*sqrt(norm_r2)); printf("ncp_pathsearch :: lcp solved with error = %e; local_tol = %e\n", err_lcp, local_tol); assert(err_lcp < local_tol); } else { NM_display(lcp_subproblem.M); printf("z r q x_plus\n"); for (unsigned i = 0; i < n; ++i) printf("%e %e %e %e\n", z[i], r[i], lcp_subproblem.q[i], x_plus[i]); DEBUG_PRINT("ncp_pathsearch :: Lemke start did not succeeded !\n"); lcp_pivot_diagnose_info(*info); if (*info == LCP_PATHSEARCH_LEAVING_T) { DEBUG_PRINTF("ncp_pathsearch :: max t value after Lemke start = %e\n", options->internalSolvers->dparam[2]); } options->internalSolvers->iparam[SICONOS_IPARAM_PIVOT_RULE] = 0; lcp_pivot(&lcp_subproblem, x_plus, x, info, options->internalSolvers); options->internalSolvers->iparam[SICONOS_IPARAM_PIVOT_RULE] = SICONOS_LCP_PIVOT_PATHSEARCH; double err_lcp = 0.0; lcp_compute_error(&lcp_subproblem, x_plus, x, 1e-14, &err_lcp); printf("ncp_pathsearch :: lemke start resolved with info = %d; error = %e\n", *info, err_lcp); printf("x_plus x_minus\n"); for (unsigned i = 0; i < n; ++i) printf("%e %e\n", x_plus[i], x[i]); /* recompute the normal norm */ problem->compute_F(problem->env, n, x_plus, r); cblas_daxpy(n, -1.0, x, 1, r, 1); double normal_norm2_newton_point = cblas_ddot(n, r, 1, r, 1); if (normal_norm2_newton_point > norm_r2) { printf("ncp_pathsearch :: lcp successfully solved, but the norm of the normal map increased! %e > %e\n", normal_norm2_newton_point, norm_r2); //assert(normal_norm2_newton_point <= norm_r2); } else { printf("ncp_pathsearch :: lcp successfully solved, norm of the normal map decreased! %.*e < %.*e\n", DECIMAL_DIG, normal_norm2_newton_point, DECIMAL_DIG, norm_r2); } if (100*normal_norm2_newton_point < norm_r2) { force_d_step_merit_check = 1; } } break; case LCP_PIVOT_NUL: printf("ncp_pathsearch :: kaboom, kaboom still more work needs to be done\n"); lcp_pivot_diagnose_info(*info); // exit(EXIT_FAILURE); force_watchdog_step = 1; break; case LCP_PATHSEARCH_NON_ENTERING_T: DEBUG_PRINT("ncp_pathsearch :: non entering t, something is wrong here. Fix the f****** code!\n"); assert(0 && "ncp_pathsearch :: non entering t, something is wrong here\n"); force_watchdog_step = 1; break; default: printf("ncp_pathsearch :: unknown code returned by the path search\n"); exit(EXIT_FAILURE); } nms_failed = NMS(data_NMS, problem, functions, z, x_plus, force_watchdog_step, force_d_step_merit_check, check_ratio); /* at this point z has been updated */ /* recompute the normal norm */ problem->compute_F(problem->env, n, z, F); functions->compute_F_merit(problem, z, F, data_NMS->ls_data->F_merit); /* XXX is this correct ? */ merit_norm = .5 * cblas_ddot(n, data_NMS->ls_data->F_merit, 1, data_NMS->ls_data->F_merit, 1); ncp_compute_error(n, z, F, nn_tol, &err); /* XXX F should be up-to-date, we should check only CC*/ DEBUG_PRINTF("ncp_pathsearch :: iter = %d, ncp_error = %e; merit_norm^2 = %e\n", nbiter, err, merit_norm); } options->iparam[1] = nbiter; options->dparam[1] = err; if (nbiter == itermax) { *info = 1; } else if (nms_failed) { *info = 2; } else { *info = 0; } DEBUG_PRINTF("ncp_pathsearch procedure finished :: info = %d; iter = %d; ncp_error = %e; merit_norm^2 = %e\n", *info, nbiter, err, merit_norm); if (!preAlloc) { freeNumericsMatrix(problem->nabla_F); free(problem->nabla_F); problem->nabla_F = NULL; free(options->dWork); options->dWork = NULL; solver_options_delete(options->internalSolvers); free(options->internalSolvers); options->internalSolvers = NULL; free_NMS_data(data_NMS); free(functions); free(options->solverData); options->solverData = NULL; } }
void DetectMTCNN::Predict(const JImage &im_src, const RectF &roi, VecBoxF *boxes, std::vector<VecPointF> *Gpoints) { boxes->clear(), Gpoints->clear(); net_p_boxes_.clear(), net_r_boxes_.clear(), net_o_boxes_.clear(); float crop_h = roi.h <= 1 ? roi.h * im_src.h_ : roi.h; float crop_w = roi.w <= 1 ? roi.w * im_src.w_ : roi.w; CalculateScales(crop_h, crop_w, factor_, max_side_, min_side_, &scales_); for (auto scale : scales_) { auto scale_h = static_cast<int>(std::ceil(crop_h * scale)); auto scale_w = static_cast<int>(std::ceil(crop_w * scale)); net_p_in_shape_[2] = scale_w, net_p_in_shape_[3] = scale_h; net_p_in_data_.resize(1 * 3 * scale_w * scale_h); ConvertData(im_src, net_p_in_data_.data(), roi, 3, scale_h, scale_w, 1, true); VecBoxInfo boxes_p; Process_net_p(net_p_in_data_.data(), net_p_in_shape_, thresholds_[0], scale, &boxes_p); net_p_boxes_.insert(net_p_boxes_.end(), boxes_p.begin(), boxes_p.end()); } net_p_boxes_ = NMS(net_p_boxes_, 0.7); BoxRegression(net_p_boxes_); Box2SquareWithConstrain(net_p_boxes_, crop_h, crop_w); if (net_p_boxes_.empty()) { return; } net_r_in_shape_[0] = static_cast<int>(net_p_boxes_.size()); net_r_in_data_.resize(net_r_in_shape_[0] * net_r_in_num_); for (int n = 0; n < net_p_boxes_.size(); ++n) { const auto &net_12_box = net_p_boxes_[n].box; ConvertData(im_src, net_r_in_data_.data() + n * net_r_in_num_, net_12_box.RectFloat(), net_r_in_c_, net_r_in_h_, net_r_in_w_, 1, true); } Process_net_r(net_r_in_data_.data(), net_r_in_shape_, thresholds_[1], net_p_boxes_, &net_r_boxes_); net_r_boxes_ = NMS(net_r_boxes_, 0.7); BoxRegression(net_r_boxes_); Box2SquareWithConstrain(net_r_boxes_, crop_h, crop_w); if (net_r_boxes_.empty()) { return; } net_o_in_shape_[0] = static_cast<int>(net_r_boxes_.size()); net_o_in_data_.resize(net_o_in_shape_[0] * net_o_in_num_); for (int n = 0; n < net_r_boxes_.size(); ++n) { const auto &net_24_box = net_r_boxes_[n].box; ConvertData(im_src, net_o_in_data_.data() + n * net_o_in_num_, net_24_box.RectFloat(), net_o_in_c_, net_o_in_h_, net_o_in_w_, 1, true); } Process_net_o(net_o_in_data_.data(), net_o_in_shape_, thresholds_[2], net_r_boxes_, &net_o_boxes_); BoxRegression(net_o_boxes_); net_o_boxes_ = NMS(net_o_boxes_, 0.7, true); BoxWithConstrain(net_o_boxes_, crop_h, crop_w); for (const auto &box_info : net_o_boxes_) { boxes->push_back(box_info.box); VecPointF mark_points; for (int k = 0; k < 5; ++k) { mark_points.emplace_back(box_info.landmark[2 * k], box_info.landmark[2 * k + 1]); } Gpoints->push_back(mark_points); } }