grab_occlusion.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include <sstream>
  2. #include <opencv2\highgui\highgui.hpp>
  3. #include "grab_occlusion.h"
  4. namespace graft_cv {
  5. CStemResultInfos::CStemResultInfos(double seedling_dist,
  6. int holes_number,
  7. double x_min,
  8. double x_max,
  9. double z_min,
  10. double z_max,
  11. std::string pcd_id,
  12. CGcvLogger*pLog)
  13. : m_pLogger(pLog)
  14. , m_seedling_dist(seedling_dist)
  15. , m_holes_number(holes_number)
  16. , m_xmin(x_min)
  17. , m_xmax(x_max)
  18. , m_zmin(z_min)
  19. , m_zmax(z_max)
  20. //, m_append_counter(0)
  21. , m_pcdId(pcd_id)
  22. , m_max_size(50)
  23. {
  24. gen_root_centers();
  25. }
  26. CStemResultInfos::~CStemResultInfos()
  27. {}
  28. void CStemResultInfos::append(
  29. CStemResult& sr
  30. )
  31. {
  32. m_infos.insert(m_infos.begin(), sr);
  33. if (m_infos.size() > m_max_size) {
  34. m_infos.pop_back();
  35. }
  36. //m_append_counter += 1;
  37. //每次都更新
  38. _update_root_centers(sr);
  39. //if (m_append_counter % 10 == 0) {
  40. // //定期写入数据
  41. // _update_root_centers();
  42. // write_root_centers(m_json_filename);
  43. //}
  44. }
  45. void CStemResultInfos::clear()
  46. {
  47. m_infos.clear();
  48. }
  49. void CStemResultInfos::get_root_centers(
  50. std::vector<CStemResult>&rst
  51. )
  52. {
  53. rst.clear();
  54. for (auto& sr : m_root_centers) {
  55. rst.push_back(sr);
  56. }
  57. }
  58. void CStemResultInfos::_update_root_centers(CStemResult& sr) {
  59. //直接在m_root_centers中找到最接近的中心,如果小于指定距离,更新m_root_centers
  60. double d1 = m_seedling_dist / 4.0;
  61. double d_min = 1.0e6;
  62. int min_root_idx = -1;
  63. for (int i = 0; i < m_root_centers.size(); ++i) {
  64. double dist = m_root_centers.at(i).calcluate_distance(sr);
  65. if (dist < d_min) {
  66. d_min = dist;
  67. min_root_idx = i;
  68. }
  69. }
  70. if (d_min < d1 && min_root_idx >= 0) {
  71. //更新指定中心
  72. double mu_x, mu_y, mu_z;
  73. CStemResult& min_root = m_root_centers.at(min_root_idx);
  74. mu_x = min_root.root_x;
  75. if (min_root.root_count == 0) {
  76. mu_y = sr.root_y;
  77. mu_z = sr.root_z;
  78. }
  79. else {
  80. mu_y = (min_root.root_y * min_root.root_count +
  81. sr.root_y * sr.root_count) / (double)(min_root.root_count + sr.root_count);
  82. mu_z = (min_root.root_z * min_root.root_count +
  83. sr.root_z * sr.root_count) / (double)(min_root.root_count + sr.root_count);
  84. }
  85. min_root.root_x = mu_x;
  86. min_root.root_y = mu_y;
  87. min_root.root_z = mu_z;
  88. min_root.root_count += sr.root_count;
  89. }
  90. }
  91. //void CStemResultInfos::_update_root_centers() {
  92. // //依据m_infos中的数据,苗间距m_seedling_dist,聚类生成茎的平均位置,茎的点云平均数量
  93. // //更新m_root_centers
  94. // //以root_center为基础进行聚类,如果root_center是空的,因当前数据进行聚类
  95. // std::vector<CStemResult> root_centers;
  96. // double d1 = m_seedling_dist / 2.0;
  97. // double d2 = d1*1.75;
  98. // pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2d_pos(new pcl::PointCloud < pcl::PointXYZ>);
  99. // for (auto&sr : m_infos) {
  100. // cloud2d_pos->points.push_back(pcl::PointXYZ((float)sr.root_x, 0.0, (float)sr.root_z));
  101. // }
  102. // cloud2d_pos->width = cloud2d_pos->points.size();
  103. // std::vector<pcl::PointXYZ>cluster_center;
  104. // std::vector<std::vector<int>> cluster_member;
  105. // euclidean_clustering_ttsas(cloud2d_pos, d1, d2, cluster_center, cluster_member);
  106. // for (size_t i = 0; i < cluster_center.size(); ++i) {
  107. // double x = (double)cluster_center.at(i).x;
  108. // double y = (double)cluster_center.at(i).y;
  109. // double z = (double)cluster_center.at(i).z;
  110. // int count = (int)cluster_member.at(i).size();
  111. // int pc_size = 0.0;
  112. // for (auto& idx : cluster_member.at(i)) {
  113. // pc_size += m_infos.at(idx).stem_size;
  114. // }
  115. // pc_size = (int)(pc_size / (float)count);
  116. // CStemResult sr = CStemResult(x, y, z, pc_size, std::string(""), count);
  117. // root_centers.push_back(sr);
  118. // }
  119. // if (m_root_centers.size() == 0) {
  120. // //如果没有历史数据,直接赋值
  121. // m_root_centers = root_centers;
  122. // }
  123. // else {
  124. // if (m_infos.size() > 50) {
  125. // //如果当前数据量较大,用当前的结果
  126. // m_root_centers = root_centers;
  127. // }
  128. // else {
  129. // //否则将当前结果合并到m_root_centers
  130. // //m_root_centers
  131. // for (auto& cent : root_centers) {
  132. // double dist_min = d2;
  133. // int min_root_idx = 0;
  134. // for (int j = 0; j < m_root_centers.size();++j) {
  135. // CStemResult& root = m_root_centers.at(j);
  136. // double dist = root.calcluate_distance(cent);
  137. // if (dist < dist_min) {
  138. // dist_min = dist;
  139. // min_root_idx = j;
  140. // }
  141. // }
  142. // if (dist_min < d1) {
  143. // //merge
  144. // double mu_x, mu_y,mu_z;
  145. // CStemResult& min_root = m_root_centers.at(min_root_idx);
  146. // mu_x = (min_root.root_x * min_root.root_count +
  147. // cent.root_x * cent.root_count) / (double)(min_root.root_count + cent.root_count);
  148. // mu_y = (min_root.root_y * min_root.root_count +
  149. // cent.root_y * cent.root_count) / (double)(min_root.root_count + cent.root_count);
  150. // mu_z = (min_root.root_z * min_root.root_count +
  151. // cent.root_z * cent.root_count) / (double)(min_root.root_count + cent.root_count);
  152. // min_root.root_x = mu_x;
  153. // min_root.root_y = mu_y;
  154. // min_root.root_z = mu_z;
  155. // min_root.root_count += cent.root_count;
  156. // }
  157. // else {
  158. // //add root
  159. // m_root_centers.push_back(cent);
  160. // }
  161. // }
  162. // }
  163. // }
  164. // //m_root_centers 排序、剔除
  165. // std::sort(m_root_centers.begin(), m_root_centers.end(),
  166. // [](const CStemResult& sr1, const CStemResult& sr2) {return sr1.root_x < sr2.root_x; });
  167. // //nms
  168. // _filter_root_centers(d1, d2);
  169. //}
  170. //void CStemResultInfos::_filter_root_centers(double d1, double d2)
  171. //{
  172. // //对生成的根中心m_root_centers进行过滤,剔除异常
  173. // //1 z值,通过中值,距离中值远的剔除
  174. // if (m_root_centers.size() > 3) {
  175. // std::vector<double>root_z;
  176. // for (auto&rc : m_root_centers) {
  177. // root_z.push_back(rc.root_z);
  178. // }
  179. // std::sort(root_z.begin(), root_z.end());
  180. // double mid_z = 0.0;
  181. // if (root_z.size() % 2 == 1) {
  182. // int idx = (m_root_centers.size() - 1) / 2;
  183. // mid_z = root_z.at(idx);
  184. // }
  185. // else {
  186. // int idx = root_z.size() / 2;
  187. // mid_z = 0.5 * (root_z.at(idx) + root_z.at(idx - 1));
  188. // }
  189. // std::vector<CStemResult> valid_root_centers;
  190. // for (auto&rc : m_root_centers) {
  191. // if (fabs(rc.root_z - mid_z) < d2) {
  192. // valid_root_centers.push_back(rc);
  193. // }
  194. // }
  195. // m_root_centers = valid_root_centers;
  196. // }
  197. // //2 按x做分组,排除权重小的
  198. // if (m_root_centers.size() > 3) {
  199. // std::vector<double> center_dist;
  200. // for (int i = 0; i < m_root_centers.size(); ++i) {
  201. // double x = m_root_centers.at(i).root_x;
  202. // double mod_sum = 0.0;
  203. // for (int j = 0; j < m_root_centers.size(); ++j) {
  204. // double dist = fabs(m_root_centers.at(j).root_x - x);
  205. // double mod = fmod(dist, m_seedling_dist);
  206. // double mod_inv = m_seedling_dist - mod;
  207. // mod = min(mod, mod_inv);
  208. // mod_sum += mod;
  209. // }
  210. // mod_sum /= (m_root_centers.size() - 1);
  211. // center_dist.push_back(mod_sum);
  212. // }
  213. // std::vector<CStemResult> valid_root_centers;
  214. // for (int i = 0; i < center_dist.size(); ++i) {
  215. // double dist = center_dist.at(i);
  216. // if (dist < d1) {
  217. // valid_root_centers.push_back(m_root_centers.at(i));
  218. // }
  219. // }
  220. // m_root_centers = valid_root_centers;
  221. // }
  222. // //3 数量少的剔除
  223. // int total_count = 0;
  224. // for (auto&rc : m_root_centers) {
  225. // total_count += rc.root_count;
  226. // }
  227. // if (total_count > 50) {
  228. // bool need_del = false;
  229. // for (auto& rc : m_root_centers) {
  230. // if (rc.root_count <= 2) {
  231. // need_del = true;
  232. // break;
  233. // }
  234. // }
  235. // if (need_del) {
  236. // std::vector<CStemResult> valid_root_centers;
  237. // for (int i = 0; i < m_root_centers.size(); ++i) {
  238. // if (m_root_centers.at(i).root_count > 2) {
  239. // valid_root_centers.push_back(m_root_centers.at(i));
  240. // }
  241. // }
  242. // m_root_centers = valid_root_centers;
  243. // }
  244. //
  245. // }
  246. //}
  247. void CStemResultInfos::gen_root_centers()
  248. {
  249. //根据 m_seedling_dist, m_holes_number, m_xmin, m_xmax生成初始的穴位中心
  250. //以m_xmin, m_xmax的中间点为中心,分别找到间隔m_seedling_dist的m_holes_number个穴位中心
  251. //初始的z设成-1,等待更新赋值
  252. double x_mid = 0.5 * (m_xmin + m_xmax);
  253. double holes_mid = 0.5 * (m_holes_number - 1) * m_seedling_dist;
  254. double x0 = x_mid - holes_mid;
  255. double z_mid = 0.5 * (m_zmin + m_zmax);
  256. m_root_centers.clear();
  257. for (int i=0; i<m_holes_number; ++i) {
  258. double x = x0 + i * m_seedling_dist;
  259. double y = 0;
  260. double z = z_mid;
  261. int size = 0;
  262. int count = 0;
  263. CStemResult sr = CStemResult(x, y, z, size, std::string(""), count);
  264. m_root_centers.push_back(sr);
  265. }
  266. }
  267. //void CStemResultInfos::set_json_filename(std::string& filename) {
  268. // m_json_filename = std::string(filename);
  269. //}
  270. //void CStemResultInfos::read_root_centers(
  271. // std::string& filename
  272. //)
  273. //{
  274. // //读取历史数据,每次启动时,去取
  275. // m_json_filename = std::string(filename);
  276. // //1 文件是否存在
  277. // ifstream f(filename.c_str());
  278. // if (!f.good()) {
  279. // //文件不存在
  280. // if (m_pLogger) {
  281. // stringstream buff;
  282. // buff << m_pcdId << ": json file not exists:" << filename;
  283. // m_pLogger->INFO(buff.str());
  284. // }
  285. // return;
  286. // }
  287. // cv::FileStorage fs(filename, cv::FileStorage::READ);
  288. // cv::FileNode root_centers = fs["root_centers"];
  289. // cv::FileNodeIterator it = root_centers.begin(), it_end = root_centers.end();
  290. // m_root_centers.clear();
  291. // for (; it != it_end; ++it) {
  292. // double x = (double)(*it)["x"];
  293. // double y = (double)(*it)["y"];
  294. // double z = (double)(*it)["z"];
  295. // int size = (int)(*it)["size"];
  296. // std::string bid = (std::string)(*it)["batch_id"];
  297. // int count = (int)(*it)["count"];
  298. // CStemResult sr = CStemResult(x,y,z,size, bid, count);
  299. // m_root_centers.push_back(sr);
  300. // }
  301. // fs.release();
  302. //}
  303. //void CStemResultInfos::write_root_centers(
  304. // std::string& filename
  305. //)
  306. //{
  307. // cv::FileStorage fs(filename, cv::FileStorage::WRITE);
  308. // fs << "root_centers" << "[";
  309. // for (auto& sr : m_root_centers) {
  310. // fs << "{" << "x" << sr.root_x
  311. // << "y" << sr.root_y
  312. // << "z" << sr.root_z
  313. // << "size" << sr.stem_size
  314. // << "batch_id" << sr.batch_id
  315. // << "count" << sr.root_count
  316. // << "}";
  317. // }
  318. // fs << "]";
  319. // fs.release();
  320. //}
  321. //void CStemResultInfos::euclidean_clustering_ttsas(
  322. // pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  323. // double d1, double d2,
  324. // std::vector<pcl::PointXYZ>&cluster_center,
  325. // std::vector<std::vector<int>> &clustr_member
  326. //)
  327. //{
  328. // if (m_pLogger) {
  329. // stringstream buff;
  330. // buff << m_pcdId << ": root center estimate: euclidean_clustering_ttsas() begin...";
  331. // m_pLogger->INFO(buff.str());
  332. // }
  333. // std::vector<int> cluster_weight;
  334. // std::vector<int> data_stat;
  335. // std::vector<pcl::PointXYZ>cluster_center_raw;
  336. // std::vector<std::vector<int>> clustr_member_raw;
  337. // for (size_t i = 0; i < in_cloud->points.size(); ++i) { data_stat.push_back(0); }
  338. // size_t data_len = in_cloud->points.size();
  339. // int exists_change = 0;
  340. // int prev_change = 0;
  341. // int cur_change = 0;
  342. // int m = 0;
  343. // while (std::find(data_stat.begin(), data_stat.end(), 0) != data_stat.end()) {
  344. // bool new_while_first = true;
  345. // for (size_t i = 0; i < data_len; ++i) {
  346. // if (data_stat.at(i) == 0 && new_while_first && exists_change == 0) {
  347. // new_while_first = false;
  348. // std::vector<int> idx;
  349. // idx.push_back(i);
  350. // clustr_member_raw.push_back(idx);
  351. // pcl::PointXYZ center;
  352. // center.x = in_cloud->points.at(i).x;
  353. // center.y = in_cloud->points.at(i).y;
  354. // center.z = in_cloud->points.at(i).z;
  355. // cluster_center_raw.push_back(center);
  356. // data_stat.at(i) = 1;
  357. // cur_change += 1;
  358. // cluster_weight.push_back(1);
  359. // m += 1;
  360. // }
  361. // else if (data_stat[i] == 0) {
  362. // std::vector<float> distances;
  363. // for (size_t j = 0; j < clustr_member_raw.size(); ++j) {
  364. // std::vector<float> distances_sub;
  365. // for (size_t jj = 0; jj < clustr_member_raw.at(j).size(); ++jj) {
  366. // size_t ele_idx = clustr_member_raw.at(j).at(jj);
  367. // double d = sqrt(
  368. // (in_cloud->points.at(i).x - in_cloud->points.at(ele_idx).x) * (in_cloud->points.at(i).x - in_cloud->points.at(ele_idx).x) +
  369. // (in_cloud->points.at(i).y - in_cloud->points.at(ele_idx).y) * (in_cloud->points.at(i).y - in_cloud->points.at(ele_idx).y) +
  370. // (in_cloud->points.at(i).z - in_cloud->points.at(ele_idx).z) * (in_cloud->points.at(i).z - in_cloud->points.at(ele_idx).z));
  371. // distances_sub.push_back(d);
  372. // }
  373. // double min_dist = *std::min_element(distances_sub.begin(), distances_sub.end());
  374. // distances.push_back(min_dist);
  375. // }
  376. // int min_idx = std::min_element(distances.begin(), distances.end()) - distances.begin();
  377. // if (distances.at(min_idx) < d1) {
  378. // data_stat.at(i) = 1;
  379. // double w = cluster_weight.at(min_idx);
  380. // cluster_weight.at(min_idx) += 1;
  381. // clustr_member_raw.at(min_idx).push_back(i);
  382. // cluster_center_raw.at(min_idx).x = (cluster_center_raw.at(min_idx).x * w + in_cloud->points.at(i).x) / (w + 1);
  383. // cluster_center_raw.at(min_idx).y = (cluster_center_raw.at(min_idx).y * w + in_cloud->points.at(i).y) / (w + 1);
  384. // cluster_center_raw.at(min_idx).z = (cluster_center_raw.at(min_idx).z * w + in_cloud->points.at(i).z) / (w + 1);
  385. // cur_change += 1;
  386. // }
  387. // else if (distances.at(min_idx) > d2) {
  388. // std::vector<int> idx;
  389. // idx.push_back(i);
  390. // clustr_member_raw.push_back(idx);
  391. // pcl::PointXYZ center;
  392. // center.x = in_cloud->points.at(i).x;
  393. // center.y = in_cloud->points.at(i).y;
  394. // center.z = in_cloud->points.at(i).z;
  395. // cluster_center_raw.push_back(center);
  396. // data_stat.at(i) = 1;
  397. // cur_change += 1;
  398. // cluster_weight.push_back(1);
  399. // m += 1;
  400. // }
  401. // }
  402. // else if (data_stat.at(i) == 1) {
  403. // cur_change += 1;
  404. // }
  405. // }
  406. // exists_change = fabs(cur_change - prev_change);
  407. // prev_change = cur_change;
  408. // cur_change = 0;
  409. // }
  410. // // copy result
  411. // for (size_t i = 0; i < clustr_member_raw.size(); ++i) {
  412. // //if (clustr_member_raw.at(i).size() < 20) { continue; }
  413. // cluster_center.push_back(cluster_center_raw.at(i));
  414. // clustr_member.push_back(clustr_member_raw.at(i));
  415. // }
  416. // if (m_pLogger) {
  417. // stringstream buff;
  418. // buff << m_pcdId << ": root center estimate: euclidean_clustering_ttsas() end";
  419. // m_pLogger->INFO(buff.str());
  420. // }
  421. //}
  422. }