#pragma once #include #include #include #include #include #include #include "data_def_api.h" #include "data_def.h" //using namespace cv; using namespace std; namespace graft_cv{ // convert ImgInfo to cv mat cv::Mat imginfo2mat(ImgInfo*); ImgInfo* mat2imginfo(const cv::Mat&); void imginfo_release(ImgInfo**); bool isvalid(const ImgInfo*); string currTime(); string getImgId(int im_type); string getImgIdOa(string iid, int im_idx); inline void throw_msg(string& msg); // set bottom image rows_cnt rows to "value", for xiaoxu camera void image_set_bottom(cv::Mat& img,unsigned char value,int rows_cnt); void image_set_top(cv::Mat& img, unsigned char value, int rows_cnt); void image_draw_line(cv::Mat& img,int x0,int y0,int x1,int y1); // histogram void mat_histogram( cv::Mat&, std::vector&hist, int axis=0, int r0=-1, int r1=-1, int c0=-1, int c1=-1 ); // weighted histogram void mat_histogram_w( cv::Mat& img, std::vector&hist, int axis=0, int r0=-1, int r1=-1, int c0=-1, int c1=-1, bool asc_w=true //true---ascending weight with x/y coordinate, [0-1.0], false --- descending weight [1.0--0.0] ); void mat_histogram_yfork( cv::Mat& img, std::vector&hist, int r0, int r1 ); // histogram to image void hist2image( vector& hist, cv::Mat&img, int aix=1, int grid_col=50, int grid_row=50 ); template void hist2image_line( vector& hist, cv::Mat&img, int grid_col/*=50*/, int grid_row/*=50*/ ) { if(hist.size()<2){return;} vector::iterator maxit = max_element(begin(hist),end(hist)); if( grid_col<10){grid_col=10;} if( grid_row<10){grid_row=10;} img = Mat::zeros(*maxit,hist.size(), CV_8UC1); drawgrid(img,grid_col, grid_row,1); for(size_t i=1; i void hist2image_scale_line( vector& hist, cv::Mat&img, T ymin, T ymax, T yratio,//数值像素比,一个像素代表的数值量 T th, int grid_col/*=50*/, int grid_row/*=50*/ ) { if(hist.size()<2){return;} if( grid_col<10){grid_col=10;} if( grid_row<10){grid_row=10;} int height =(int)((ymax-ymin)/yratio); img = cv::Mat::zeros(height,hist.size(), CV_8UC1); drawgrid(img,grid_col, grid_row,1); for(size_t i=1; i double r2index( const vector& x, const vector& y, size_t i0, size_t i1, double& beta0, double& beta1) { double r2 = 0.0; assert(x.size() == y.size()); assert(i01); assert(i0>=0 && i1& hist_h, double h_ratio, int padding, int cent_x, int width_x, int&x0, int&x1, int&stem_x0, int&stem_x1 ); void get_stem_x_range_rscut( const std::vector& hist_h, double h_ratio, int padding, int cent_x, int width_x, int&x0, int&x1, int&stem_x0, int&stem_x1 ); void get_stem_x_range_scion( const std::vector& hist_h, double h_ratio, int padding, int&x0, int&x1, int&stem_x0, int&stem_x1 ); //////////////////////////////////////////////////////////////////////// // y-fork detect void get_stem_y_fork( const std::vector& hist, double ratio, int stem_dia_min, int stem_fork_y_min, double stem_dia_mp, int& fork_y, //output, 茎分叉y像素位置 int& end_y, //output,茎根部y像素位置 int& stem_dia //output, end_y和fork_y间茎粗 ); void get_stem_y_fork_rs( const std::vector& hist, double ratio, int stem_dia_min, int stem_fork_y_min, double stem_dia_mp, int& fork_y, //output int& end_y, //output int& stem_dia, //output int& roi_max_y //output ); void get_stem_y_fork_rs_update( const cv::Mat& bin_img, int stem_x_padding, int x0, int x1, int max_y, int stem_root_y, int stem_dia, bool image_show, double cut_point_offset_ratio, cv::Point& fork_cent, double& max_radius, double& stem_angle ); double yfork_validity_position( int max_y, int end_y, int fork_y); double yfork_validity_stemdiaratio( int stem_dia, int dia_y, double opt_dia_ratio); void yfork_validity_stemdiachange( const std::vector& hist, int stem_dia_min, std::vector& var_ratio ); //通过计算茎均值,运用统计过程控制方法检测显著点 void get_stem_y_fork_3sigma( const std::vector& hist, double ratio, int stem_dia_min, int stem_fork_y_min, double stem_dia_mp, int& fork_y, //output, 茎分叉y像素位置 int& end_y, //output,茎根部y像素位置 int& stem_dia //output, end_y和fork_y间茎粗 ); double stem_y_fork_validity( const std::vector& hist, int fork_y, int end_y); void get_hist_segment( const std::vector& hist, int threshold, std::vector>& segments ); void get_hist_mean_var_local( const std::vector& hist, int x0, int x1, double& mean, double& var ); //void get_stem_y_index( // Mat& bin_img, // int x0, // int x1, // int stem_dia_min, // int stem_fork_y_min, // double stem_dia_mp, // int& fork_y, //output // int& end_y, //output // int& stem_dia //output //); void imshow_wait( const char* winname, cv::Mat&, int waittype=-1 ); int get_stem_fork_right( cv::Mat&stem_img, int stem_fork_y, int stem_x0, int stem_x1, int detect_window); int get_stem_fork_left( cv::Mat&stem_img, int stem_fork_y, int stem_x0, int stem_x1, int detect_window); void get_stem_fork_xs( cv::Mat&stem_img, int stem_fork_y, int stem_x0, int stem_x1, int x0, int x1, int & fork_x0, int & fork_x1 ); void get_next_pt( cv::Mat& edge_img, gcv_point&start_pt, gcv_point&pre_pt, gcv_point&nxt_pt, //output bool is_up=true); // 二次曲线拟合,返回二次曲线对称轴x的坐标 double qua_fitting(vector&xx, vector&yy); template vector sort_indexes_e(vector &v, bool ascending=true) { vector idx(v.size()); iota(idx.begin(), idx.end(), 0); if(ascending){ sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) {return v[i1] < v[i2]; }); } else{ sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) {return v[i1] > v[i2]; }); } return idx; } template void hist_filter(vector& hist, int method=0, int radius=2) { //mothod: 0---mid; 1--mean assert(radius>=1); if(hist.size()<3){return;} vectortmp; if(method==0){ T* buff = new T[2+2*radius]; for(int i=0; i=hist.size()){continue;} buff[cnt++]=hist[idx]; } sort(buff,buff+cnt); int cent = cnt/2; tmp.push_back(buff[cent]); } delete []buff; } if(method==1){ for(int i=0; i=hist.size()){continue;} mean+=hist[idx]; } mean =mean/cnt; tmp.push_back(mean); } } for(size_t j=0;j double otsu(std::vector&data) { if (data.size() == 0) { return 0.0; } std::vectordata_sort(data); std::sort(data_sort.begin(), data_sort.end()); double t0 = data_sort[int(data_sort.size() / 2)]; double t1 = data_sort.back(); double t = t0; double max_g = 0; double max_t = t0; std::vectord0; std::vectord1; double n = data.size(); while (t < t1) { d0.clear(); d1.clear(); for (auto& v : data_sort) { if (v < t) { d0.push_back(v); } else { d1.push_back(v); } } double g = get_hist_mean(d0) - get_hist_mean(d1); g *= g; g = g* d0.size() * d1.size() / n / n; if (g > max_g) { max_g = g; max_t = t; } t += 1; } return max_t; } template double get_hist_mean(std::vector&data) { double mu = 0; for (auto &v : data) { mu += v; } if (data.size() > 0) { mu /= data.size(); } return mu; } template double get_hist_std(std::vector&data, T mu) { double std_v = 0; for (auto &v : data) { std_v += (v-mu)*(v - mu); } if (data.size() > 0) { std_v /= data.size(); std_v = sqrt(std_v); } return std_v; } template int trend_detect_pos(const vector&data, int data_th, int step=15) { int pos = -1; if (data.size() < 2 * step) { return pos; } int radius = int(step/2); boost::math::binomial_distribution<> binomal(radius, 0.5); pos = radius; int max_v = 0; int pos_n, neg_n; for (size_t i = radius; i < data.size() - radius; ++i) { pos_n = neg_n = 0; for (int j = 1; j <= radius; ++j) { int diff = data[i + j] - data[i + j -radius]; if (diff > 0) { pos_n++; } else { neg_n++; } } int k = min(pos_n, neg_n); double p = 2.0 * boost::math::cdf(binomal, k); std::cout <<"idx="<