algo1-1.cpp 计算1-1/x+1/x*x…

本文介绍了一个使用C++编写的程序,该程序能够计算一个特定的数学级数和1-1/x+1/x*x…。通过输入x和项数n,程序将输出级数的总和及其计算所耗费的时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1.  // algo1-1.cpp 计算1-1/x+1/x*x…
  2.  #include<stdio.h>
  3.  #include<sys/timeb.h>
  4.  void main()
  5.  {
  6.    timeb t1,t2;
  7.    long t;
  8.    double x,sum=1,sum1;
  9.    int i,j,n;
  10.    printf("请输入x n:");
  11.    scanf("%lf%d",&x,&n);
  12.    ftime(&t1); // 求得当前时间
  13.    for(i=1;i<=n;i++)
  14.    {
  15.      sum1=1;
  16.      for(j=1;j<=i;j++)
  17.        sum1=sum1*(-1.0/x);
  18.      sum+=sum1;
  19.    }
  20.    ftime(&t2); // 求得当前时间
  21.    t=(t2.time-t1.time)*1000+(t2.millitm-t1.millitm); // 计算时间差
  22.    printf("sum=%lf 用时%ld毫秒/n",sum,t);
  23.  }
 
Line 7: Char 9: ================================================================= ==22==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000354 at pc 0x55de9091eda9 bp 0x7ffeb85c4260 sp 0x7ffeb85c4258 READ of size 4 at 0x502000000354 thread T0 #0 0x55de9091eda8 in swap<int> /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/move.h:222:13 #1 0x55de9091eda8 in iter_swap<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > > /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algobase.h:185:7 #2 0x55de9091eda8 in void std::__reverse<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, std::random_access_iterator_tag) /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algo.h:1062:4 #3 0x55de9091ec00 in reverse<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > > /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algo.h:1089:7 #4 0x55de9091ec00 in Solution::rotate(std::vector<int, std::allocator<int>>&, int) solution.cpp:7:9 #5 0x55de9091e4ad in __helper__ solution.cpp:7:18 #6 0x55de9091e4ad in main solution.cpp:7:30 #7 0x7f3b1408a1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6) #8 0x7f3b1408a28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6) #9 0x55de90847f44 in _start (solution+0xb2f44) 0x502000000354 is located 0 bytes after 4-byte region [0x502000000350,0x502000000354) allocated by thread T0 here: #0 0x55de9091bb6d in operator new(unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:86:3 #1 0x55de909381de i
03-09
分析一下这个函数:bool MultiCentreLaserExtract(const cv::Mat& src_img, std::vector<cv::Point2f>& centre_points, std::vector<uint8_t>& gray_values, int gray_threshold, int search_range, LaserSearchDirection search_direction, CentreExtractMode mode, const BlurConfig& blur_config, int filter_half_size, float laser_half_width) { if (src_img.type() != CV_8UC1) { LOG_ERROR_AND_RETURN_FALSE("src_img should be CV_8UC1"); } cv::Mat src_img_float; // Transpose to use the same coordinates if (search_direction == LaserSearchDirection::kVertical) { #ifdef _DEBUG cv::transpose(src_img, src_img_float); #else // 多线程分块转置 if (!BlockTransposeGrayImg(src_img, src_img_float, 128)) { LOG_ERROR_AND_RETURN_FALSE("BlockTransposeGrayImg failed"); } #endif // DEBUG } else { src_img_float = src_img.clone(); } // #ifdef _DEBUG // // 图像预处理 // if (blur_config.enabled && blur_config.kernel_size.width > 0 && // blur_config.kernel_size.height > 0) { // algo::image_process::CvBlur(src_img_float, src_img_float, blur_config.kernel_size, // CV_8UC1, // BlurMode::kGaussianBlur); // } // // src_img_float.convertTo(src_img_float, CV_32FC1); // #else // 图像预处理 // src_img_float.convertTo(src_img_float, CV_32FC1); // 和 FPGA 一致, 没有先转为浮点数再滤波 if (blur_config.enabled && blur_config.kernel_size.width > 0 && blur_config.kernel_size.height > 0) { algo::image_process::CvBlur(src_img_float, src_img_float, blur_config.kernel_size, CV_8UC1, BlurMode::kGaussianBlur); } // #endif // DEBUG int resolution_width = src_img_float.cols; int resolution_height = src_img_float.rows; // 初始化输出 auto centre_points_internal = std::vector<cv::Point2f>(resolution_height); for (int h = 0; h < resolution_height; h++) { centre_points_internal[h] = cv::Point2f(0.f, h); } auto gray_values_internal = std::vector<uint8_t>(resolution_height); switch (mode) { case CentreExtractMode::kCaliper: { //先进行高斯滤波 sigma需要大于等于激光线半宽除以sqrt(3) //详情见《An Unbiased Detector of Curvilinear Structures》 cv::GaussianBlur(src_img_float, src_img_float, cv::Size(0, 0), laser_half_width/sqrt(3)); //用高斯一阶导进行滤波 //每行中正响应最大点和负响应最大点构成激光线的边缘 //滤波核的计算方法见《An Unbiased Detector of Curvilinear Structures》 cv::Mat kernel(1, 2 * filter_half_size + 1, CV_32F); float sigma = filter_half_size / 1.0; for (int i = 0; i < kernel.cols; i++) { int x = i - filter_half_size; kernel.at<float>(0, i) = exp(-(pow(x + 0.5, 2) / (2 * sigma * sigma))) / (sqrt(2 * CV_PI) * sigma) - exp(-(pow(x - 0.5, 2) / (2 * sigma * sigma))) / (sqrt(2 * CV_PI) * sigma); } cv::Mat filtered; cv::filter2D(src_img_float, filtered, CV_32F, kernel); for (int h = 0; h < resolution_height; h++) { std::vector<float> data(&filtered.at<float>(h, 0), &filtered.at<float>(h, 0) + resolution_width); cv::Point pMax, pMin; cv::minMaxLoc(data, NULL, NULL, &pMin, &pMax); int width = fabs(pMax.x - pMin.x) + 1; //激光线太细 数据量不够 不计算 if (width < 3) continue; int start = pMax.x < pMin.x ? pMax.x : pMin.x; int end = pMax.x > pMin.x ? pMax.x : pMin.x; //计算[start,end]区间内平均灰度 float avg = cv::sum(std::vector<uchar>(&src_img_float.at<uchar>(h, start), &src_img_float.at<uchar>(h, start) + width))[0] / (float)width; //平均灰度太低 不计算 if (avg < gray_threshold) continue; //对[start,end]内的点进行高斯拟合,方法见 //https://blog.csdn.net/qq_33487700/article/details/121998149 cv::Mat A(width, 3, CV_64F); cv::Mat b(width, 1, CV_64F); for (int r = 0; r < A.rows; r++) { A.at<double>(r, 0) = 1; int x = start + r; int y = src_img_float.at<uchar>(h, x); A.at<double>(r, 1) = x; A.at<double>(r, 2) = x * x; b.at<double>(r, 0) = log(y); } //cv::Mat x; //cv::solve(A, b, x, cv::DecompTypes::DECOMP_SVD); //和fpga一致 cv::Mat x = (A.t() * A).inv() * A.t() * b; centre_points_internal[h].x = -x.at<double>(1, 0) / (2 * x.at<double>(2, 0)); gray_values_internal[h] = src_img_float.at<uchar>(h, centre_points_internal[h].x); } break; } default: { std::vector<std::vector<BrightSection>> bright_ranges_cand = std::vector<std::vector<BrightSection>>(resolution_height); constexpr int kNumCandSectionsPerRow = 5; for (auto& ranges : bright_ranges_cand) { ranges.reserve(kNumCandSectionsPerRow); } #ifdef _DEBUG const int kNumThreads = 1; #else const int kNumThreads = std::max(1, omp_get_num_procs() / 2); #pragma omp parallel for num_threads(kNumThreads) schedule(static) #endif for (int h = 0; h < resolution_height; h++) { // #ifdef _DEBUG auto* data_src = src_img_float.ptr<uchar>(h); // #else // auto* data_src = src_img_float.ptr<float>(h); // #endif std::vector<BrightSection> bright_ranges; for (int w = 0; w < resolution_width; w++) { // Search The Largest Value In Area // [w - search_range, w + search_range + 1] if (data_src[w] <= gray_threshold) continue; auto start_w = std::max(0, w - search_range); auto end_w = std::min(resolution_width, w + search_range + 1); // 确保 w 位置的灰度是局部最大值 if (std::any_of(data_src + start_w, data_src + end_w, [&](const auto& val) { return data_src[w] < val; })) { continue; } // Find Gravity Sub-pixel Centre for Candidate double x_index_weighted = 0, intensity_weighted = 0; double sum_loc_intensity = 0; double sum_intensity_intensity = 0; double sum_intensity = 0; double max_intensity = 0; start_w = std::max(0, w - search_range); end_w = std::min(resolution_width, w + search_range + 1); for (int index_w = start_w; index_w < end_w; index_w++) // Find Sub_centre around max_pos { double intensity = data_src[index_w]; sum_loc_intensity += (index_w * intensity); sum_intensity_intensity += intensity * intensity; sum_intensity += intensity; max_intensity = std::max(max_intensity, intensity); } if (sum_intensity <= 0) continue; // Sorting according to x_index not gray_val if (bright_ranges.size() < kNumCandSectionsPerRow) { bright_ranges.emplace_back( sum_intensity_intensity / sum_intensity, max_intensity, cv::Point2f{static_cast<float>(sum_loc_intensity / sum_intensity), static_cast<float>(h)}); } else { auto min_it = std::min_element(bright_ranges.begin(), bright_ranges.end(), [](const BrightSection& a, const BrightSection& b) { return a.max_intensity < b.max_intensity; }); size_t min_index = min_it - bright_ranges.begin(); // The coming value is greater than min gray_val && x_index greater than all // the candidates if (bright_ranges[min_index].max_intensity < max_intensity) { // 将min_index后面的元素前移一位 std::copy(bright_ranges.begin() + min_index + 1, bright_ranges.end(), bright_ranges.begin() + min_index); // 在最后放入新值 bright_ranges.back() = BrightSection{ intensity_weighted, max_intensity, cv::Point2f{static_cast<float>(sum_loc_intensity / sum_intensity), static_cast<float>(h)}}; } } w += search_range; // Avoid repeated traversal } bright_ranges_cand[h] = std::move(bright_ranges); // 对于只有一个点的情况, 先赋值 if (bright_ranges_cand[h].size() == 1) { centre_points_internal[h].x = bright_ranges_cand[h][0].center.x; gray_values_internal[h] = bright_ranges_cand[h][0].mean_intensity; } } for (int h = 0; h < resolution_height; h++) { if (bright_ranges_cand[h].size() <= 1) continue; switch (mode) { case CentreExtractMode::kMaxValue: { auto max_it = std::max_element( bright_ranges_cand[h].begin(), bright_ranges_cand[h].end(), [](const BrightSection& a, const BrightSection& b) { return a.max_intensity < b.max_intensity; // 不同区域比较使用该区域的灰度最大值 }); centre_points_internal[h].x = max_it->center.x; gray_values_internal[h] = max_it->mean_intensity; // 返回灰度使用加权均值 break; } case CentreExtractMode::kNearLeft: centre_points_internal[h].x = bright_ranges_cand[h][0].center.x; gray_values_internal[h] = bright_ranges_cand[h][0].mean_intensity; break; case CentreExtractMode::kFarRight: centre_points_internal[h].x = bright_ranges_cand[h].back().center.x; gray_values_internal[h] = bright_ranges_cand[h].back().mean_intensity; break; case CentreExtractMode::kContinuous: { int index_select = -1; const int kSearchRange = 5; const float kHWeights[kSearchRange + 1] = {0.0, 1.0, 0.9, 0.8, 0.7, 0.5}; float dist_min = std::numeric_limits<float>::max(); // 初始化最小距离, // 确保第一个区域能命中 for (int index = 0; index < bright_ranges_cand[h].size(); index++) { float dist_temp = 0.f; int start_h = std::max(0, h - kSearchRange); int end_h = std::min(resolution_height, h + kSearchRange + 1); for (int index_h = start_h; index_h < end_h; index_h++) { if (centre_points_internal[index_h].x > 0) { dist_temp += (fabs(bright_ranges_cand[h][index].center.x - centre_points_internal[index_h].x) * kHWeights[abs(index_h - h)]); } } if (dist_temp <= dist_min) { dist_min = dist_temp; index_select = index; } } centre_points_internal[h].x = bright_ranges_cand[h][index_select].center.x; gray_values_internal[h] = bright_ranges_cand[h][index_select].mean_intensity; break; } case CentreExtractMode::kRemove: centre_points_internal[h].x = 0; gray_values_internal[h] = 0; break; default: break; } } break; } } // result if (search_direction == LaserSearchDirection::kVertical) { // x <-> y for (auto& point : centre_points_internal) { std::swap(point.x, point.y); } } assert(centre_points_internal.size() == gray_values_internal.size()); centre_points = std::move(centre_points_internal); gray_values = std::move(gray_values_internal); return true; }
07-19
分析一下这段代码:/******************************************************************************* * FILENAME: 3d_reconstruction.cpp * * AUTHORS: Zhiwen Dai START DATE: Monday, July 22nd 2024 * * LAST MODIFIED: Monday, May 26th 2025, 5:38:37 pm * * Copyright (c) 2023 - 2024 DepthVision Limited * * CONTACT: zwdai@hkclr.hk *******************************************************************************/ #include "geom_cal/3d_reconstruction.h" #include <opencv2/core/matx.hpp> #include <vector> #include "opencv2/core/types.hpp" #include "utils/invalid_3d_point.h" #include "utils/logger.h" #include "utils/stop_watch.h" #include<fstream> #include"utils/file_system.h" ALGO_GEOM_CAL_NS_BEGIN // 读神经网络参数文件 bool Read(std::ifstream& file, cv::Mat& data) { try { int size[2]; file.read((char*)size, sizeof(int) * 2); cv::Mat temp(size[1], size[0], CV_32F); file.read((char*)&temp.at<float>(0, 0), sizeof(float) * size[0] * size[1]); data = temp.t(); return true; } catch (std::exception ex) { file.close(); LOG_ERROR_AND_RETURN_FALSE("Read failed"); } } bool NeuralNet::Init(std::string filename) { std::ifstream file(filename, std::ios::binary); if (!file.is_open()) LOG_ERROR_AND_RETURN_FALSE("file open failed"); try { file.read((char*)&x_min_, sizeof(float)); file.read((char*)&x_max_, sizeof(float)); file.read((char*)&y_min_, sizeof(float)); file.read((char*)&y_max_, sizeof(float)); offsets_.resize(2); gains_.resize(2); mins_.resize(2); if (!Read(file, offsets_[0])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, gains_[0])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, mins_[0])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, offsets_[1])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, gains_[1])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, mins_[1])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); int layers_num; file.read((char*)&layers_num, sizeof(int)); weights_.resize(layers_num); bias_.resize(layers_num); for (int i = 0; i < layers_num; i++) { if (!Read(file, weights_[i])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); if (!Read(file, bias_[i])) LOG_ERROR_AND_RETURN_FALSE("Load failed"); } int taylor_order; file.read((char*)&taylor_order, sizeof(int)); while (file.peek() != EOF) { std::vector<float> temp(2 + taylor_order); file.read((char*)&temp[0], sizeof(float) * temp.size()); taylor_coefficients_.push_back(temp); } file.close(); return true; } catch (std::exception ex) { file.close(); LOG_ERROR_AND_RETURN_FALSE("Init failed"); } } // 激活函数 void Tanh(cv::Mat& data, const std::vector<std::vector<float>>& taylor_coefficients) { for (int r = 0; r < data.rows; r++) { float value = data.at<float>(r, 0); float fabs_value = fabs(value); if (fabs_value >= taylor_coefficients.size()) data.at<float>(r, 0) = value > 0 ? 1 : -1; else { int quotient = std::floor(fabs_value * 2); int index = std::floor(quotient * 0.5); //用泰勒展开计算激活函数 float x0 = taylor_coefficients[index][0]; //按定义算 /*float res = taylor_coefficients[index][1]; for (int k = 2; k < taylor_coefficients[index].size(); k++) res += taylor_coefficients[index][k] * pow(fabs_value - x0, k - 1);*/ //按秦九韶算法 float res = taylor_coefficients[index].back(); float delta_x = fabs_value - x0; for (int k = taylor_coefficients[index].size() - 2; k >= 1; k--) res = res * delta_x + taylor_coefficients[index][k]; data.at<float>(r, 0) = value > 0 ? res : -res; } } } bool NeuralNet::Predict(const std::vector<cv::Point2f>& centers, std::vector<cv::Point3f>& points3d) { if (centers.size() == 0) LOG_ERROR_AND_RETURN_FALSE("centers shouldn't be empty"); points3d = std::vector<cv::Point3f>(centers.size()); std::vector<cv::Point2f> centers_valid; // 如果激光中心点不在范围内 不重建 for (int i = 0; i < centers.size(); i++) { if (centers[i].y == 0 || !(centers[i].x >= x_min_ && centers[i].x <= x_max_ && centers[i].y >= y_min_ && centers[i].y <= y_max_)) points3d[i] = INVALID_POINT; else centers_valid.push_back(centers[i]); } if (centers_valid.size() == 0) return true; std::vector<cv::Point2f> pts2d(centers_valid.size()); cv::Mat gain1 = 1 / gains_[1]; for (int i = 0; i < centers_valid.size(); i++) { cv::Mat p = (cv::Mat_<float>(2, 1) << centers_valid[i].x, centers_valid[i].y); p = (p - offsets_[0]).mul(gains_[0]) + mins_[0]; for (int j = 0; j < weights_.size() - 1; j++) { p = weights_[j] * p + bias_[j]; Tanh(p, taylor_coefficients_); } p = weights_.back() * p + bias_.back(); p = (p - mins_[1]).mul(gain1) + offsets_[1]; pts2d[i] = cv::Point2f(p.at<float>(0, 0), p.at<float>(1, 0)); } int c = 0; for (int i = 0; i < points3d.size(); i++) { if (points3d[i] != INVALID_POINT) { points3d[i] = cv::Point3f(pts2d[c].x, 0, pts2d[c].y); c++; } } return true; } ALGO_GEOM_CAL_NS_END
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值