活动介绍

C++ 求std::vector<float>的中位数

时间: 2024-09-29 12:02:32 浏览: 130
在C++中,计算`std::vector<float>`的中位数需要一些步骤,因为标准库本身并不提供直接获取中位数的函数。以下是手动实现的一个基本步骤: 1. 首先,你需要包含必要的头文件,并声明一个函数来找到中间元素: ```cpp #include <vector> #include <algorithm> float findMedian(std::vector<float>& nums) { // ... } ``` 2. 确定向量是否为空,如果为空则返回0或抛出异常(取决于你的需求): ```cpp if (nums.empty()) { return 0; // 或者抛出异常 } ``` 3. 对于奇数大小的向量,中位数是正中间那个数;对于偶数大小的向量,中位数是中间两个数的平均值。你可以通过排序vector来完成这一步: ```cpp std::sort(nums.begin(), nums.end()); size_t middle = nums.size() / 2; ``` 4. 计算并返回中位数: ```cpp if (nums.size() % 2 == 0) { // 偶数元素 return (nums[middle - 1] + nums[middle]) / 2.0f; } else { // 奇数元素 return nums[middle]; } ``` 完整示例: ```cpp #include <iostream> #include <vector> #include <algorithm> float findMedian(std::vector<float>& nums) { if (nums.empty()) { throw std::runtime_error("Vector is empty"); } std::sort(nums.begin(), nums.end()); size_t middle = nums.size() / 2; return nums.size() % 2 ? nums[middle] : (nums[middle - 1] + nums[middle]) / 2.0f; } int main() { std::vector<float> vec = {5.2, 3.7, 8.9, 1.1, 4.6}; try { float median = findMedian(vec); std::cout << "Median of the vector: " << median << std::endl; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; } ```
阅读全文

相关推荐

#include <iostream> #include <fstream> #include <vector> #include <cmath> #include <complex> // WAV文件头结构(44字节) #pragma pack(push, 1) struct WAVHeader { char riff[4]; // "RIFF" uint32_t fileSize; // 文件总大小-8 char wave[4]; // "WAVE" char fmt[4]; // "fmt " uint32_t fmtSize; // fmt块大小(16) uint16_t format; // 1=PCM uint16_t channels; // 通道数 uint32_t sampleRate; // 采样率 uint32_t byteRate; // 每秒字节数 uint16_t blockAlign; // 数据块对齐 uint16_t bitsPerSample; // 位深度 char data[4]; // "data" uint32_t dataSize; // 数据块大小 }; #pragma pack(pop) // 读取IQ WAV文件(假设32位浮点双通道) std::vector<std::complex<float>> readIQWav(const std::string& filename) { std::ifstream file(filename, std::ios::binary); if (!file) { throw std::runtime_error("无法打开文件"); } WAVHeader header; file.read(reinterpret_cast<char*>(&header), sizeof(header)); // 验证头信息 if (memcmp(header.riff, "RIFF", 4) != 0 || memcmp(header.wave, "WAVE", 4) != 0 || header.format != 3) { // 3表示浮点格式 throw std::runtime_error("不支持的WAV格式"); } const size_t numSamples = header.dataSize / (sizeof(float) * 2); std::vector<std::complex<float>> iqData(numSamples); // 读取IQ数据(交替存储的I和Q) for (size_t i = 0; i < numSamples; ++i) { float I, Q; file.read(reinterpret_cast<char*>(&I), sizeof(float)); file.read(reinterpret_cast<char*>(&Q), sizeof(float)); iqData[i] = std::complex<float>(I, Q); } return iqData; } // 频率搬移(复数混频) void frequencyShift(std::vector<std::complex<float>>& data, float sampleRate, float shiftFreq) { const float phaseStep = 2 * M_PI * shiftFreq / sampleRate; float phase = 0.0f; for (auto& sample : data) { // 生成复数指数 std::complex<float> mixer(std::cos(phase), -std::sin(phase)); sample *= mixer; // 相位累积 phase = fmod(phase + phaseStep, 2 * M_PI); } } // 生成汉宁窗FIR低通滤波器系数 std::vector<float> designHanningLPF(float cutoffFreq, float sampleRate, int numTaps) { std::vector<float> coeffs(numTaps); const float normCutoff = cutoffFreq / sampleRate; for (int n = 0; n < numTaps; ++n) { // 理想低通冲激响应 float h = 2 * normCutoff * sinc(2 * M_PI * normCutoff * (n - (numTaps-1)/2.0f)); // 应用汉宁窗 float window = 0.5 - 0.5 * cos(2 * M_PI * n / (numTaps - 1)); coeffs[n] = h * window; } return coeffs; } // FIR滤波器实现 std::vector<std::complex<float>> applyFIRFilter( const std::vector<std::complex<float>>& input, const std::vector<float>& coeffs) { std::vector<std::complex<float>> output(input.size(), 0); const int numTaps = coeffs.size(); for (size_t i = 0; i < input.size(); ++i) { for (int j = 0; j < numTaps; ++j) { if (i >= j) { output[i] += input[i - j] * coeffs[j]; } } } return output; } // 示例使用 int main() { try { // 1. 读取IQ数据 auto iqData = readIQWav("input.wav"); // 2. 频率搬移(示例:下变频2MHz) const float sampleRate = 10e6; // 假设采样率10MHz frequencyShift(iqData, sampleRate, -2e6); // 3. 设计滤波器(截止频率1MHz,101阶) auto coeffs = designHanningLPF(1e6, sampleRate, 101); // 4. 应用滤波 auto filtered = applyFIRFilter(iqData, coeffs); // 可添加保存结果的代码... } catch (const std::exception& e) { std::cerr << "错误: " << e.what() << std::endl; return 1; } return 0; }修复错误

