#include "rms_dll.h" #include "QString" #define SIZE 15 //迭代次数 #define MATSIZE 201 //总宽高 #define EDGE 40 //边 #define HALFMATSIZE 101 #include #include #include double biggest; double smallest; QImage image(450, 450, QImage::Format_RGB32); // 创建一个450x400的QImage对象 QImage imageRGB(MATSIZE,MATSIZE,QImage::Format_RGB32); QImage imageRGBS(242,242,QImage::Format_RGB32); int bos = 60; RMS_Dll::RMS_Dll() { _Socket = new QTcpSocket(); } RMS_Dll::add(int a, int b) { return a+b; } //实现接口连接探头,返回是否连接成功 bool RMS_Dll::RMS_Connect(QString IP, quint16 Port) { //return 1; bool ret = false; //取消已有的连接 _Socket->abort(); //连接服务器 _Socket->connectToHost(IP, Port); bool isconnect = _Socket->waitForConnected();//等待直到连接成功 //如果连接成功 if (isconnect) { ret = true; //接收缓冲区(服务器)信息 //connect(_Socket, &QTcpSocket::readyRead, this, &TCPIPClient::ReadData); } return ret; } void RMS_Dll::RMS_Disconnect() { _Socket->disconnectFromHost(); } bool RMS_Dll::RMS_Read_Empty() { dataInsert.clear(); x.clear(); biggest = 0; smallest = 0; ave = 0; modeImage = 0; stdDev = 0; image.fill(0); imageRGB.fill(0); imageRGBS.fill(0); QString Cmd = "EQINT,\rMRPMS,1,\r\n"; bool ret = false; QByteArray data = Cmd.toLatin1(); _Socket->write(data); //判断是否写入成功 bool isWrite = _Socket->waitForBytesWritten(); if (isWrite) { //写入成功 ret = true; }else { return 0; } if(ret == true) { QString Str; bool isRead = _Socket->waitForReadyRead(); if(isRead) { QByteArray Buff = _Socket->readAll(); if (!Buff.isEmpty()) { Str = QString(Buff); } } return 1; }else { return 0; } } double RMS_Dll::RMS_Read_Single() { QString Cmd = "EQINT,\rMRPMS,1,\r\n"; bool ret = false; QByteArray data = Cmd.toLatin1(); _Socket->write(data); //判断是否写入成功 bool isWrite = _Socket->waitForBytesWritten(); if (isWrite) { //写入成功 ret = true; }else { return 0; } if(ret == true) { QString Str; bool isRead = _Socket->waitForReadyRead(); if(isRead) { QByteArray Buff = _Socket->readAll(); if (!Buff.isEmpty()) { Str = QString(Buff); } } Str.chop(3); int StartIndex = Str.lastIndexOf(","); int StopIndex = Str.count() - 1; QString DisPlayStr = Str.mid(StartIndex + 1, StopIndex); return DisPlayStr.toDouble(); } } //实现接口进行读取,并返回是否读取成功 bool RMS_Dll::RMS_Read(int cx, int cy) { QString Cmd = "EQINT,\rMRPMS,1,\r\n"; bool ret = false; QByteArray data = Cmd.toLatin1(); _Socket->write(data); //判断是否写入成功 bool isWrite = _Socket->waitForBytesWritten(); if (isWrite) { //写入成功 ret = true; }else { return 0; } if(ret == true) { QString Str; bool isRead = _Socket->waitForReadyRead(); if(isRead) { QByteArray Buff = _Socket->readAll(); if (!Buff.isEmpty()) { Str = QString(Buff); } } Str.chop(3); int StartIndex = Str.lastIndexOf(","); int StopIndex = Str.count() - 1; QString DisPlayStr = Str.mid(StartIndex + 1, StopIndex); double A; A = DisPlayStr.toDouble(); //存储所有点 x.append(A);///QVector x; QStringList fields; fields.append("1"); fields.append(QString::number(cx,10)); fields.append(QString::number(cy,10)); fields.append(DisPlayStr); dataInsert.append(fields); return 1; }else { return 0; } } //所有点读取完成,调用此接口,进行最大最小值计算并返回 void RMS_Dll::RMS_ACQ(double *max,double *min,double *med,double *mode) { auto max1 = std::max_element(std::begin(x), std::end(x));//最小值表示 auto min1 = std::min_element(std::begin(x), std::end(x));//直接赋值表示 *max = *max1; *min = *min1; int size = x.size(); std::sort(x.begin(), x.end()); // 对QVector进行排序 if (size % 2 == 0) { *med = (x[size / 2 - 1] + x[size / 2]) / 2; // 如果QVector长度为偶数,则返回中间两个数的平均值 } else { *med = x[size / 2]; // 如果QVector长度为奇数,则返回中间的数 } QMap countMap; int maxCount = 0; // 统计每个元素出现的次数 for (int i = 0; i < x.size(); i++) { double key = x.at(i); if (countMap.contains(key)) { countMap[key]++; } else { countMap.insert(key, 1); } } // 找出出现次数最多的元素 QMapIterator iter(countMap); while (iter.hasNext()) { iter.next(); if (iter.value() > maxCount) { maxCount = iter.value(); *mode = iter.key(); modeImage = *mode; } } return; } #include "cmath" void RMS_Dll::RMS_P(double mode,double *Pt,double *Ps,double Pm,double Po) { double t1 = 0.59; double t2 = 59.49; double s1 = 1.48; double s2 = 0.47; *Pt = Pm*(t1*exp(t2/(mode*1000))) + Po; *Ps = s1*(*Pt)+s2; } void trans(float arr[][MATSIZE][MATSIZE])//按真实值排序,范围界定真实值 { std::vector seg; for (int i = EDGE; i < MATSIZE-EDGE; ++i) { for (int j = EDGE; j < MATSIZE-EDGE; ++j) { seg.push_back(arr[SIZE%2][i][j]); } } sort(seg.begin(), seg.end());//按升序排序 #if 1 float small = (float)smallest; float big = (float)biggest; #else if float small = seg[0]; float big = seg[seg.size()-1]; #endif float eighth = (big - small)/8; //qDebug()<< "small:"<= small && arr[SIZE%2][ix][iy]< small+eighth) { //qDebug() <<"blue"; imageRGB.setPixel(iy,ix,qRgb(23,8,255)); imageRGBS.setPixel((iy-40)*2,(ix-40)*2,qRgb(23,8,255)); imageRGBS.setPixel((iy-40)*2+1,(ix-40)*2,qRgb(23,8,255)); imageRGBS.setPixel((iy-40)*2,(ix-40)*2+1,qRgb(23,8,255)); imageRGBS.setPixel((iy-40)*2+1,(ix-40)*2+1,qRgb(23,8,255)); } else if (arr[SIZE%2][ix][iy] >= small+eighth && arr[SIZE%2][ix][iy]= small+eighth*2 && arr[SIZE%2][ix][iy]= small+eighth*3 && arr[SIZE%2][ix][iy]= small+eighth*4 && arr[SIZE%2][ix][iy]= small+eighth*5 && arr[SIZE%2][ix][iy]= small+eighth*6 && arr[SIZE%2][ix][iy]= small+eighth*7 && arr[SIZE%2][ix][iy]<=big) { imageRGB.setPixel(iy,ix,qRgb(196, 0, 0)); imageRGBS.setPixel((iy-40)*2,(ix-40)*2,qRgb(196, 0, 0)); imageRGBS.setPixel((iy-40)*2+1,(ix-40)*2,qRgb(196, 0, 0)); imageRGBS.setPixel((iy-40)*2,(ix-40)*2+1,qRgb(196, 0, 0)); imageRGBS.setPixel((iy-40)*2+1,(ix-40)*2+1,qRgb(196, 0, 0)); } } } } //基函数 float bpline_w_f(float x)//函数返回权重,W(d) { if (x <= 1)//x是d { return 2.0/3.0 - (1.0 - x/2.0)*x*x; } else if (x > 1 && x <= 2) { return (2.0 - x) * (2.0 - x) * (2.0 - x) / 6.0; } return 0.0; } //计算权重系数 void cal_bpline_coeff(float x, float y, float* coeff)//旧float传入 { float u = x - floor(x) + 1;//留小数部分+1 float v = y - floor(y) + 1; float A[4];//计算出四个绝对值,4个d,得出x方向权重保存在数组A A[0] = bpline_w_f(abs(u));//传入距离,传出权重 A[1] = bpline_w_f(abs(u - 1)); A[2] = bpline_w_f(abs(u - 2)); A[3] = bpline_w_f(abs(u - 3)); for (int s = 0; s < 4; s++) { float C = bpline_w_f(abs(v - s));//同理计算y方向权重 coeff[s * 4] = A[0] * C; coeff[s * 4 + 1] = A[1] * C; coeff[s * 4 + 2] = A[2] * C; coeff[s * 4 + 3] = A[3] * C; } //得到的coeff即周围16个点各自的权重(x*y) } //三次B样条插值,得到加权总值//传入新转旧float,得到了其周围16个点的权重,进而得到加权总值 float bpline_inner(float arr[][MATSIZE][MATSIZE], int k ,float x_float, float y_float) { float coeff[16]; cal_bpline_coeff(x_float, y_float, coeff); //计算权重系数 float sum = 0.0; int x0 = floor(x_float) - 1; int y0 = floor(y_float) - 1;//向下取整再减一 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { sum += coeff[i * 4 + j] * arr[k%2][x0 + i][y0 + j];//周围16个点的权重乘以各自的值,加总 } } return sum;//精度的核心就在于这个强转 } float nearst_inner(float arr[][MATSIZE][MATSIZE], int k , float x_float, float y_float) { //若自身不是255,则维持,若自身是255,则选取周围任意非空点 if(arr[k%2][(int)(x_float)][(int)(y_float)] != 255) { return arr[k%2][(int)(x_float)][(int)(y_float)]; }else { if(arr[k%2][(int)(x_float-1)][(int)(y_float-1)] != 255)return arr[k%2][(int)(x_float-1)][(int)(y_float-1)]; if(arr[k%2][(int)(x_float-1)][(int)(y_float)] != 255)return arr[k%2][(int)(x_float-1)][(int)(y_float)]; if(arr[k%2][(int)(x_float-1)][(int)(y_float+1)] != 255)return arr[k%2][(int)(x_float-1)][(int)(y_float+1)]; if(arr[k%2][(int)(x_float+1)][(int)(y_float-1)] != 255)return arr[k%2][(int)(x_float+1)][(int)(y_float-1)]; if(arr[k%2][(int)(x_float+1)][(int)(y_float)] != 255)return arr[k%2][(int)(x_float+1)][(int)(y_float)]; if(arr[k%2][(int)(x_float+1)][(int)(y_float+1)] != 255)return arr[k%2][(int)(x_float+1)][(int)(y_float+1)]; if(arr[k%2][(int)(x_float)][(int)(y_float-1)] != 255)return arr[k%2][(int)(x_float)][(int)(y_float-1)]; if(arr[k%2][(int)(x_float)][(int)(y_float+1)] != 255)return arr[k%2][(int)(x_float)][(int)(y_float+1)]; } return arr[k%2][(int)(x_float)][(int)(y_float)]; } void RMS_Dll::dotToImg() { /*************************************************************** * dotToImg() dotToImg,将点数据转化成热力图 * 输入: * 无 * 输出: * 无 * 描述: * 根据接收到的所有电阻率点的数据进行热力图绘制,数据于dataRecv中 * 逐点读取,生成的热力图保存于imageRGBS **************************************************************/ float Arr[2][MATSIZE][MATSIZE]; //-------------------把src矩阵赋给堆[0]------------------------------ int rows = dataInsert.size();///有几条QStringList,即几个点 for (int x = 0; x < MATSIZE; x++) { for (int y = 0; y < MATSIZE; y++) { Arr[0][x][y] = 255; Arr[1][x][y] = 255; //txtOutput<< "X:"<255 || Arr[1][x][y] == 0) Arr[1][x][y] = 255; } else { //Arr[0][x][y] = bpline_inner(Arr, k, x, y); Arr[0][x][y] = nearst_inner(Arr, k, x, y); //if(isnan(Arr[0][x][y]) == 1 || Arr[0][x][y]>255 || Arr[0][x][y] == 0) Arr[0][x][y] = 255; } } } } for(int k = 0;k<4;k++) { for (int x = 5; x < MATSIZE-5; x++) { for (int y = 5; y < MATSIZE-5; y++) { if(k%2 == 0) { Arr[1][x][y] = bpline_inner(Arr, k, x, y);//k是偶数,则数据源为 Arr0 //if(isnan(Arr[1][x][y]) == 1 || Arr[1][x][y]>255 || Arr[1][x][y] == 0) Arr[1][x][y] = 255; } else { Arr[0][x][y] = bpline_inner(Arr, k, x, y); //if(isnan(Arr[0][x][y]) == 1 || Arr[0][x][y]>255 || Arr[0][x][y] == 0) Arr[0][x][y] = 255; } } } } float ary90[MATSIZE][MATSIZE]; //旋转数组 for (int i = 0; i < MATSIZE; i++) { for (int j = 0; j < MATSIZE; j++) { //ary90[j][MATSIZE - i - 1] = Arr[SIZE%2][i][j];//顺时针90度 ary90[MATSIZE - j - 1][i] = Arr[SIZE%2][i][j];//逆时针90度 } } for (int i = 0; i < MATSIZE; i++) { for (int j = 0; j < MATSIZE; j++) { Arr[SIZE%2][i][j] = ary90[i][j]; } } trans(Arr); } void RMS_Dll::Algo() { /*************************************************************** * 名称:Algo() * 功能:将热力图绘制在窗口上 * 输入: * 无 * 输出: * 无 * 描述: * 根据imageRGBS进行热力图的显示,并画出坐标系 * **************************************************************/ biggest*=10000; smallest*=10000; //qDebug()<& data) { double sum = 0.0; for (double value : data) { sum += value; } return sum / data.size(); } double calculate_standard_deviation(const QVector& data) { if (data.size() < 2) { return 0; // 如果数据点少于两个,则标准差为 0 } double mean = calculate_mean(data); double variance = 0.0; for (double value : data) { variance += std::pow(value*1000 - mean*1000, 2);//为了放大标准差*1000 } variance /= data.size(); return std::sqrt(variance); } QImage RMS_Dll::RMS_Image(int size) { // QString fileName = "D:/PYpro/002-NSC-6-230501.csv"; // QFile file(fileName); // 新建QFile对象 // if (!file.open(QFile::ReadOnly | QFile::Text)) // { // } // QTextStream in(&file);///文件流in // while (!in.atEnd()) // { // QString line = in.readLine();///一行一行的读取 // QStringList fields; // fields.append("1"); // fields.append(line.split(","));///逗号分隔123元素 // double A = (fields.at(3)).toDouble();//获取该行第3个单元格内容 // x.append(A);///QVector x; // dataInsert.append(fields); // } ave = calculate_mean(x); stdDev = calculate_standard_deviation(x); bos = size; auto max = std::max_element(std::begin(x), std::end(x));//最小值表示 auto min = std::min_element(std::begin(x), std::end(x));//直接赋值表示 biggest = *max; smallest = *min; Algo(); //file.close(); return image; }