utils.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #pragma once
  2. #include <opencv2\imgproc\imgproc.hpp>
  3. #include <vector>
  4. #include <time.h>
  5. #include <string>
  6. #include <numeric>
  7. #include "data_def_api.h"
  8. #include "data_def.h"
  9. using namespace cv;
  10. using namespace std;
  11. namespace graft_cv{
  12. // convert ImgInfo to cv mat
  13. Mat imginfo2mat(ImgInfo*);
  14. ImgInfo* mat2imginfo(const Mat&);
  15. void imginfo_release(ImgInfo**);
  16. bool isvalid(const ImgInfo*);
  17. string currTime();
  18. string getImgId(int im_type);
  19. string getImgIdOa(string iid, int im_idx);
  20. inline void throw_msg(string& msg);
  21. // set bottom image rows_cnt rows to "value", for xiaoxu camera
  22. void image_set_bottom(Mat& img,unsigned char value,int rows_cnt);
  23. void image_set_top( Mat& img, unsigned char value, int rows_cnt);
  24. void image_draw_line(Mat& img,int x0,int y0,int x1,int y1);
  25. // histogram
  26. void mat_histogram(
  27. Mat&,
  28. std::vector<int>&hist,
  29. int axis=0,
  30. int r0=-1,
  31. int r1=-1,
  32. int c0=-1,
  33. int c1=-1
  34. );
  35. // weighted histogram
  36. void mat_histogram_w(
  37. Mat& img,
  38. std::vector<int>&hist,
  39. int axis=0,
  40. int r0=-1,
  41. int r1=-1,
  42. int c0=-1,
  43. int c1=-1,
  44. bool asc_w=true //true---ascending weight with x/y coordinate, [0-1.0], false --- descending weight [1.0--0.0]
  45. );
  46. void mat_histogram_yfork(
  47. Mat& img,
  48. std::vector<int>&hist,
  49. int r0,
  50. int r1
  51. );
  52. // histogram to image
  53. void hist2image(
  54. vector<int>& hist,
  55. Mat&img,
  56. int aix=1,
  57. int grid_col=50,
  58. int grid_row=50
  59. );
  60. template<class T>
  61. void hist2image_line(
  62. vector<T>& hist,
  63. Mat&img,
  64. int grid_col/*=50*/,
  65. int grid_row/*=50*/
  66. )
  67. {
  68. if(hist.size()<2){return;}
  69. vector<T>::iterator maxit = max_element(begin(hist),end(hist));
  70. if( grid_col<10){grid_col=10;}
  71. if( grid_row<10){grid_row=10;}
  72. img = Mat::zeros(*maxit,hist.size(), CV_8UC1);
  73. drawgrid(img,grid_col, grid_row,1);
  74. for(size_t i=1; i<hist.size();++i){
  75. line(img,Point(i-1,(int)*maxit - (int)hist[i-1]),Point(i,(int)*maxit - (int)hist[i]),Scalar(255));
  76. }
  77. };
  78. template<class T>
  79. void hist2image_scale_line(
  80. vector<T>& hist,
  81. Mat&img,
  82. T ymin,
  83. T ymax,
  84. T yratio,//数值像素比,一个像素代表的数值量
  85. T th,
  86. int grid_col/*=50*/,
  87. int grid_row/*=50*/
  88. )
  89. {
  90. if(hist.size()<2){return;}
  91. if( grid_col<10){grid_col=10;}
  92. if( grid_row<10){grid_row=10;}
  93. int height =(int)((ymax-ymin)/yratio);
  94. img = Mat::zeros(height,hist.size(), CV_8UC1);
  95. drawgrid(img,grid_col, grid_row,1);
  96. for(size_t i=1; i<hist.size();++i){
  97. int y_1 = height-(int)((hist[i-1]-ymin)/yratio);
  98. int y_0 = height-(int)((hist[i]-ymin)/yratio);
  99. line(img,Point(i-1,y_1),Point(i,y_0),Scalar(255));
  100. }
  101. int h1 = height-(int)((th-ymin)/yratio);
  102. int h2 = height-(int)((1.0/th-ymin)/yratio);
  103. line(img,Point(0,h1),Point(hist.size()-1,h1),Scalar(200));
  104. line(img,Point(0,h2),Point(hist.size()-1,h2),Scalar(200));
  105. };
  106. void drawgrid(
  107. Mat&img,
  108. int grid_col=50,
  109. int grid_row=50,
  110. int line_thick=1
  111. );
  112. //r2 index calculation for line regression
  113. // y = beta0 + beta1 * x
  114. template<class T>
  115. double r2index(
  116. const vector<T>& x,
  117. const vector<T>& y,
  118. size_t i0,
  119. size_t i1,
  120. double& beta0,
  121. double& beta1)
  122. {
  123. double r2 = 0.0;
  124. assert(x.size() == y.size());
  125. assert(i0<i1);
  126. assert(i1-i0>1);
  127. assert(i0>=0 && i1<y.size());
  128. // y = beta0 + beta1 * x
  129. //double beta0=0, beta1=0;
  130. double t1=0, t2=0,t3=0,t4=0;
  131. double n = (double)(i1-i0+1);
  132. for(size_t i=i0; i<=i1; ++i)
  133. {
  134. t1 += (double)x[i] * (double)x[i];
  135. t2 += (double)x[i];
  136. t3 += (double)x[i] * (double)y[i];
  137. t4 += (double)y[i];
  138. }
  139. beta0 = (t1*t4 - t2*t3) / (t1*n - t2*t2);
  140. beta1 = (t3*n - t2*t4) / (t1*n -t2*t2);
  141. double sst=0, ssr=0, sse=0;
  142. double y_mu = t4/n;
  143. double y_hat;
  144. for(size_t i=i0; i<=i1; ++i)
  145. {
  146. y_hat = beta0 + beta1*(double)x[i];
  147. ssr += (y_hat - y_mu)*(y_hat - y_mu);
  148. sse += ((double)y[i] - y_hat)* ((double)y[i] - y_hat);
  149. }
  150. sst = ssr + sse;
  151. r2 = 1.0 - sse/sst;
  152. return r2;
  153. };
  154. void get_stem_x_range_oa(
  155. const std::vector<int>& hist_h,
  156. double h_ratio,
  157. int padding,
  158. int cent_x,
  159. int width_x,
  160. int&x0,
  161. int&x1,
  162. int&stem_x0,
  163. int&stem_x1
  164. );
  165. void get_stem_x_range_rscut(
  166. const std::vector<int>& hist_h,
  167. double h_ratio,
  168. int padding,
  169. int cent_x,
  170. int width_x,
  171. int&x0,
  172. int&x1,
  173. int&stem_x0,
  174. int&stem_x1
  175. );
  176. void get_stem_x_range_scion(
  177. const std::vector<int>& hist_h,
  178. double h_ratio,
  179. int padding,
  180. int&x0,
  181. int&x1,
  182. int&stem_x0,
  183. int&stem_x1
  184. );
  185. ////////////////////////////////////////////////////////////////////////
  186. // y-fork detect
  187. void get_stem_y_fork(
  188. const std::vector<int>& hist,
  189. double ratio,
  190. int stem_dia_min,
  191. int stem_fork_y_min,
  192. double stem_dia_mp,
  193. int& fork_y, //output, 茎分叉y像素位置
  194. int& end_y, //output,茎根部y像素位置
  195. int& stem_dia //output, end_y和fork_y间茎粗
  196. );
  197. void get_stem_y_fork_rs(
  198. const std::vector<int>& hist,
  199. double ratio,
  200. int stem_dia_min,
  201. int stem_fork_y_min,
  202. double stem_dia_mp,
  203. int& fork_y, //output
  204. int& end_y, //output
  205. int& stem_dia, //output
  206. int& roi_max_y //output
  207. );
  208. void get_stem_y_fork_rs_update(
  209. const Mat& bin_img,
  210. int stem_x_padding,
  211. int x0,
  212. int x1,
  213. int max_y,
  214. int stem_root_y,
  215. int stem_dia,
  216. bool image_show,
  217. double cut_point_offset_ratio,
  218. Point& fork_cent,
  219. double& max_radius,
  220. double& stem_angle
  221. );
  222. double yfork_validity_position(
  223. int max_y,
  224. int end_y,
  225. int fork_y);
  226. double yfork_validity_stemdiaratio(
  227. int stem_dia,
  228. int dia_y,
  229. double opt_dia_ratio);
  230. void yfork_validity_stemdiachange(
  231. const std::vector<int>& hist,
  232. int stem_dia_min,
  233. std::vector<double>& var_ratio
  234. );
  235. //通过计算茎均值,运用统计过程控制方法检测显著点
  236. void get_stem_y_fork_3sigma(
  237. const std::vector<int>& hist,
  238. double ratio,
  239. int stem_dia_min,
  240. int stem_fork_y_min,
  241. double stem_dia_mp,
  242. int& fork_y, //output, 茎分叉y像素位置
  243. int& end_y, //output,茎根部y像素位置
  244. int& stem_dia //output, end_y和fork_y间茎粗
  245. );
  246. double stem_y_fork_validity(
  247. const std::vector<int>& hist,
  248. int fork_y,
  249. int end_y);
  250. void get_hist_segment(
  251. const std::vector<int>& hist,
  252. int threshold,
  253. std::vector<gcv_point<int>>& segments
  254. );
  255. void get_hist_mean_var_local(
  256. const std::vector<int>& hist,
  257. int x0,
  258. int x1,
  259. double& mean,
  260. double& var
  261. );
  262. //void get_stem_y_index(
  263. // Mat& bin_img,
  264. // int x0,
  265. // int x1,
  266. // int stem_dia_min,
  267. // int stem_fork_y_min,
  268. // double stem_dia_mp,
  269. // int& fork_y, //output
  270. // int& end_y, //output
  271. // int& stem_dia //output
  272. //);
  273. void imshow_wait(
  274. const char* winname,
  275. Mat&,
  276. int waittype=-1
  277. );
  278. int get_stem_fork_right(
  279. Mat&stem_img,
  280. int stem_fork_y,
  281. int stem_x0,
  282. int stem_x1,
  283. int detect_window);
  284. int get_stem_fork_left(
  285. Mat&stem_img,
  286. int stem_fork_y,
  287. int stem_x0,
  288. int stem_x1,
  289. int detect_window);
  290. void get_stem_fork_xs(
  291. Mat&stem_img,
  292. int stem_fork_y,
  293. int stem_x0,
  294. int stem_x1,
  295. int x0,
  296. int x1,
  297. int & fork_x0,
  298. int & fork_x1
  299. );
  300. void get_next_pt(
  301. Mat& edge_img,
  302. gcv_point<int>&start_pt,
  303. gcv_point<int>&pre_pt,
  304. gcv_point<int>&nxt_pt, //output
  305. bool is_up=true);
  306. // 二次曲线拟合,返回二次曲线对称轴x的坐标
  307. double qua_fitting(vector<double>&xx, vector<double>&yy);
  308. template <typename T>
  309. vector<size_t> sort_indexes_e(vector<T> &v, bool ascending=true)
  310. {
  311. vector<size_t> idx(v.size());
  312. iota(idx.begin(), idx.end(), 0);
  313. if(ascending){
  314. sort(idx.begin(), idx.end(),
  315. [&v](size_t i1, size_t i2) {return v[i1] < v[i2]; });
  316. }
  317. else{
  318. sort(idx.begin(), idx.end(),
  319. [&v](size_t i1, size_t i2) {return v[i1] > v[i2]; });
  320. }
  321. return idx;
  322. }
  323. template<typename T>
  324. void hist_filter(vector<T>& hist, int method=0, int radius=2)
  325. {
  326. //mothod: 0---mid; 1--mean
  327. assert(radius>=1);
  328. if(hist.size()<3){return;}
  329. vector<T>tmp;
  330. if(method==0){
  331. T* buff = new T[2+2*radius];
  332. for(int i=0; i<hist.size();++i){
  333. int cnt=0;
  334. for(int r = -radius;r<=radius;++r){
  335. int idx=i+r;
  336. if(idx<0 || idx>=hist.size()){continue;}
  337. buff[cnt++]=hist[idx];
  338. }
  339. sort(buff,buff+cnt);
  340. int cent = cnt/2;
  341. tmp.push_back(buff[cent]);
  342. }
  343. delete []buff;
  344. }
  345. if(method==1){
  346. for(int i=0; i<hist.size();++i){
  347. int cnt=0;
  348. T mean = T(0);
  349. for(int r = -radius;r<=radius;++r){
  350. int idx=i+r;
  351. if(idx<0 || idx>=hist.size()){continue;}
  352. mean+=hist[idx];
  353. }
  354. mean =mean/cnt;
  355. tmp.push_back(mean);
  356. }
  357. }
  358. for(size_t j=0;j<hist.size();++j){hist[j]=tmp[j];}
  359. }
  360. };