#include <opencv2/opencv.hpp> #include <iostream> #include <vector> using namespace cv; using namespace std; using namespace cv::ml; // 特征提取函数 vector<float> extractFeatures(Mat img) { resize(img, img, Size(64, 64)); // 统一尺寸 GaussianBlur(img, img, Size(5, 5), 0); // 去噪 Mat hsv; cvtColor(img, hsv, COLOR_BGR2HSV); // 转换色彩空间 // 计算H-S二维直方图 int histSize[] = { 16,16 }; float hRange[] = { 0,180 }, sRange[] = { 0,256 }; const float* ranges[] = { hRange, sRange }; int channels[] = { 0,1 }; Mat hist; calcHist(&hsv, 1, channels, Mat(), hist, 2, histSize, ranges, true, false); normalize(hist, hist, 0, 1, NORM_MINMAX); // 归一化 vector<float> features; features.assign((float*)hist.datastart, (float*)hist.dataend); return features; } int main() { // 加载数据集路径 vector<string> posPaths, negPaths; glob("dataset/qualified/*.jpg", posPaths); glob("dataset/unqualified/*.jpg", negPaths); // 提取特征 vector<vector<float>> features; vector<int> labels; // 处理合格样本 for (auto& path : posPaths) { Mat img = imread(path); if (!img.empty()) { features.push_back(extractFeatures(img)); labels.push_back(1); } } // 处理不合格样本 for (auto& path : negPaths) { Mat img = imread(path); if (!img.empty()) { features.push_back(extractFeatures(img)); labels.push_back(0); } } // 创建训练数据矩阵 Mat trainData(features.size(), features[0].size(), CV_32FC1); for (int i = 0; i < features.size(); ++i) trainData.row(i) = Mat(features[i]).t(); Mat labelsMat(labels); // 创建SVM模型 Ptr<SVM> svm = SVM::create(); svm->setType(SVM::C_SVC); svm->setKernel(SVM::RBF); svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 1000, 1e-6)); // 训练并保存模型 svm->train(trainData, ROW_SAMPLE, labelsMat); svm->save("peanut_model.xml"); cout << "模型训练完成!" << endl; return 0; }把以上程序改成,数据集有good ,atrophy ,spot ,broken ,peeling ,moldy 六个标签,且已经分为了训练集和测试集两组,更改加载数据集

uint32_t extracted_length; fread(&extracted_length, sizeof(uint32_t), 1, input_file); extracted_length = ntohl(extracted_length);提取代码也加入上面代码,进行修改std::string f5ExtractColorImage(cv::Mat& img) { // 转换到YCrCb颜色空间 cv::Mat yuv_image; cv::cvtColor(img, yuv_image, cv::COLOR_BGR2YCrCb); std::vector<cv::Mat> channels; cv::split(yuv_image, channels); cv::Mat y_channel = channels[0].clone(); // 生成块坐标并洗牌(必须与嵌入时相同的随机逻辑) const int block_size = 8; std::vector<cv::Point> blocks; for (int y = 0; y < y_channel.rows; y += block_size) { for (int x = 0; x < y_channel.cols; x += block_size) { blocks.emplace_back(x, y); } } std::mt19937 rng(12345); // 固定种子确保洗牌顺序一致 std::shuffle(blocks.begin(), blocks.end(), rng); std::string extracted_bits; // 遍历每个块提取信息 for (const auto& block : blocks) { cv::Rect roi(block.x, block.y, block_size, block_size); if (roi.br().x > y_channel.cols || roi.br().y > y_channel.rows) continue; cv::Mat block_data = y_channel(roi).clone(); block_data.convertTo(block_data, CV_32F); // DCT变换 cv::Mat dct_coeffs; cv::dct(block_data, dct_coeffs); // 提取量化系数的LSB for (int i = 0; i < block_size; ++i) { for (int j = 0; j < block_size; ++j) { if (i == 0 && j == 0) continue; // 跳过直流分量 float q_val = QUANTIZATION_MATRIX.at<float>(i, j); float quantized = std::round(dct_coeffs.at<float>(i, j) / q_val); if (quantized == 0) continue; // 跳过未嵌入的系数 // 提取最低有效位 extracted_bits += (static_cast<int>(quantized) % 2) ? '1' : '0'; } } } // 二进制转字符串 std::string secret_message; for (size_t i = 0; i < extracted_bits.size(); i += 8) { if (i + 8 > extracted_bits.size()) break; secret_message += static_cast<char>( std::bitset<8>(extracted_bits.substr(i, 8)).to_ulong() ); } // 移除可能存在的填充空字符 size_t null_pos = secret_message.find('\0'); return (null_pos != std::string::npos) ? secret_message.substr(0, null_pos) : secret_message; }提取代码也修改一下

我正在编辑【c++】代码,遇到了 【0x00007FFFD5C115E1 (vcruntime140.dll) (test.exe 中)处有未经处理的异常: 0xC0000005: 写入位置 0x00000259FE6D4000 时发生访问冲突。 】 ,请帮我检查并改正错误点。我的原始代码如下: 【#include <iostream> #include <memory> #include <chrono> #include <fstream> #include <string> #include <iomanip> #include <opencv2/highgui.hpp> #include <opencv2/opencv.hpp> #include "gdal_priv.h" #include <gdal_alg_priv.h> #include <gdal.h> using namespace std; using namespace cv; //参考https://blog.csdn.net/ivan_ljf/article/details/9226463 //计算trans中图片xy点的经纬度信息 //adfGeoTransform的6个参数分别为左上角x坐标,水平分辨率,旋转参数,左上角y坐标,旋转参数,竖直分辨率,一般来说,旋转参数都为0 bool Projection2ImageRowCol(double* adfGeoTransform, double dProjX, double dProjY, int& iCol, int& iRow) { try { double dTemp = adfGeoTransform[1] * adfGeoTransform[5] - adfGeoTransform[2] * adfGeoTransform[4]; double dCol = 0.0, dRow = 0.0; dCol = (adfGeoTransform[5] * (dProjX - adfGeoTransform[0]) - adfGeoTransform[2] * (dProjY - adfGeoTransform[3])) / dTemp + 0.5; dRow = (adfGeoTransform[1] * (dProjY - adfGeoTransform[3]) - adfGeoTransform[4] * (dProjX - adfGeoTransform[0])) / dTemp + 0.5; iCol = int(dCol); iRow = int(dRow); return true; } catch (...) { return false; } } bool ImageRowCol2Projection(double* adfGeoTransform, int iCol, int iRow, double& dProjX, double& dProjY) { try { dProjX = adfGeoTransform[0] + adfGeoTransform[1] * iCol + adfGeoTransform[2] * iRow; dProjY = adfGeoTransform[3] + adfGeoTransform[4] * iCol + adfGeoTransform[5] * iRow; return true; } catch (...) { return false; } } int main() { GDALAllRegister();//注册所有的驱动 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径和文件名 //1、加载tif数据 string file_path_name = "D:\\Downloads\\上海区域九景影像\\ZY3_01a_mynbavp_880146_20120923_104301_0008_SASMAC_CHN_sec_rel_001_1209248618.tif"; //std::cout << "请输入图片路径:" << std::endl; //std::cin >> file_path_name; GDALDataset* poDataset = (GDALDataset*)GDALOpen(file_path_name.c_str(), GA_ReadOnly);//GA_Update和GA_ReadOnly两种模式 if (poDataset == NULL) { std::cout << "指定的文件不能打开!" << std::endl; return 0; } //获取图像的尺寸 int nImgSizeX = poDataset->GetRasterXSize(); int nImgSizeY = poDataset->GetRasterYSize(); std::cout << "ImageX = " << nImgSizeX << ", ImageY = " << nImgSizeY << std::endl; //获取图像的通道数(波段数量) int bandCount = poDataset->GetRasterCount(); std::cout << "bandCount = " << bandCount << std::endl; //获取图像波段 在GDAL中波段数的起始数是1,而非0 GDALRasterBand* poBand1 = poDataset->GetRasterBand(1); //GDAL中的数据类型 由此可知,每一个波段都可以有不同的数据类型 /* 一共包含以下12种数据类型 typedef enum { GDT_Unknown = 0, GDT_Byte = 1, GDT_UInt16 = 2, GDT_Int16 = 3, GDT_UInt32 = 4, GDT_Int32 = 5,GDT_UInt64,GDT_Int64 GDT_Float32 = 6, GDT_Float64 = 7, GDT_CInt16 = 8, GDT_CInt32 = 9,GDT_CInt64 GDT_CFloat32 = 10, GDT_CFloat64 = 11, GDT_TypeCount = 12 } GDALDataType; */ GDALDataType g_type = GDALDataType(poBand1->GetRasterDataType()); std::cout << "g_type = " << g_type << std::endl; //获取坐标变换系数 double trans[6] = { 0,1,0,0,0,1 };//定义为默认值,即x、y分辨率为1,其他信息为0 CPLErr aaa = poDataset->GetGeoTransform(trans); trans[2] = 0.3;//修改x的旋转参数信息 trans[4] = 0.1;//修改y的旋转参数信息 //poDataset->SetGeoTransform(trans);//设置坐标变换系数 std::cout << "trans = " << trans[0] << "," << trans[1] << "," << trans[2] << "," << trans[3] << "," << trans[4] << "," << trans[5] << std::endl; //像素坐标与投影坐标的换算 double dProjX, dProjY; int iCol, iRow; iCol = 111; iRow = 111; ImageRowCol2Projection(trans, iCol, iRow, dProjX, dProjY); std::cout << "在trans中,像素坐标=》经纬度:" << iCol << "," << iRow << "====》" << dProjX << "," << dProjY << std::endl; Projection2ImageRowCol(trans, dProjX, dProjY, iCol, iRow); std::cout << "在trans中,经纬度=》像素坐标:" << dProjX << "," << dProjY << "====》" << iCol << "," << iRow << std::endl; //获取图像投影坐标系信息, std::string projs = poDataset->GetProjectionRef(); //设置地理坐标系信息 //poDataset->SetProjection(projs.c_str()); std::cout << "projs = " << projs << std::endl; //读取gadl中第一个通道的数据到mat中 【通道数是从1开始的】 //RasterIO参数列表的详细说明可以参考 https://blog.51cto.com/u_15469043/4903358 /*从参数列表中是可以看到,GDAL是支持将数据分块读入的内存中的 CPLErr GDALRasterBand::RasterIO ( GDALRWFlag eRWFlag, int nXOff,//x的起始点 int nYOff,//y的起始点 int nXSize,//读取窗口的宽 int nYSize,//读取窗口的高 void * pData, int nBufXSize,//与nXSize相同 int nBufYSize,//与nYSize相同 GDALDataType eBufType, int nPixelSpace,//通常默认为0 int nLineSpace //通常默认为0 ) */ // cv::Mat gdal_mat1(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0)); cv::Mat gdal_mat2(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0)); cv::Mat gdal_mat3(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0)); poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat1.data, nImgSizeX, nImgSizeY, g_type, 0, 0); poDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat2.data, nImgSizeX, nImgSizeY, g_type, 0, 0); poDataset->GetRasterBand(3)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat3.data, nImgSizeX, nImgSizeY, g_type, 0, 0); cv::Mat mg; cv::merge(vector<cv::Mat>{ gdal_mat3, gdal_mat2, gdal_mat1, }, mg); cv::imwrite("read_save.jpg", mg); /* //读取gadl中第一个通道的数据到指针中 //void * malloc(size_t n):给指针分配相应的内存,并返回内存空间的首地址。当内存不再使用的时候,应使用free()函数将内存块释放掉。 uint8_t* srcData = (uint8_t*)malloc(sizeof(uint8_t) * nImgSizeX * nImgSizeY); //void * memset (void * p,int c,size_t n):将p中的n个字节都赋值为c memset(srcData, 0, sizeof(uint8_t) * 1 * nImgSizeX * nImgSizeY);//为空间赋默认值0 poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, srcData, nImgSizeX, nImgSizeY, g_type, 0, 0); */ //-----------创建gdal对象 MEM追加,CreateCopy保存支持tif、png、jpg等格式----- int nImgSizeX2 = gdal_mat1.cols; int nImgSizeY2 = gdal_mat1.rows; //获取GDAL驱动,MEM表示为内存对象,可以快速的分块追加写入数据。MEM文件大小是和你的系统内存大小有关系,并不会存储到磁盘中。可用的驱动格式还有:BMP、JPEG、PNG、GTiff、GIF、HFA、BT、ECW、FITS、HDF4、EHdr。分别对应着不同的文件类型 GDALDriver* pDriverMEM = GetGDALDriverManager()->GetDriverByName("MEM"); int nBands = 1; //创建GDAL对象,只保存原图的一个通道 //Create(const char * pszName,int nXSize, int nYSize, int nBands, GDALDataType eType, char** papszOptions) GDALDataset* poDataset2 = pDriverMEM->Create("", nImgSizeX2, nImgSizeY2, nBands, g_type, NULL); //将mat数据写入到GDALDataset中 poDataset2->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX2, nImgSizeY2, gdal_mat1.data, nImgSizeX2, nImgSizeY2, GDT_Byte, 0, 0); //获取GDAL驱动,PNG表示为用png驱动保存数据 GDALDriver* pDriverSave = GetGDALDriverManager()->GetDriverByName("PNG"); pDriverSave->CreateCopy("saved.png", poDataset2, TRUE, 0, 0, 0); //创建png文件 std::cout << "png 文件保存成功" << std::endl; //-----------创建gdal对象 一次性写入,只支持tiff数据。PEN、JPEG等驱动没有实现相应的Create方法----- int nImgSizeX3 = gdal_mat1.cols; int nImgSizeY3 = gdal_mat1.rows; GDALDriver* pDriverMEM3 = GetGDALDriverManager()->GetDriverByName("GTiff"); if (!pDriverMEM3) { fprintf(stderr, "get driver by name failed\n"); return -1; } int nBands3 = 1; GDALDataset* poDataset3 = pDriverMEM3->Create("saved3.tif", nImgSizeX3, nImgSizeY3, nBands3, g_type, NULL); if (!poDataset3) { fprintf(stderr, "Create GDALDataset failed\n"); return -1; } poDataset3->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX3, nImgSizeY3, gdal_mat1.data, nImgSizeX3, nImgSizeY3, GDT_Byte, 0, 0); std::cout << "tif 文件保存成功" << std::endl; //关闭GDAL对象,并注销所有驱动 GDALClose(poDataset); GDALClose(poDataset2); GDALClose(poDataset3); GDALDestroyDriverManager(); return -1; }】

void parseTrainMileage(const std::string& hexStr, float& mileage, uint8_t& direction, bool& isTestData) { if (hexStr == “7F9698” || hexStr == “FFFFFF”) { mileage = 9999.999f; // 固定最大值 direction = 0; // 方向设为无效值 isTestData = true; // 标记为特殊数据 return; // 直接返回不执行后续解析 } // Step 1: 分割字符串为字节数组 std::vector<uint8_t> bytes; std::istringstream iss(hexStr); std::string byteStr; while (iss >> byteStr) { bytes.push_back(static_cast<uint8_t>(std::stoul(byteStr, nullptr, 16))); } // Step 3: 合并为32位整数 (小端序) uint32_t combined = 0; for (uint8_t byte : bytes) { combined = (combined << 8) | byte; } // Step 4: 测试数据判断 isTestData = (combined == 9999888 || combined == 8888888); if (!isTestData) { // Step 5: 提取标志位和里程数据 uint32_t flag = combined >> 22; // 取高2位 uint32_t rawMileage = combined & 0x3FFFFF; // 掩码操作 // Step 6: 符号判断(根据你的需求调整) int32_t signedMileage = rawMileage; if ((flag >> 1) & 0x01) { // 如果标志位第2位为1 signedMileage = -signedMileage; } // Step 7: 方向标志提取 direction = flag & 0x01; // 取最低位 // Step 8: 转换为公里数(保留3位小数) mileage = static_cast<float>(signedMileage) / 1000.0f; } else { mileage = 0.0f; direction = 0; } } 这是一个函数,输入16进制数据进行数据转换。现在它的转换有问题,能不能帮我排除一下。大概是输入 3位16进制数据,比如“1f3ace”,第一步转换为2进制,得到“000111110011101011001110”完整的2进制。第二部提取前2位进行处理,然后将后22位由二进制转为10进制数字“2046670”使用C++代码方案,可在PlatformIO环境中运行

void BilateralFilter(InputArray _src, OutputArray _dst, int d, double sigmaColor, double sigmaSpace, int borderType) { Mat src = _src.getMat(); _dst.create(src.size(), src.type()); Mat dst = _dst.getMat(); if (src.depth() == CV_8U) bilateralFilter_8u(src, dst, d, sigmaColor, sigmaSpace, borderType); } void bilateralFilter_8u(const Mat& src, Mat& dst, int d, double sigma_color, double sigma_space, int borderType) { int cn = src.channels(); int i, j, k, maxk, radius; Size size = src.size(); CV_Assert((src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data); if (sigma_color <= 0) sigma_color = 1; if (sigma_space <= 0) sigma_space = 1; // 计算颜色域和空间域的权重的高斯核系数, 均值 μ = 0; exp(-1/(2*sigma^2)) double gauss_color_coeff = -0.5 / (sigma_color*sigma_color); double gauss_space_coeff = -0.5 / (sigma_space*sigma_space); // radius 为空间域的大小: 其值是 windosw_size 的一半 if (d <= 0) radius = cvRound(sigma_space*1.5); else radius = d / 2; radius = MAX(radius, 1); d = radius * 2 + 1; cout << "radius: " << radius << endl; cout << "d: " << d << endl; Mat temp; copyMakeBorder(src, temp, radius, radius, radius, radius, borderType); cout << "copyMakeBorder = " << endl << temp << endl; vector<float> _color_weight(cn * 256); vector<float> _space_weight(d*d); vector<int> _space_ofs(d*d); float* color_weight = &_color_weight[0]; float* space_weight = &_space_weight[0]; int* space_ofs = &_space_ofs[0]; // 初始化颜色相关的滤波器系数: exp(-1*x^2/(2*sigma^2)) cout << "颜色相关的滤波器系数:"; for (i = 0; i < 256 * cn; i++) { color_weight[i] = (float)std::exp(i*i*gauss_color_coeff); cout << i << ":" << color_weight[i] << "; "; } // 初始化空间相关的滤波器系数和 offset: cout << endl<<"空间相关的滤波器系数和offset:"; for (i = -radius, maxk = 0; i <= radius; i++) { j = -radius; for (; j <= radius; j++) { double r = std::sqrt((double)i*i + (double)j*j); if (r > radius) continue; space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); //space_ofs[maxk++] = (int)(i*temp.step + j * cn); space_ofs[maxk] = (int)(i*temp.step + j * cn); cout << "(" <<i << "," <<j<<")" << space_weight[maxk] <<","<< space_ofs[maxk] << "; "; maxk++; } } cout <<endl<< "maxk:" << maxk << endl; // 开始计算滤波后的像素值 for (i = 0; i < size.height; i++) { const uchar* sptr = temp.ptr(i + radius) + radius * cn; // 目标像素点 uchar* dptr = dst.ptr(i); if (cn == 1) { // 按行开始遍历 for (j = 0; j < size.width; j++) { float sum = 0, wsum = 0; int val0 = sptr[j]; cout << endl<<"计算滤波后的像素值: (" << i << "," << j << ")" << val0 << ": "; // 遍历当前中心点所在的空间邻域 for (k = 0; k < maxk; k++) { int val = sptr[j + space_ofs[k]]; float w = space_weight[k] * color_weight[std::abs(val - val0)]; sum += val * w; wsum += w; cout << k << " val: " << val << " w: " << w << " sum: " << sum; } // 这里不可能溢出, 因此不必使用 CV_CAST_8U. dptr[j] = (uchar)cvRound(sum / wsum); cout << " dst输出值:" << dptr[j] << endl; } } else { assert(cn == 3); for (j = 0; j < size.width * 3; j += 3) { float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; int b0 = sptr[j], g0 = sptr[j + 1], r0 = sptr[j + 2]; k = 0; for (; k < maxk; k++) { const uchar* sptr_k = sptr + j + space_ofs[k]; int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; float w = space_weight[k] * color_weight[std::abs(b - b0) + std::abs(g - g0) + std::abs(r - r0)]; sum_b += b * w; sum_g += g * w; sum_r += r * w; wsum += w; } wsum = 1.f / wsum; b0 = cvRound(sum_b*wsum); g0 = cvRound(sum_g*wsum); r0 = cvRound(sum_r*wsum); dptr[j] = (uchar)b0; dptr[j + 1] = (uchar)g0; dptr[j + 2] = (uchar)r0; } } } }

inline uint64_t MurmurHash(const void* srcData, int len) { const uint32_t m = 0x5bd1e995; const uint32_t seed = 97; const int r = 24; uint32_t h1 = seed ^ len; uint32_t h2 = 0; uint64_t h = 0; const uint32_t* data = (const uint32_t*)srcData; while (len >= 8) { uint32_t k1 = *data++; k1 *= m; k1 ^= k1 >> r; k1 *= m; h1 *= m; h1 ^= k1; len -= 4; uint32_t k2 = *data++; k2 *= m; k2 ^= k2 >> r; k2 *= m; h2 *= m; h2 ^= k2; len -= 4; } if (len >= 4) { uint32_t k1 = *data++; k1 *= m; k1 ^= k1 >> r; k1 *= m; h1 *= m; h1 ^= k1; len -= 4; } switch (len) { case 3: h2 ^= ((unsigned char*)data)[2] << 16; case 2: h2 ^= ((unsigned char*)data)[1] << 8; case 1: h2 ^= ((unsigned char*)data)[0]; h2 *= m; }; h1 ^= h2 >> 18; h1 *= m; h2 ^= h1 >> 22; h2 *= m; h1 ^= h2 >> 17; h1 *= m; h2 ^= h1 >> 19; h2 *= m; h = h1; h = (h << 32) | h2; h = (h) & 0x7FFFFFFFFFFFFFFF; return h; } inline uint64_t calPointMurmurHash(const PointF* input, uint32_t num) { if (input == nullptr) { return 0; } uint64_t hash = 0; int dlen = sizeof(float) * 2 * num; float* src = new float[2 * num]; if (!src) { return 0; } for (std::size_t i = 0; i < num; ++i) { src[2 * i] = input[i].x(); src[2 * i + 1] = input[i].y(); } hash = MurmurHash(src, dlen); delete[] src; src = nullptr; return hash; } inline uint64_t calPointMurmurHash(const std::vector& input) { return calPointMurmurHash(input.data(), input.size()); } inline uint64_t calPoseMurmurHash(const std::vector& input) { uint64_t hash = 0; int dlen = sizeof(float) * 2 * input.size(); float* src = new float[2 * input.size()]; if (!src) { return 0; } for (std::size_t i = 0; i < input.size(); ++i) { src[2 * i] = input[i].point_.x(); src[2 * i + 1] = input[i].point_.y(); } hash = MurmurHash(src, dlen); delete[] src; src = nullptr; return hash; } inline uint64_t calMurmurHash(uint64_t* input, uint32_t size) { uint64_t hash = 0; if (size > 0) hash = MurmurHash(input, size); return hash; }转换成python

最新推荐

recommend-type

婚纱摄影公司网络推广人员工作绩效说明.docx

婚纱摄影公司网络推广人员工作绩效说明.docx
recommend-type

VC图像编程全面资料及程序汇总

【标题】:"精通VC图像编程资料全览" 【知识点】: VC即Visual C++,是微软公司推出的一个集成开发环境(IDE),专门用于C++语言的开发。VC图像编程涉及到如何在VC++开发环境中处理和操作图像。在VC图像编程中,开发者通常会使用到Windows API中的GDI(图形设备接口)或GDI+来进行图形绘制,以及DirectX中的Direct2D或DirectDraw进行更高级的图形处理。 1. GDI(图形设备接口): - GDI是Windows操作系统提供的一套应用程序接口,它允许应用程序通过设备无关的方式绘制图形。 - 在VC图像编程中,主要使用CDC类(设备上下文类)来调用GDI函数进行绘制,比如绘制线条、填充颜色、显示文本等。 - CDC类提供了很多函数,比如`MoveTo`、`LineTo`、`Rectangle`、`Ellipse`、`Polygon`等,用于绘制基本的图形。 - 对于图像处理,可以使用`StretchBlt`、`BitBlt`、`TransparentBlt`等函数进行图像的位块传输。 2. GDI+: - GDI+是GDI的后继技术,提供了更丰富的图形处理功能。 - GDI+通过使用`Graphics`类来提供图像的绘制、文本的渲染、图像的处理和颜色管理等功能。 - GDI+引入了对矢量图形、渐变色、复杂的文本格式和坐标空间等更高级的图形处理功能。 - `Image`类是GDI+中用于图像操作的基础类,通过它可以进行图像的加载、保存、旋转、缩放等操作。 3. DirectX: - DirectX是微软推出的一系列API集合,用于在Windows平台上进行高性能多媒体编程。 - DirectX中的Direct2D是用于硬件加速的二维图形API,专门用于UI元素和简单的图形渲染。 - DirectDraw主要用于硬件加速的位图操作,比如全屏游戏开发中的画面渲染。 4. 位图操作: - 在VC图像编程中,位图操作是一个重要的部分。需要了解如何加载、保存和处理位图(BMP)文件。 - 可以使用位图文件格式的解析,来访问位图的像素数据,进行像素级别的图像处理和修改。 5. 高级图像处理技术: - 包括图像滤镜、图像转换、图像压缩和解压缩技术。 - 需要掌握一些图像处理算法,比如卷积、FFT(快速傅里叶变换)、DCT(离散余弦变换)等。 - 了解图像的色彩空间转换,比如RGB到YUV的转换,这在视频处理中非常重要。 6. 图像库的使用: - 除了直接使用API进行图像处理之外,还可以使用开源的图像处理库,如OpenCV。 - OpenCV是一个跨平台的计算机视觉和机器学习软件库,它提供了很多高级的图像处理功能。 【压缩包子文件的文件名称列表】: VC++ 文件名称列表显示为"VC++",这表明文件包中可能包含了Visual C++的项目、源代码文件、动态链接库(DLLs)、编译器设置、链接器设置等。如果要使用这些文件进行VC图像编程,需要确保Visual C++开发环境已经安装并且配置好,同时需要安装好所有依赖的库和工具。 要开始VC图像编程,开发者需要具备C++编程基础,熟悉Windows编程概念,并且对图形学有一定的了解。掌握VC图像编程技巧,对于进行桌面应用程序开发、图像处理软件开发以及游戏开发等都是至关重要的。
recommend-type

Pokemmo响应速度翻倍:多线程处理的高级技巧

# 摘要 多线程处理是提高软件并发性能和响应速度的关键技术,本文从基础概念与优势出发,深入探讨了多线程的实现机制,包括线程模型、调度算法、编程关键技术、线程安全性最佳实践、死锁预防与处理等方面。通
recommend-type

人名列表滚动抽奖

<think>嗯,用户想实现一个滚动抽奖功能,需要前端动画效果和随机选择逻辑。首先,我得考虑前端怎么实现滚动效果。可能用CSS动画或者JavaScript的requestAnimationFrame?比如,使用CSS的@keyframes来控制位移,或者用JS动态更新样式。然后,随机选择算法,可能需要确保公平性,比如用Fisher-Yates洗牌算法,或者用Math.random()来生成随机索引。然后,用户可能需要平滑的滚动动画,比如先快速滚动,然后逐渐减速,最后停在选中的人名上。这可能需要设置定时器,逐步改变位置,或者使用CSS过渡效果。另外,还要考虑性能,避免页面卡顿,可能需要使用硬件加
recommend-type

一站式JSF开发环境:即解压即用JAR包

标题:“jsf开发完整JAR包”所指的知识点: 1. JSF全称JavaServer Faces,是Java EE(现EE4J)规范之一,用于简化Java Web应用中基于组件的用户界面构建。JSF提供了一种模型-视图-控制器(MVC)架构的实现,使得开发者可以将业务逻辑与页面表示分离。 2. “开发完整包”意味着这个JAR包包含了JSF开发所需的所有类库和资源文件。通常来说,一个完整的JSF包会包含核心的JSF库,以及一些可选的扩展库,例如PrimeFaces、RichFaces等,这些扩展库提供了额外的用户界面组件。 3. 在一个项目中使用JSF,开发者无需单独添加每个必要的JAR文件到项目的构建路径中。因为打包成一个完整的JAR包后,所有这些依赖都被整合在一起,极大地方便了开发者的部署工作。 4. “解压之后就可以直接导入工程中使用”表明这个JAR包是一个可执行的归档文件,可能是一个EAR包或者一个可直接部署的Java应用包。解压后,开发者只需将其内容导入到他们的IDE(如Eclipse或IntelliJ IDEA)中,或者将其放置在Web应用服务器的正确目录下,就可以立即进行开发。 描述中所指的知识点: 1. “解压之后就可以直接导入工程中使用”说明这个JAR包是预先配置好的,它可能包含了所有必要的配置文件,例如web.xml、faces-config.xml等,这些文件是JSF项目运行所必需的。 2. 直接使用意味着减少了开发者配置环境和处理依赖的时间,有助于提高开发效率。 标签“jsf jar包”所指的知识点: 1. 标签指明了JAR包的内容是专门针对JSF框架的。因此,这个JAR包包含了JSF规范所定义的API以及可能包含的具体实现,比如Mojarra或MyFaces。 2. “jar包”是一种Java平台的归档文件格式,用于聚合多个文件到一个文件中。在JSF开发中,JAR文件经常被用来打包和分发库或应用程序。 文件名称列表“jsf”所指的知识点: 1. “jsf”文件名可能意味着这是JSF开发的核心库,它应该包含了所有核心的JavaServer Faces类文件以及资源文件。 2. 如果是使用特定版本的JSF,例如“jsf-2.2.jar”,则表明文件内包含了对应版本的JSF实现。这种情况下,开发者必须确认他们所使用的Web服务器或应用程序服务器支持该版本的JSF。 3. 文件名称也可能是“jsf-components.jar”、“jsf-impl.jar”等,表明这个JAR包是JSF的一个子模块或特定功能组件。例如,“jsf-components.jar”可能包含了一系列用于在JSF应用中使用的自定义组件。 4. 对于开发者而言,了解文件名称中所蕴含的信息非常重要,因为这将决定他们需要下载哪些JAR包来满足特定项目的需求。 综合以上信息,开发者在使用JSF进行Java Web应用开发时,会通过一个预先配置好的JAR包来快速地搭建和启动项目。这样做不仅简化了项目初始化的过程,也使得开发者能够更加聚焦于业务逻辑的实现和界面设计,而不必深究底层框架配置的细节。
recommend-type

Pokemmo内存优化揭秘:专家教你如何降低50%资源消耗

# 摘要 本文综述了Pokemmo游戏的内存优化方法,从内存管理基础出发,探讨内存使用效率的影响因素,并介绍了性能监控与分析工具。在内存优化实践技巧章节中,详细讨论了代码层面的优化、数据结构和算法选择对内存效率的影响,并通过案例分析展示了实际的优化过程。针对Pokemmo游戏特点,分析了内存消耗特性并提出了特定优化技术。最后,本文展望了未来内存管理技术的发展方向,以及游戏开发中面临的新挑战,为Pokemmo及类似游戏提供了优化建议。 # 关键字 内存优化;内存管理;性能监控;数据结构;算法效率;游戏开发 参考资源链接:[Pokemmo必备资源包:四种ROM与汉化补丁](https://we
recommend-type

直接访问子路由是吧

<think>我们正在使用Vue2,因此需要参考VueRouterv3的文档(因为Vue2对应VueRouterv3,Vue3对应VueRouterv4)。用户的问题是:如何配置路由以支持直接访问子路由?即,在Vue2中,我们希望直接通过URL访问嵌套的子路由(例如:/parent/child),而不仅仅是先访问父路由再导航到子路由。根据之前的回答和引用,我们已经知道:1.在父路由的配置中,使用`children`数组来定义子路由。2.子路由的`path`不能以斜杠开头(例如:'child'而不是'/child'),这样它就会基于父路由的路径进行拼接。3.在父组件的模板中放置`<router-
recommend-type

C++函数库查询辞典使用指南与功能介绍

标题中提到的“C++函数库查询辞典”指的是一个参考工具书或者是一个软件应用,专门用来查询C++编程语言中提供的标准库中的函数。C++是一种静态类型、编译式、通用编程语言,它支持多种编程范式,包括过程化、面向对象和泛型编程。C++标准库是一组包含函数、类、迭代器和模板的库,它为C++程序员提供标准算法和数据结构。 描述中提供的内容并没有给出实际的知识点,只是重复了标题的内容,并且有一串无关的字符“sdfsdfsdffffffffffffffffff”,因此这部分内容无法提供有价值的信息。 标签“C++ 函数库 查询辞典”强调了该工具的用途,即帮助开发者查询C++的标准库函数。它可能包含每个函数的详细说明、语法、使用方法、参数说明以及示例代码等,是学习和开发过程中不可或缺的参考资源。 文件名称“c++函数库查询辞典.exe”表明这是一个可执行程序。在Windows操作系统中,以“.exe”结尾的文件通常是可执行程序。这意味着用户可以通过双击或者命令行工具来运行这个程序,进而使用其中的查询功能查找C++标准库中各类函数的详细信息。 详细知识点如下: 1. C++标准库的组成: C++标准库由多个组件构成,包括输入输出流(iostream)、算法(algorithm)、容器(container)、迭代器(iterator)、字符串处理(string)、数值计算(numeric)、本地化(locale)等。 2. 输入输出流(iostream)库: 提供输入输出操作的基本功能。使用诸如iostream、fstream、sstream等头文件中的类和对象(如cin, cout, cerr等)来实现基本的输入输出操作。 3. 算法(algorithm)库: 包含对容器进行操作的大量模板函数,如排序(sort)、查找(find)、拷贝(copy)等。 4. 容器(container)库: 提供各种数据结构,如向量(vector)、列表(list)、队列(queue)、映射(map)等。 5. 迭代器(iterator): 迭代器提供了一种方法来访问容器中的元素,同时隐藏了容器的内部结构。 6. 字符串处理(string)库: C++标准库中的字符串类提供了丰富的功能用于处理字符串。 7. 数值计算(numeric)库: 提供数值计算所需的函数和类,比如对复数的支持和数值算法。 8. 本地化(locale)库: 提供本地化相关的功能,比如日期、时间的格式化显示以及字符的本地化比较。 9. 错误处理和异常: C++通过throw、try、catch关键字和标准异常类提供了一套异常处理机制。 10. 智能指针: C++11及其后续版本提供了智能指针(如unique_ptr、shared_ptr、weak_ptr)来自动管理动态分配的内存。 11. lambda表达式: 在C++11中引入,允许临时创建匿名函数对象。 12. C++11新特性: 包括范围for循环、移动语义、类内初始化器、auto类型推导等。 使用C++函数库查询辞典的用户可能需要对C++的基础知识有一定的掌握,例如变量、数据类型、控制结构、函数以及面向对象的概念等。了解C++标准库的结构和内容能够帮助程序员有效地利用库函数进行软件开发,提高编程效率并减少重复造轮子的工作。 总结来说,一个C++函数库查询辞典工具对于C++程序员来说是一个非常有用的资源,它能够提供快速查找标准库函数的能力,帮助程序员更高效地解决问题和进行学习。同时,随着C++标准的不断更新,例如C++11、C++14、C++17和C++20,函数库查询辞典也会不断地更新以包含新的特性,这对于紧跟技术发展的开发者来说尤为重要。
recommend-type

【bat脚本安全最佳实践】:保护你的系统与脚本安全的黄金法则

# 摘要 本文旨在全面阐述BAT脚本的基础知识、安全编写原则、审查与优化方法以及在企业环境中的安全应用。通过深入分析脚本安全基础、常见安全陷阱及脚本的权限管理,文章提出了安全编写的具体实践和预防措施。本文详细介绍了脚本安全审查流程、代码优化、错误处理和安全更新维护策略。在企业应用方面,探讨了企业安全政策制定、脚本审计和版本控制以及外部威胁的防范措施。通过案例分析,总结了脚本
recommend-type

IIC抽电

<think>首先,用户的问题是:“请问IIC电路供电问题”。这看起来是关于IIC(Inter-IntegratedCircuit)总线的电源供应问题。IIC是一种串行通信总线,常用于微控制器和外设之间的通信。从系统级指令:-所有行内数学表达式必须使用$...$格式。-独立公式必须使用$$...$$格式并单独成段。-使用中文回答。-生成相关问题。-回答中引用的段落末尾自然地添加引用标识。-回答结构清晰,帮助用户逐步解决问题。参考提供的引用:-引用[1]提到IIC总线注意事项,包括热插拔问题和电源干扰。-引用[2]是关于IIC原理的代码片段。-引用[3]讨论实时时钟RTC,提到PCF85063A