#pragma once #include <QtWidgets/QMainWindow> #include "ui_mvCameraWidgets.h" #include "mvCamera.h" #include <QRect> #include<opencv2/opencv.hpp> #include<QPainter> #include <QWindow> #include <QScreen> #include <QDesktopWidget> #include <QGradient> #include <QVector> #include "roiAnalyse.h" //test #include <stdio.h> #include <stdlib.h> #include <math.h> #include <QtGui/QtGui> // #define WIDTH 800 // #define HEIGHT 600 // #define PI 3.14159265 //test end #include "mymethod.h" using namespace cv; using namespace std; class mvCameraWidgets : public QMainWindow { Q_OBJECT public: mvCameraWidgets(QWidget *parent = nullptr); ~mvCameraWidgets(); void paintEvent(QPaintEvent *event) override; // 重绘事件 private slots: void on_pushButton_getimagebuffer_clicked(); void on_pushButton_callbackimagebuffer_clicked(); void on_pushButton_getroibuffer_clicked(); void on_pushButton_readimg_clicked(); void on_pushButton_savemat_clicked(); void on_pushButton_colormap_clicked(); void on_pushButton_gray_clicked(); void on_lineEdit_down_returnPressed(); void on_lineEdit_up_returnPressed(); void on_pushButton_contiue_clicked(); void on_pushButton_point_frequency_clicked(); void on_lineEdit_N_returnPressed(); void on_pushButton_test_clicked(); void on_pushButton_test_2_clicked(); void on_pushButton_test_3_clicked(); void on_pushButton_test_4_clicked(); void on_pushButton_test_5_clicked(); void on_pushButton_test_6_clicked(); void on_pushButton_test_7_clicked();//固定输入数据,测试扫频结果 void on_pushButton_test_8_clicked();//固定输入数据,测试点频结果 void on_pushButton_test_dft_clicked();//dft 傅里叶变换 void on_pushButton_test_color_clicked();//磁场矢量伪彩图 void on_pushButton_test_9_clicked();//曲线拟合 void on_pushButton_roiSet_clicked(); void on_pushButton_save16Mat_clicked(); void on_pushButton_read16Mat_clicked(); void on_pushButton_readRaw_clicked(); void on_pushButton_readparams_clicked(); private: private: Ui::mvCameraWidgetsClass ui; mvCamera myCamera; mymethod method; double down; double up; int N; unsigned char *tmp_RawBuffer;//原数据缓存区 roiAnalyse *new_roiAnalyse; //test QVector<QVector<int>> fn_12int; };
#include "mvCameraWidgets.h" mvCameraWidgets::mvCameraWidgets(QWidget *parent) : QMainWindow(parent) { //初始化相机 if (myCamera.init_Camera()==-1) { // return; } //设置相机分辨 QRect roi = QRect(0, 0, 2448, 2048); myCamera.set_Image_Resolution_roi(roi); myCamera.set_Exposure_time(300); ui.setupUi(this); setWindowTitle("平台项目"); //比色卡相关初始化 down = 100.0; up = 400.0; ui.lineEdit_down->setText("100"); ui.lineEdit_up->setText("400"); N = 4; ui.lineEdit_N->setText("4"); //数据缓存相关初始化 tmp_RawBuffer = (unsigned char *)malloc(myCamera.m_buffersize); } mvCameraWidgets::~mvCameraWidgets() { if (tmp_RawBuffer != NULL) { free(tmp_RawBuffer); tmp_RawBuffer = NULL; } } double Bx(double x, double y) { // 计算x方向的磁场分量 return -y / (x*x + y * y); } double By(double x, double y) { // 计算y方向的磁场分量 return x / (x*x + y * y); } void FitPolynomialCurve(const std::vector<cv::Point>& points, int n, cv::Mat& A) { //最小二乘法多项式曲线拟合原理与实现 https://blog.csdn.net/jairuschan/article/details/7517773/ //https://www.cnblogs.com/fengliu-/p/8031406.html int N = points.size(); cv::Mat X = cv::Mat::zeros(n + 1, n + 1, CV_64FC1); for (int i = 0; i < n + 1; i++) { for (int j = 0; j < n + 1; j++) { for (int k = 0; k < N; k++) { X.at<double>(i, j) = X.at<double>(i, j) + std::pow(points[k].x, i + j); } } } cv::Mat Y = cv::Mat::zeros(n + 1, 1, CV_64FC1); for (int i = 0; i < n + 1; i++) { for (int k = 0; k < N; k++) { Y.at<double>(i, 0) = Y.at<double>(i, 0) + std::pow(points[k].x, i) * points[k].y; } } A = cv::Mat::zeros(n + 1, 1, CV_64FC1); cv::solve(X, Y, A, cv::DECOMP_LU); } void mvCameraWidgets::paintEvent(QPaintEvent * event) { //设置比色卡 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing);//反锯齿 int x = ui.colormap->x(); int y = ui.colormap->y(); int w = ui.colormap->rect().width(); int h = ui.colormap->rect().height(); QLinearGradient linearGradient(0, y, 0, y+h);//渐变区域 linearGradient.setColorAt(0, Qt::red); linearGradient.setColorAt(0.5, Qt::blue); linearGradient.setColorAt(1, Qt::green); // QFont ft = painter.font(); // ft.setPixelSize(60); // painter.setFont(ft); // QFontMetrics fm(ft); // QRect rt = fm.boundingRect(ui.colormap->rect(), Qt::AlignCenter, "TEST"); // QPainterPath path; // path.addText(rt.bottomLeft(), ft, "TEST"); // painter.fillPath(path, linearGradient); //painter.strokePath(path, QPen(Qt::darkMagenta, 1));//字体边框 painter.setBrush(linearGradient);//设置画刷,则painter.drawRect(rect());绘制出渐变背景 painter.drawRect(QRect(x,y,w,h)); //painter.drawRect(QRect(0,0,w,h)); } void mvCameraWidgets::on_pushButton_getimagebuffer_clicked() { //设置连续触发模式 if (myCamera.set_Trigger_Mode(0)!=0) { return; } //获得相机分辨率 QRect roi; myCamera.get_Image_Resolution(roi); //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); QVector<int> v_12int; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); Mat a; mymethod::rawChangetoMat(tmp_RawBuffer, roi.width(), roi.height(), a); a = a / a; cv::Mat inImage; cv::Scalar neam = cv::mean(a); double MyMeanValue = neam.val[0];//.val[0]表示第一个通道的均值 float scale = 255.0 / 4096.0; Mat b; a.convertTo(b, CV_32F, scale, 0); QVector<float> raw_3; for (int i = 0; i < b.rows; i++) { for (int j = 0; j < b.cols; j++) { raw_3.push_back(b.at<float>(i, j)); } } imwrite("img/raw2mat.png", b); QImage img; img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_12int); img.save("img/imgbuffer.png"); img.save("img/imgbuffer1.bmp"); // QVector<unsigned char>tmp; // for (int i = 0; i < 100; ++i) // { // tmp.push_back(c_Raw[i]); // } //读取图像数据 // QVector<unsigned char>tmpimg; // int imgh = img.height(); // int imgw = img.width(); // for (int y = 0; y < img.height(); y++) // { // QRgb* line = (QRgb *)img.scanLine(y);//读取行 // for (int x = 0; x < img.width(); x++) // { // tmpimg.push_back(line[x]); // } // // } return; } void mvCameraWidgets::on_pushButton_callbackimagebuffer_clicked() { //获得相机分辨率 QRect roi; myCamera.get_Image_Resolution(roi); myCamera.set_Callback_Function(); while (!myCamera.m_RawBuffer_Queue.isEmpty()) { myCamera.m_RawBuffer = myCamera.m_RawBuffer_Queue.front(); myCamera.m_RawBuffer_Queue.pop_front();//弹出队列操作 QVector<int> v_12int; mymethod::rawChangetoInt(myCamera.m_RawBuffer, roi.width(), roi.height(), v_12int); QImage img; img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_12int); img.save("img/imgbuffercallback.png"); //读取图像数据 // QVector<unsigned char>tmpimg; // int imgh = img.height(); // int imgw = img.width(); // for (int y = 0; y < img.height(); y++) // { // QRgb* line = (QRgb *)img.scanLine(y);//读取行 // for (int x = 0; x < img.width(); x++) // { // tmpimg.push_back(line[x]); // } // // } } return; } void mvCameraWidgets::on_pushButton_getroibuffer_clicked() { QRect roi; myCamera.get_Image_Resolution(roi); //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); QVector<int> v_12int; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); QVector<int> v_12int_roi; QRect roi2 = QRect(0, 0, 1920, 1080); mymethod::intChangetoRoiInt(roi.width(), roi.height(), v_12int, roi2, v_12int_roi); QImage img; img = mymethod::intChangetoQimg(roi2.width(), roi2.height(), v_12int_roi); img.save("img/imgbufferROI.png"); // QVector<unsigned char>tmp; // for (int i = 0; i < 100; ++i) // { // tmp.push_back(c_Raw[i]); // } // //读取图像数据 // QVector<unsigned char>tmpimg; // int imgh = img.height(); // int imgw = img.width(); // for (int y = 0; y < img.height(); y++) // { // QRgb* line = (QRgb *)img.scanLine(y);//读取行 // for (int x = 0; x < img.width(); x++) // { // tmpimg.push_back(line[x]); // } // // } return; } void mvCameraWidgets::on_pushButton_readimg_clicked() { cv::Mat image; //创建一个空图像image image = imread("img/snapmat.png", IMREAD_UNCHANGED); //读取文件夹中的图像 //mat to char* int nHeight = image.rows; int nWidth = image.cols; int nBytes = nHeight * nWidth ;//图像总的字节 unsigned char* readmata = new unsigned char[nBytes]; memcpy(readmata, image.data, nBytes);//转化函数,注意Mat的data成员 QImage readimg; QVector <int> v_12int; mymethod::rawChangetoInt(readmata,nWidth/3*2,nHeight, v_12int); readimg = mymethod::intChangetoQimg(nWidth /3*2, nHeight, v_12int); readimg.save("img/readimg.png"); } void mvCameraWidgets::on_pushButton_savemat_clicked() { Mat img0 = myCamera.snapmat(); imwrite("img/snapmat.png", img0); imwrite("img/snapmat1.bmp", img0); } void mvCameraWidgets::on_pushButton_colormap_clicked() { //构造磁场强度信息 QRect roi; myCamera.get_Image_Resolution(roi); int w_pic = roi.width(); int h_pic = roi.height(); w_pic = 2000; h_pic = 2000; QVector<double> magnetic_strength; for (int y = 0; y < h_pic; y++) { for (int x = 0; x < w_pic; x++) { double d = (double)(x/5.0) ; magnetic_strength.push_back(d); } } // if (myCamera.get_Image_Buffer() != 0) // { // return; // } // QVector<int> v_12int; // if (myCamera.method_Raw_12int(v_12int) != 0) // { // return; // } // magnetic_strength.clear(); // for (int i = 0; i < v_12int.size(); i++) // { // magnetic_strength.push_back(v_12int[i]); // } //ui.colormap->setGeometry(50, 50, 50, 100); //开始的位置(50,50),宽高(50,100) //设置渐变图在重写的paintEvent函数里 QPixmap pix = grab(QRect(ui.colormap->x(), ui.colormap->y(), ui.colormap->width(), ui.colormap->height())); QImage image0 = pix.toImage(); image0.save("img/colormap.png"); QImage img = mymethod::intChangetoQcolorimg(w_pic, h_pic, magnetic_strength, down, up, image0); img.save("img/image_mapping.png"); } void mvCameraWidgets::on_pushButton_gray_clicked() { QRect roi; myCamera.get_Image_Resolution(roi); //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); QVector<int> v_12; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12); int w_pic = roi.width(); int h_pic = roi.height(); unsigned char *Buffer; //磁场强度信息值,根据在上下限up,down中比例转换到0-255 Buffer = (unsigned char *)malloc(w_pic*h_pic); for (int i = 0; i < w_pic*h_pic; i++) { int tmp = (int)((double)v_12[i] /(double)4096 * (double)255); uchar utmp = (uchar)tmp; Buffer[i] = utmp; } QImage img = QImage(Buffer, w_pic, h_pic, QImage::Format_Indexed8); //ui.colormap->setGeometry(50, 50, 50, 100); //开始的位置(50,50),宽高(50,100) QVector<QRgb> grayColourTable; for (int i = 0; i < 256; i++) { grayColourTable.append(qRgb(i, i, i)); } img.setColorTable(grayColourTable); img.save("img/image_gray.png"); free(Buffer); } void mvCameraWidgets::on_lineEdit_down_returnPressed() { QString value = ui.lineEdit_down->text(); down = value.toInt(); } void mvCameraWidgets::on_lineEdit_up_returnPressed() { QString value = ui.lineEdit_up->text(); up = value.toInt(); } void mvCameraWidgets::on_pushButton_contiue_clicked() { QRect roi; myCamera.get_Image_Resolution(roi); //fo-fn 扫频一次结果,一个频率采一张图 int fn = 10; QVector<QPoint> m_avr; for (int i=0;i<fn;i++) { //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); QVector<int> v_12int; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); double avr = mymethod::myaverage(v_12int); m_avr.push_back(QPoint(i, avr)); } //写文件 QFile myFile_write("img/imgcontiue.dat"); if (!myFile_write.open(QIODevice::WriteOnly)) { qDebug() << myFile_write.errorString(); } //写文件---可以用作另存 QTextStream textStream_write(&myFile_write); for (int i=0;i< m_avr.size();i++) { double x = m_avr[i].x(); double y = m_avr[i].y(); textStream_write << x; textStream_write << " "; textStream_write << y; textStream_write << "\n"; } textStream_write.flush(); } void mvCameraWidgets::on_pushButton_point_frequency_clicked() { int count = 0; QVector<int>v_molecule; QVector<int>v_denominator; QVector<int>v_add; bool is_initialize = true; QRect roi; myCamera.get_Image_Resolution(roi); QVector<int> v_12int; while (count < N * 2) { //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); if (is_initialize) { for (int i = 0; i < v_12int.size(); ++i) { v_add.push_back(0); } is_initialize = false; } if (count%2==0) { v_molecule = v_12int; } else { v_denominator = v_12int; if (mymethod::mydivisionadd(v_molecule, v_denominator, v_add) != 0) { return; } } count++; } QImage img; img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_add); img.save("img/imgpointfrequency.png"); } void mvCameraWidgets::on_lineEdit_N_returnPressed() { QString value = ui.lineEdit_N->text(); N = value.toInt(); } void mvCameraWidgets::on_pushButton_test_clicked() { QRect roi; myCamera.get_Image_Resolution(roi); //fo-fn 扫频一次结果,一个频率采一张图 int fn = 10; QVector<QPoint> m_avr; QVector<int>op; for (int i = 0; i < fn; i++) { //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); //帧ID int id0 = myCamera.get_Camera_ID(); op.push_back(id0); QVector<int> v_12int; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); fn_12int.push_back(v_12int); double avr = mymethod::myaverage(v_12int); m_avr.push_back(QPoint(i, avr)); } //写文件 QFile myFile_write("img/imgcontiue.dat"); if (!myFile_write.open(QIODevice::WriteOnly)) { qDebug() << myFile_write.errorString(); } //写文件---可以用作另存 QTextStream textStream_write(&myFile_write); for (int i = 0; i < m_avr.size(); i++) { double x = m_avr[i].x(); double y = m_avr[i].y(); textStream_write << x; textStream_write << " "; textStream_write << y; textStream_write << "\n"; } textStream_write.flush(); m_avr.clear(); //设置roi后,重新扫频 for (int i = 0; i < fn; i++) { QVector<int> v_12int_roi; mymethod::intChangetoRoiInt(roi.width(), roi.height(), fn_12int[i], roi,v_12int_roi); double avr = mymethod::myaverage(v_12int_roi); m_avr.push_back(QPoint(i, avr)); } //写文件 QFile myFile_write2("img/imgcontiue_roi.dat"); if (!myFile_write2.open(QIODevice::WriteOnly)) { qDebug() << myFile_write2.errorString(); } //写文件---可以用作另存 QTextStream textStream_write2(&myFile_write2); for (int i = 0; i < m_avr.size(); i++) { double x = m_avr[i].x(); double y = m_avr[i].y(); textStream_write2 << x; textStream_write2 << " "; textStream_write2 << y; textStream_write2 << "\n"; } textStream_write2.flush(); } void mvCameraWidgets::on_pushButton_test_2_clicked() { int count = 0; QVector<int>v_molecule; QVector<int>v_denominator; QVector<int>v_add; bool is_initialize; QRect roi; QImage img; QVector<int> v_12int; myCamera.get_Image_Resolution(roi); is_initialize = true; while (count < N * 2) { //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); if (is_initialize) { for (int i = 0; i < v_12int.size(); ++i) { v_add.push_back(0); } is_initialize = false; } if (count % 2 == 0) { v_molecule = v_12int; } else { v_denominator = v_12int; if (mymethod::mydivisionadd(v_molecule, v_denominator, v_add) != 0) { return; } } count++; } img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_add); img.save("img/imgpointfrequency.png"); for (int i = 0; i < 100; i++) { v_add[i] = 4096; } //重新设置roi QRect roi2 = QRect(0, 0, 100, 100); QVector<int> v_12int_roi; mymethod::intChangetoRoiInt(roi.width(), roi.height(), v_12int, roi2, v_12int_roi); img = mymethod::intChangetoQimg(roi2.width(), roi2.height(), v_12int_roi); img.save("img/imgpointfrequency_roi.png"); } void mvCameraWidgets::on_pushButton_test_3_clicked() { //设置连续触发模式 if (myCamera.set_Trigger_Mode(1) != 0) { return; } if (myCamera.clear_Camera_buffer()!=0) { return; } //获得相机分辨率 QRect roi; myCamera.get_Image_Resolution(roi); //主动获取相机一帧数据,存在m_Rawbuffer for (int i=0 ;i<10;i++) { if (myCamera.set_Camera_softwareonce() != 0) { return; } myCamera.get_Image_Buffer(tmp_RawBuffer); int id0 = myCamera.get_Camera_ID(); QVector<int> v_12int; mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); QImage img; img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_12int); img.save("img/imgbuffer_software.png"); } } void mvCameraWidgets::on_pushButton_test_4_clicked() { // void cv::resize(InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, // int interpolation = INTER_LINEAR) // 参数 // src - 输入图像。 // dst - 输出图像;它的大小为 dsize(当它非零时)或从 src.size()、fx 和 fy 计算的大小;dst 的类型与 src 的类型相同。 // dsize - 输出图像大小;如果它等于零,则计算为:dsize = Size(round(fx*src.cols), round(fy*src.rows))。dsize 或 fx 和 fy 必须为非零。 // fx - 沿水平轴的比例因子;当它等于 0 时,它被计算为(double)dsize.width / src.cols // fy - 沿垂直轴的比例因子;当它等于 0 时,它被计算为(double)dsize.height / src.rows // interpolation - 插值方法 // INTER_NEAREST - 最近邻插值(最近邻插值) - // INTER_LINEAR双线性插值(默认使用) // INTER_AREA - 使用像素区域关系重采样。它可能是图像抽取的首选方法,因为它可以提供无莫尔条纹的结果。 // 但是当图像被缩放时,它类似于 INTER_NEAREST 方法。 // INTER_CUBIC - 4x4 像素邻域上的双三次插值 // INTER_LANCZOS4 - 8x8 像素邻域上的 Lanczos 插值 //Mat image = imread("img/image_mapping.png"); int h = 12; int w = 12; vector<double> raw_image; for (int i = 0; i <h; i++) { for (int j = 0; j < w; j++) { /*image.at<ushort>(i, j)=i+j;*/ /*raw_image.push_back(image.at<ushort>(i, j));*/ raw_image.push_back(i*12+j); } } Mat image = Mat(raw_image); image=image.reshape(0, 12); cout << "zoom= (CSV)" << endl << format(image, Formatter::FMT_CSV) << endl << endl; //缩放Mat Mat zoomin; h = image.rows; w = image.cols; cv::resize(image, zoomin, cv::Size(w / 2, h / 2), 0, 0, cv::INTER_AREA); //缩小到4/1 QVector<double> raw_zoomin; for (int i = 0; i < zoomin.rows; i++) { for (int j = 0; j < zoomin.cols; j++) { raw_zoomin.push_back(zoomin.at<double>(i, j)); } } cout << "zoomin= (CSV)" << endl << format(zoomin, Formatter::FMT_CSV) << endl << endl; cv::Mat resultMat(h, w, CV_64F); resultMat = zoomin / zoomin*255; cout << "devMat= (CSV)" << endl << format(resultMat, Formatter::FMT_CSV) << endl << endl; resultMat.convertTo(resultMat, CV_8UC1); cout << "devMat= (CSV)" << endl << format(resultMat, Formatter::FMT_CSV) << endl << endl; QVector<uchar> raw_tmp; for (int i = 0; i < resultMat.rows; i++) { for (int j = 0; j < resultMat.cols; j++) { double tmp = (resultMat.at<uchar>(i, j)); uchar uc = tmp; } } QImage img((uchar*)resultMat.data, resultMat.cols, resultMat.rows, resultMat.cols * 1, QImage::Format_Grayscale8); QVector<int>tmpvalue; for (int y = 0; y < img.height(); y++) { for (int x = 0; x < img.width(); x++) { // 获取像素值 int pixelValue = qGray(img.pixel(x, y)); tmpvalue.push_back(pixelValue); } } img.save("img/imgTest.png"); return; } void mvCameraWidgets::on_pushButton_test_5_clicked() { int count = 10000000; vector<int>v_tmp; for (int i=0;i<count;++i) { v_tmp.push_back(i); } double v_sum=0.0; double v_avr=0.0; for (int i = 0; i < v_tmp.size(); i++) { v_sum += v_tmp.at(i); } v_avr = v_sum / v_tmp.size(); // QVector<int>Q_tmp; for (int i = 0; i < count; ++i) { Q_tmp.push_back(i); } double Q_sum=0.0; double Q_avr=0.0; for (int i = 0; i < Q_tmp.size(); i++) { Q_sum += Q_tmp.at(i); } Q_avr = Q_sum / Q_tmp.size(); } void mvCameraWidgets::on_pushButton_test_6_clicked() { //设置连续触发模式 if (myCamera.set_Trigger_Mode(0) != 0) { return; } //获得相机分辨率 QRect roi; myCamera.get_Image_Resolution(roi); //主动获取相机一帧数据,存在m_Rawbuffer myCamera.get_Image_Buffer(tmp_RawBuffer); QVector<int> v_12int,v_12int_1; for (int i=0;i<2;++i) { if (i==0) { mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int); } if (i == 1) { mymethod::rawChangetoInt(tmp_RawBuffer, roi.width(), roi.height(), v_12int_1); } } QVector<int>v_add; for (int i=0;i< v_12int.size();++i) { v_add.push_back(0); } mymethod::mydivisionadd(v_12int, v_12int_1, v_add); QImage img; img = mymethod::intChangetoQimg(roi.width(), roi.height(), v_12int); img.save("img/test_1.png"); Mat a; Mat b; a.create(roi.height(), roi.width(), CV_64F); b.create(roi.height(), roi.width(), CV_64F); for (int i = 0; i < 2; ++i) { if (i == 0) { mymethod::rawChangetoMat(tmp_RawBuffer, roi.width(), roi.height(), a); } if (i == 1) { mymethod::rawChangetoMat(tmp_RawBuffer, roi.width(), roi.height(), b); } } Mat c; c= a / b; c = a+b ; float scale = 255.0 / 4096.0; Mat m; a.convertTo(m, CV_8UC1, scale, 0); //注意在QImage的生存周期内,必须保证Mat中的数据不会被释放,否则QImage就会失效 //解决方法:调用QImage::bits函数复制一份Mat数据,这样Mat释放,QImage也能正常使用 QImage img2((uchar *)m.data, m.cols, m.rows, m.cols * 1, QImage::Format_Grayscale8); img2.save("img/test_2.png"); // enum QImage::Format // QImage::Format_Invalid 图像无效 // QImage::Format_Mono 存储使用1位每像素的图像,字节填充最重要位第一 // QImage::Format_MonoLSB 存储使用1位每像素的图像,字节填充不显著位第一 // QImage::Format_Indexed8 图像存储使用8位指标转化成Colormap及需要设定一张颜色表QVector<QRgb> // // QImage::Format_Grayscale8 图像是使用一个8位灰度格式存储,不需要颜色表 // QImage::Format_RGB32 存储使用32位RGB格式的图像(0xffrrggbb) // QImage::Format_ARGB32 存储使用32为ARGB格式的图像(0xaarrggbb) // QImage::Format_ARGB32_Premultiplied 图像存储使用一个自左乘32位ARGB格式 // QImage::Format_RGB16 图像存储使用5 - 6 - 5 16位RGB格式 // QImage::Format_ARGB8565_Premultiplied 图像存储使用一个自左乘24位ARGB格式8 - 5 - 6 - 5 // QImage::Format_RGB666 图像存储使用6 - 6 - 6 24位RGB格式,未使用的最重要的位总是为零 // QImage::Format_ARGB6666_Premultiplied 图像存储使用一个自左乘24位ARGB格式6 - 6 - 6 - 6 // QImage::Format_RGB555 图像存储使用16位RGB格式(5 - 5 - 5),位置用的最重要的始终为零 // QImage::Format_ARGB8555_Premultiplied 图像存储使用一个自左乘24位ARGB格式8 - 5 - 5 - 5 // QImage::Format_RGB888 图像存储使用8 - 8 - 8 24位RGB格式(0xrrggbb) // // QImage::Format_RGB444 图像存储使用16位RGB格式(4 - 4 - 4)未使用的位始终为零 // QImage::Format_ARGB4444_Premultiplied 图像存储使用一个自左乘16位ARGB格式4 - 4 - 4 - 4 // QImage::Format_RGBX8888 图像存储使用32位字节命令RGB(x)格式8 - 8 - 8 - 8 // QImage::Format_RGBA8888 存储使用32位字节命令RGBA格式(8 - 8 - 8 - 8)的的图像 // QImage::Format_RGBA8888_Premultiplied 图像存储使用一个自左乘32位字节命令RGBA格式8 - 8 - 8 - 8 // QImage::Format_BGR30 存储使用32位BGR格式(x - 10 - 10 - 10)的的图像 // QImage::Format_A2BGR30_Premultiplied 图像存储使用32位自左乘abgr格式2 - 10 - 10 - 10 // QImage::Format_RGB30 存储使用32位RGB格式(x - 10 - 10 - 10)的的图像 // QImage::Format_A2RGB30_Premultiplied 图像存储使用2 - 10 - 10 - 10 32位自左乘ARGB格式 // QImage::Format_Alpha8 该图像是使用一个8位的阿尔法格式存储 } void mvCameraWidgets::on_pushButton_test_7_clicked() { //固定数据 QRect roi = QRect(0, 0, 2448, 2048); int w_test = roi.width(); int h_test = roi.height(); unsigned char* testBuffer = (unsigned char *)malloc(w_test*h_test*3); //模拟相机一帧数据testBuffer,全部插入128数据转换为2048,2056 /* a0(128) a1(128) a2(128) 1000 0000 1000 0000 1000 0000 b1=(a0 << 4) | (a1 & 0xf); b2=(a2 << 4) | ((a1 & 0xf0) >> 4); 1000 0000 0000(2048) 1000 0000 1000(2056) */ for (int j = 0; j < w_test*h_test * 3 / 2;j++) { testBuffer[j] = 128; } //fo-fn 扫频 int fn = 10; QVector<QPoint> m_avr; for (int i = 0; i < fn; i++) { QVector<int> v_12int; mymethod::rawChangetoInt(testBuffer, w_test,h_test, v_12int); QRect roi2 = QRect(0, 0, 1000, 1000); QVector<int>v_12roiint; mymethod::intChangetoRoiInt(w_test, h_test, v_12int, roi2, v_12roiint); double avr = mymethod::myaverage(v_12int); m_avr.push_back(QPoint(i, avr)); } //写文件 QFile myFile_write("img/contiue.dat"); if (!myFile_write.open(QIODevice::WriteOnly)) { qDebug() << myFile_write.errorString(); } //写文件---可以用作另存 QTextStream textStream_write(&myFile_write); for (int i = 0; i < m_avr.size(); i++) { double x = m_avr[i].x(); double y = m_avr[i].y(); textStream_write << x; textStream_write << " "; textStream_write << y; textStream_write << "\n"; } textStream_write.flush(); free(testBuffer); testBuffer = NULL; } void mvCameraWidgets::on_pushButton_test_8_clicked() { if (0) { //固定数据 QRect roi = QRect(0, 0, 2448, 2048); int w_test = roi.width(); int h_test = roi.height(); //模拟相机一帧数据testBuffer,全部插入255数据转换为4095,4095 /* a0(128) a1(128) a2(128) 1000 0000 1000 0000 1000 0000 b1=(a0 << 4) | (a1 & 0xf); b2=(a2 << 4) | ((a1 & 0xf0) >> 4); 1000 0000 0000(2048) 1000 0000 1000(2056) */ unsigned char* testBuffer1 = (unsigned char *)malloc(w_test*h_test * 3); for (int j = 0; j < w_test*h_test * 3 / 2; j++) { testBuffer1[j] = 255; } //模拟相机一帧数据testBuffer,,全部插入128数据转换为2048,2056 unsigned char* testBuffer2 = (unsigned char *)malloc(w_test*h_test * 3); for (int j = 0; j < w_test*h_test * 3 / 2; j++) { testBuffer2[j] = 2; } int count = 0; QVector<int>v_molecule; QVector<int>v_denominator; QVector<int>v_add; bool is_initialize; QImage img; is_initialize = true; while (count < N * 2) { if (count % 2 == 0) { mymethod::rawChangetoInt(testBuffer1, roi.width(), roi.height(), v_molecule); } else { mymethod::rawChangetoInt(testBuffer2, roi.width(), roi.height(), v_denominator); if (is_initialize) { for (int i = 0; i < v_denominator.size(); ++i) { v_add.push_back(0); } is_initialize = false; } if (mymethod::mydivisionadd(v_molecule, v_denominator, v_add) != 0) { return; } } count++; } QVector<int>v_12int; for (int i = 0; i < w_test*h_test; ++i) { v_12int.push_back(0); } v_12int[1000] = 4096; img = mymethod::intChangetoQimg(w_test, h_test, v_12int); img.save("img/pointfrequency.png"); free(testBuffer1); testBuffer1 = NULL; free(testBuffer2); testBuffer2 = NULL; } else { unsigned char* m_Bufferoff = (unsigned char *)malloc(2448*2048*3); unsigned char* m_Bufferon = (unsigned char *)malloc(2448 * 2048*3); cv::Mat offMat,onMat,resultMat; mymethod::readRawMat("D:\\syl\\PingtaiProject\\IMGTEST\\dp10\\(off1)2.8633.png", m_Bufferoff); mymethod::rawChangetoMat(m_Bufferoff, 2448, 2048, offMat); mymethod::readRawMat("D:\\syl\\PingtaiProject\\IMGTEST\\dp10\\(on0)2.8633.png", m_Bufferon); mymethod::rawChangetoMat(m_Bufferon, 2448, 2048, onMat); ///==================================================================================/// int m = offMat.rows; int n = offMat.cols; for (int i = 0; i < m; i++) { for (int j = 1; j < n; j++) { // 计算当前元素与前一个元素的差值 double diff = offMat.at<int>(i, j) - offMat.at<int>(i, j - 1); double diff2 = onMat.at<int>(i, j) - onMat.at<int>(i, j - 1); // 将计算结果存入原矩阵a中 offMat.at<int>(i, j - 1) = diff; onMat.at<int>(i, j - 1) = diff2; } // 最后一列的差分值为0,因为没有后续元素了 offMat.at<int>(i, n - 1) = 0; onMat.at<int>(i, n - 1) = 0; } ///==================================================================================/// cv::Mat a = onMat/offMat*255; imwrite("img/absdiff.png", a); a.convertTo(a, CV_64F); cv::Mat binaryImage; double thresh_value = 25; // 指定阈值下限 double max_value = 230; // 指定阈值上限 int threshold_type = cv::THRESH_BINARY; // 设为二元阈值化 // 将所有低于10的像素值都设置为0(黑色),所有高于255的像素值都设置为255(白色)。 cv::threshold(a, a, thresh_value, max_value, cv::THRESH_BINARY); imwrite("img/threshold.png", a); int iterations = 1; // 设定迭代次数 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); // 构造一个 3x3 的结构元素(kernel) // 对输入矩阵执行开运算 cv::erode(a, resultMat, kernel, cv::Point(-1, -1), iterations); cv::dilate(resultMat, resultMat, kernel, cv::Point(-1, -1), iterations); imwrite("img/morphologyEx.png", resultMat); cv::Mat kernel2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); // 构造一个 3x3 的结构元素(kernel) cv::erode(resultMat, resultMat, kernel2, cv::Point(-1, -1), iterations); cv::dilate(resultMat, resultMat, kernel2, cv::Point(-1, -1), iterations); imwrite("img/morphologyEx2.png", resultMat); int rows = resultMat.rows; int cols = resultMat.cols; QVector<double>tmp; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 访问矩阵中的每个像素值并执行操作 tmp.push_back(resultMat.at<double>(i, j)); } } } } void mvCameraWidgets::on_pushButton_test_dft_clicked() { //Mat image = imread("img/dft.jpg", IMREAD_GRAYSCALE); Mat image = imread("img/imgbuffer-1.png", IMREAD_GRAYSCALE); if (image.empty()) { cout << "Error loading the image" << endl; return ; } Mat padded; int m = getOptimalDFTSize(image.rows); int n = getOptimalDFTSize(image.cols); copyMakeBorder(image, padded, 0, m - image.rows, 0, n - image.cols, BORDER_CONSTANT, Scalar::all(0)); Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) }; Mat complexImg; merge(planes, 2, complexImg); dft(complexImg, complexImg); split(complexImg, planes); magnitude(planes[0], planes[1], planes[0]); Mat magImg = planes[0]; magImg += Scalar::all(1); log(magImg, magImg); magImg = magImg(Rect(0, 0, magImg.cols & -2, magImg.rows & -2)); int cx = magImg.cols / 2; int cy = magImg.rows / 2; Mat q0(magImg, Rect(0, 0, cx, cy)); Mat q1(magImg, Rect(cx, 0, cx, cy)); Mat q2(magImg, Rect(0, cy, cx, cy)); Mat q3(magImg, Rect(cx, cy, cx, cy)); Mat tmp; q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3); q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2); normalize(magImg, magImg, 0, 1, NORM_MINMAX); namedWindow("InputImage", WINDOW_NORMAL); resizeWindow("InputImage", 612, 512); imshow("InputImage", image); namedWindow("Spectrum_Magnitude", WINDOW_NORMAL); resizeWindow("Spectrum_Magnitude", 612, 512); imshow("Spectrum_Magnitude", magImg); // imwrite("img/InputImage.png", image); // imwrite("img/Spectrum_Magnitude.png", magImg); } void mvCameraWidgets::on_pushButton_test_color_clicked() { // 读取3张灰度图像 Mat x_image = imread("img/xx.png", IMREAD_GRAYSCALE); Mat y_image = imread("img/xx.png", IMREAD_GRAYSCALE); Mat z_image = imread("img/xx.png", IMREAD_GRAYSCALE); int b = 0; int g = 0; int r = 0; // 定义绘制磁场箭头的颜色和线宽度 int width = 1; //箭头线宽 // 根据图片尺寸,创建空白图像 Mat magnetic_field_map = Mat::zeros(x_image.rows, x_image.cols, CV_8UC3); // 遍历每个像素点,计算磁场大小和角度,并绘制对应的箭头 for (int i = 0; i < x_image.rows;i+=5) { for (int j = 0; j < x_image.cols;j+=5) { // 获取图像中该位置处的x、y、z方向上的磁场值 float bx = static_cast<float>(x_image.at<uchar>(i,j)); float by = static_cast<float>(y_image.at<uchar>(i,j)); float bz = static_cast<float>(z_image.at<uchar>(i,j)); b = float(bx)/255.0*100.0; g = float(by)/255.0*100.0; r = float(bz)/255.0*100.0; // 计算该点磁场强度的大小 float B = sqrt(bx * bx + by * by + bz * bz); if (B > 0.001f) { // 为了可视化,根据磁场强度调整箭头长度 float scale = min(B / 100.0f, 1.0f); B = B * scale; // 计算该点磁场xy方向的角度 float angle = atan2(by, bx); // 计算该点磁场yz方向的角度 float angle2 = atan2(by, bz); // 画出箭头 Point pt1(j, i); // 起点坐标为(x,y) Point pt2(cvRound(pt1.x + B * cos(angle)*cos(angle2)), cvRound(pt1.y + B * sin(angle)*sin(angle2))); // 根据磁场大小和角度计算终点坐标 Scalar color(b, g, r); // 使用cv::arrowedLine函数绘制箭头 arrowedLine(magnetic_field_map, pt1, pt2, color, width); } } } // 将绘制好的图像保存到文件中 imwrite("img/magnetic_field.png", magnetic_field_map); } void mvCameraWidgets::on_pushButton_test_9_clicked() { string path = "img/dft.jpg"; Mat img = imread(path); Mat img_gray, img_bi; cvtColor(img, img_gray, COLOR_BGR2GRAY); threshold(img_gray, img_bi, 80, 255, THRESH_BINARY_INV); vector<vector<Point> > contours; vector<Vec4i> hierarchy; findContours(img_bi, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); std::cout << contours[0].size() << std::endl; cv::Mat img_draw = cv::Mat(img.rows, img.cols, CV_8UC3, Scalar(0, 0, 255)); drawContours(img_draw, contours, -1, Scalar(255, 255, 255)); int n = 3; cv::Mat A; FitPolynomialCurve(contours[0], n, A); std::vector<cv::Point> points_fitted; for (int x = 0; x < 800; x++) { double y = A.at<double>(0, 0) + A.at<double>(1, 0) * x + A.at<double>(2, 0)*std::pow(x, 2) + A.at<double>(3, 0)*std::pow(x, 3); points_fitted.push_back(cv::Point(x, y)); } cv::polylines(img_draw, points_fitted, false, cv::Scalar(0, 0, 0), 1, 8, 0); imshow("img_src", img); imshow("img_draw", img_draw); imshow("img_bi", img_bi); waitKey(0); } void mvCameraWidgets::on_pushButton_roiSet_clicked() { new_roiAnalyse = new roiAnalyse(); new_roiAnalyse->show(); } void mvCameraWidgets::on_pushButton_save16Mat_clicked() { cv::Mat image; //创建一个空图像image image = imread("img/snapmat1.bmp", IMREAD_UNCHANGED); //读取文件夹中的图像 //mat to char* int nHeight = image.rows; int nWidth = image.cols; int nBytes = nHeight * nWidth;//图像总的字节 unsigned char* readmata = new unsigned char[nBytes]; memcpy(readmata, image.data, nBytes);//转化函数,注意Mat的data成员 QVector <int> v_12int; mymethod::rawChangetoInt(readmata, nWidth / 3 * 2, nHeight, v_12int); for (int i=0;i<v_12int.size();++i) { v_12int[i] *= 16; } std::vector<ushort> vec(v_12int.begin(), v_12int.end()); cv::Mat img_16bit(vec.size(),1, CV_16UC1, &vec[0]); // 构造Mat图片,每个像素占用两个16bit数据 img_16bit=img_16bit.reshape(0, nHeight); cv::imwrite("img/img_16bit.tiff", img_16bit); } void mvCameraWidgets::on_pushButton_read16Mat_clicked() { QVector<int>v_12int; string str = "img/img_16bit.tiff"; mymethod::read16Mat(str, v_12int); return; } void mvCameraWidgets::on_pushButton_readRaw_clicked() { std::string rawpaht = "img/2770.0.RAW"; QVector<int>v_12; mymethod::read16Raw(rawpaht, 2448, 2048, v_12); // 读取raw10图片 std::string strFilename = "img/2770.0.RAW"; int nWidth = 2448; int nHeight = 2048; ushort* pRaw16buf = new ushort[(size_t)nWidth * nHeight]; if (!pRaw16buf) { std::cout << "ERROR: 开辟内存失败!" << std::endl; return; } FILE* pfile = nullptr; errno_t err_code = fopen_s(&pfile, strFilename.c_str(), "rb"); if (!pfile) { std::cout << "ERROR: 打开文件失败!" << std::endl; return; } fread(pRaw16buf, sizeof(pRaw16buf[0]), (size_t)nWidth * nHeight, pfile); fclose(pfile); pfile = nullptr; vector<ushort>tmp_pfile; for (int i=0;i< nWidth * nHeight;++i) { tmp_pfile.push_back(pRaw16buf[i]); } cv::Mat src(nHeight, nWidth, CV_16UC1, pRaw16buf); cv::namedWindow(strFilename, cv::WINDOW_NORMAL); cv::imshow(strFilename, src); cv::waitKey(0); float scale = 255.0 / 65535.0; int method = 1; vector<ushort>tmp_buffer; for (int i = 0; i < nHeight; i++) { ushort *dptr = src.ptr<ushort>(i); for (int j = 0; j < nWidth; j++) { if (method==1) { //5e70 dptr[j] /=16; } if (method==2) { //75e int tmp = dptr[j]/16; int low = tmp >> 4; int high = (tmp & 0x0f) << 8; int m = high + low; dptr[j]= m*scale*16; } if (method==3) { //705e int tmp = dptr[j]; int low = tmp >> 8; int high = (tmp & 0xff) << 8; int m = high + low; dptr[j] = m * scale; } tmp_buffer.push_back(dptr[j]); } } src.convertTo(src, CV_8UC1);//将src改为8位,用来显示 imwrite("16rawimg/(on1)2770.0.bmp", src); } void mvCameraWidgets::on_pushButton_readparams_clicked() { QString runPath = QCoreApplication::applicationDirPath();//获取项目的根路径 QString file_name = QFileDialog::getOpenFileName(this, QStringLiteral("选择文件"), runPath, "Text Files(*.dat)", nullptr, QFileDialog::DontResolveSymlinks); QFile myFile(file_name); //读取文件 if (!myFile.open(QIODevice::ReadOnly)) { qDebug() << myFile.errorString(); } QTextStream textStream(&myFile); textStream.setDevice(&myFile); int count_line = 0; //文件行数 QVector<double> data_params; while (!textStream.atEnd()) { QString str = textStream.readLine(); QString str_first = *str.begin(); if (str_first == "%") { continue; } double str1 = str.split(" ", QString::SkipEmptyParts)[0].toDouble(); double str2 = str.split(" ", QString::SkipEmptyParts)[1].toDouble(); double str3 = str.split(" ", QString::SkipEmptyParts)[2].toDouble(); data_params.push_back(str1); data_params.push_back(str2); data_params.push_back(str3); count_line++; } textStream.seek(0); } void ReadRaw8() { std::string strFilename = "img/2770.0.RAW"; int nWidth = 2448; int nHeight = 2048; uint8_t* pRawbuf = new uint8_t[(size_t)nWidth * nHeight]; if (!pRawbuf) { std::cout << "ERROR: 开辟内存失败!" << std::endl; return; } FILE* pfile = nullptr; errno_t err_code = fopen_s(&pfile, strFilename.c_str(), "rb"); if (!pfile) { std::cout << "ERROR: 打开文件失败!" << std::endl; return; } fread(pRawbuf, 1, ((size_t)nWidth * nHeight), pfile); fclose(pfile); pfile = nullptr; cv::Mat img(nHeight, nWidth, CV_8UC1, pRawbuf); cv::namedWindow(strFilename, cv::WINDOW_NORMAL); cv::imshow(strFilename, img); cv::waitKey(0); cv::Mat rgb; cv::Mat gray; cv::cvtColor(img, rgb, cv::COLOR_BayerRG2RGB); cv::imshow(strFilename, rgb); cv::waitKey(0); cv::cvtColor(rgb, gray, cv::COLOR_RGB2GRAY); cv::imshow(strFilename, gray); cv::waitKey(0); } void ReadRaw10() { // 读取raw10图片 std::string strFilename = "raw10.raw"; int nWidth = 4208; int nHeight = 3120; short* pRaw10buf = new short[(size_t)nWidth * nHeight]; if (!pRaw10buf) { std::cout << "ERROR: 开辟内存失败!" << std::endl; return; } FILE* pfile = nullptr; errno_t err_code = fopen_s(&pfile, strFilename.c_str(), "rb"); if (!pfile) { std::cout << "ERROR: 打开文件失败!" << std::endl; return; } fread(pRaw10buf, sizeof(pRaw10buf[0]), (size_t)nWidth * nHeight, pfile); fclose(pfile); pfile = nullptr; cv::Mat raw10Img(nHeight, nWidth, CV_16SC1, pRaw10buf); cv::namedWindow(strFilename, cv::WINDOW_NORMAL); cv::imshow(strFilename, raw10Img); cv::waitKey(0); // 以下运行会崩溃,因为rgb和gray都是8U类型的数据,而raw10Img是16S,数据溢出,因此需要转换位raw8之后再转成RGB或BGR图像 cv::Mat img_raw8; cv::convertScaleAbs(img_raw8, img_raw8, 0.25); cv::imshow(strFilename, img_raw8); cv::waitKey(0); cv::Mat rgb; cv::Mat gray; cv::cvtColor(img_raw8, rgb, cv::COLOR_BayerRG2RGB); cv::imshow(strFilename, rgb); cv::waitKey(0); cv::cvtColor(rgb, gray, cv::COLOR_RGB2GRAY); cv::imshow(strFilename, gray); cv::waitKey(0); } void read_16raw() { int w = 2448;//原始图像的高 int h = 2048;//原始图像的宽 FILE* fp = NULL; //定义指针s fp = fopen("img/2770.0.RAW", "rb+"); Mat src; src.create(Size(w, h), CV_16UC1); fread(src.data, sizeof(unsigned short), h * w, fp);//将文件读入src imshow("原图", src); // 将2Byte的数据合成为一个byte的数据 Mat origin = src; vector<vector<int>> data; for (int i = 0; i < h; ++i) { vector<int> sub; for (int j = 0; j < w; ++j) { int sum = (int)origin.at<uchar>(i, 2 * j) + (int)origin.at<uchar>(i, 2 * j + 1) * 256; sub.push_back(sum); } data.push_back(sub); } normalize(src, src, 0, 255, NORM_MINMAX);//将src中0~65535缩放到0~255 src.convertTo(src, CV_8UC1);//将src改为8位,用来显示 // 转为彩色图 Mat color; applyColorMap(src, color, cv::COLORMAP_JET); imshow("原图", src); imshow("彩色图", color); waitKey(0); }
#pragma once #include <iostream> #include <vector> #include <QImage> #include <stdlib.h> #include <opencv2/opencv.hpp> #include <string> #include <fstream> using namespace std; using namespace cv; class mymethod { public: //声明静态成员函数 /// \brief 相机数据转换成12bit的int数据 /// \param [in]inputbyte 相机原数据 /// \param [in]img_width 转换后图片的宽 /// \param [in]img_height 转换后图片的高 /// \param [out] outputarray 转换后12bit的int数据 /// \return 成功返回 0 static int rawChangetoInt(unsigned char *inputbyte,int img_width,int img_height,QVector<int> &outputarray); /// \brief 相机数据转换成12bit的int数据 /// \param [in]inputbyte 相机原数据 /// \param [in]img_width 转换后图片的宽 /// \param [in]img_height 转换后图片的高 /// \param [out] img 转换后mat图片 /// \return 成功返回 0 static int rawChangetoMat(unsigned char *inputbyte, int img_width, int img_height, Mat &outputimg); /// \brief 将12bit的int,按照Roi区域划分 /// \param [in]img_width 当前图片的宽 /// \param [in]img_height 当前图片的高 /// \param [in]v_12int 当前int数据 /// \param [in] roi 需要扣数据的roi区域 /// \param [out] v_12int_roi 对应roi区域的int数据 /// \return 成功返回0 static int intChangetoRoiInt(int img_width, int img_height, QVector<int>&v_12int, QRect roi, QVector<int>&v_12int_roi); /// \brief 相除累加算法 /// \param [in] v_molecule 分子数组 /// \param [in] v_denominator 分母数组 /// \param [out] v_add 累加数组 /// \return 成功返回0 static int mydivisionadd(QVector<int>&v_molecule, QVector<int>&v_denominator, QVector<int>&v_add); /// \brief 求一个vector的均值 /// \param [in] v_tmp 待求均值的vector /// \return 成功返回double static double myaverage(QVector<int> &v_tmp); /// \brief 12bit的int数据经过压缩到0-255转换成Qiamge /// \param [in]img_width 图片的宽 /// \param [in]img_height 图片的高 /// \param [in]inputarray 12bit的int数据 /// \return 成功返回QImage static QImage intChangetoQimg(int img_width, int img_height, QVector<int> &inputarray); /// \brief 将double数据,根据比色卡上下限转换到0-255,再转换到伪彩图 /// \param [in]img_width 图片的宽 /// \param [in]img_height 图片的高 /// \param [in] magnetic_strength 需要转换的磁场强度数组 /// \param [in] down 比色卡下限 /// \param [in] up 比色卡上限 /// \param [in] image0 渐变图的图片,需要在界面上设置grab函数抓取 /// \return 成功返回QImage static QImage intChangetoQcolorimg(int img_width, int img_height, QVector<double> &magnetic_strength, double down, double up, QImage &image0); /// \brief 将相机原数据,保存为Mat图片 /// \param [in]img_width 图片的宽 /// \param [in]img_height 图片的高 /// \param [in] Rawbuffer 需要保存的相机原数据 /// \param [in] imgpath 保存图片的路径 比如:img/snapmat.png /// \return 成功返回0 static int saveRawMat(int img_width, int img_height, unsigned char * Rawbuffer,string savepath); /// \brief 读取路径下的Mat图片,转换成相机原数据 /// \param [in]imgpath 需要读取图片的路径 比如:img/snapmat.png /// \param [out]Rawbuff 得到的相机原数据 /// \return 成功返回0 static int readRawMat (string imgpath,unsigned char* Rawbuff); /// \brief 读取路径下的Mat图片,转换成相机原数据 /// \param [in]imgpath 需要读取图片的路径 比如:img/snapmat.png /// \param [in]value_x 查询点的x坐标(图片坐标系) /// \param [in]value_y 查询点的y坐标(图片坐标系) /// \param [out]output 输出结果(0-4096) /// \return 成功返回0 static int readSingleValueFromRaw(string imgpath,int value_x,int value_y,int& output); /// \brief 将相机原数据,保存为16bitMat图片 /// \param [in]img_width 图片的宽 /// \param [in]img_height 图片的高 /// \param [in] Rawbuffer 需要保存的相机原数据 /// \param [in] savepath 保存图片的路径 比如:img/snapmat.png /// \return 成功返回0 static int save16Mat(int img_width, int img_height, unsigned char * Rawbuffer, string savepath); /// \brief 读取路径下的Mat图片,转换QVector<int>(0-4096) /// \param [in]imgpath 需要读取图片的路径 比如:img/snapmat.png /// \param [out]v_12int 得到的12bit数据 /// \return 成功返回0 static int read16Mat(string imgpath, QVector<int>&v_12int); /// \brief 将相机原数据,保存为RAW数据 /// \param [in]img_width 图片的宽 /// \param [in]img_height 图片的高 /// \param [in] Rawbuffer 需要保存的相机原数据 /// \param [in] savepath 保存RAW的路径 比如:img/snapmat.RAW /// \return 成功返回0 static int save16Raw(int img_width, int img_height, unsigned char * Rawbuffer, string savepath); /// \brief 读取路径下的16RAW数据,转换QVector<int>(0-4096) /// \param [in]rawpath 需要读取RAW的路径 比如:img/snapmat.png /// \param [in]imgWidth 图片宽 /// \param [in]rawpath 图片高 /// \param [out]v_12int 得到的12bit数据 /// \return 成功返回0 static int read16Raw(string rawpath, int imgWidth, int imgHeight, QVector<int>& v_12int); /// \brief Mat转到QVector /// \param [in]inputarray /// \param [out]v_double /// \return 成功返回0 static int mymethod::MattoQVector(Mat inputarray, QVector<double>& v_double); };
#include "mymethod.h" int mymethod::rawChangetoInt(unsigned char *inputbyte, int img_width, int img_height, QVector<int> &outputarray) { /* a0 a1 a2 10100101 0000 1111 0101 1010 b1=(a0 << 4) | (a1 & 0xf); b2=(a2 << 4) | ((a1 & 0xf0) >> 4); 1010 0101 1111 0101 1010 0000 //将500万图像数据,进行拆分重组为12bit数据; //应该获取500万的1.5倍数据,拆分后得到500万数据 */ // WORD* pNewFrameBuffer = (WORD*)CameraAlignMalloc(g_W_H_INFO.sensor_height*g_W_H_INFO.sensor_width * 2, 16); // BYTE BYTE_1, BYTE_2, BYTE_3; // int inddd = 0; // // for (int i = 0; i < g_tFrameHead.uBytes / 3 - 1; i++) // { // BYTE_1 = *m_RawBuffer++; // BYTE_2 = *m_RawBuffer++; // BYTE_3 = *m_RawBuffer++; // WORD Y0 = (BYTE_1 << 4) | ((BYTE_2 & 0xF0)>>4); // WORD Y1 = (BYTE_3 << 4) | (BYTE_2 & 0x0F); // // pNewFrameBuffer[inddd] = Y0; // inddd++; // pNewFrameBuffer[inddd] = Y1; // inddd++; // } // g_tFrameHead.uBytes = g_W_H_INFO.sensor_height*g_W_H_INFO.sensor_width * 2; // CameraSaveImage(g_hCamera, (char*)"./raw16rgb.raw", (BYTE*)pNewFrameBuffer, &g_tFrameHead, FILE_RAW_16BIT, 100); // CameraAlignFree((BYTE*)pNewFrameBuffer); outputarray.clear(); int Size_byte= img_width * img_height; for (int i=0;i< Size_byte/2;++i) { int a0 = inputbyte[i * 3]; int a1 = inputbyte[i * 3 + 1]; int a2 = inputbyte[i * 3 + 2]; int raw1 = (a0 << 4) | (a1 & 0xf); int raw2 = (a2 << 4) | ((a1 & 0xf0) >> 4); outputarray.push_back(raw1); outputarray.push_back(raw2); } return 0; } int mymethod::rawChangetoMat(unsigned char * inputbyte, int img_width, int img_height, Mat &outputimg) { vector<int>outputarray; int Size_byte = img_width * img_height; for (int i = 0; i < Size_byte / 2; ++i) { int a0 = inputbyte[i * 3]; int a1 = inputbyte[i * 3 + 1]; int a2 = inputbyte[i * 3 + 2]; int raw1 = (a0 << 4) | (a1 & 0xf); int raw2 = (a2 << 4) | ((a1 & 0xf0) >> 4); outputarray.push_back(raw1); outputarray.push_back(raw2); } // 更改矩阵大小为n行 Mat tmp = Mat(outputarray); tmp = tmp.reshape(0, img_height); outputimg = tmp.clone(); return 0; } int mymethod::intChangetoRoiInt(int img_width, int img_height, QVector<int>& v_12int, QRect roi, QVector<int>& v_12int_roi) { //每次进入函数先清空,防止多次调用导致数据错误 v_12int_roi.clear(); int x = roi.x(); int y = roi.y(); int w = roi.width(); int h = roi.height(); //防止越界处理 if ((x < 0) || (y < 0) || (w < 0) || (h < 0)) { return -1; } if ((w > img_width) || (h > img_height)) { return -1; } //(x,y)--(x+w,y) int j_start = x + y * img_width; int j_end = x + w + y * img_width; for (int i = y; i < y + h; ++i) { for (int j = x + i * img_width; j < x + w + i * img_width; ++j) { int tmp = v_12int[j]; v_12int_roi.push_back(tmp); } } return 0; } int mymethod::mydivisionadd(QVector<int>& v_molecule, QVector<int>& v_denominator, QVector<int>& v_add) { //将两个vector相除累加 if (v_molecule.size() != v_denominator.size()) { return -1; } if (v_molecule.size() != v_add.size()) { return -1; } else { for (int i = 0; i < v_molecule.size(); ++i) { double i_tmp = 0; double i_openwave = (double)v_molecule[i]; double i_closewave = (double)v_denominator[i]; //分母为0 if (i_closewave == 0) { i_tmp = 0; } else { //i_tmp = (i_openwave / i_closewave) * 4096.0; i_tmp = (i_closewave - i_openwave); } v_add[i] += (int)i_tmp; } // int max_val = 0; // int min_val = 4096; // for (int i = 0; i < v_add.size(); i++) { // // // max_val = std::max(max_val, v_add[i]); // min_val = std::min(min_val, v_add[i]); // // } }//相除累加结束 return 0; } double mymethod::myaverage(QVector<int>& v_tmp) { double average = 0.0; double sum = 0; for (int i = 0; i < v_tmp.size(); ++i) { sum += v_tmp[i]; } average = sum / v_tmp.size(); return average; } QImage mymethod::intChangetoQimg(int img_width, int img_height, QVector<int> &inputarray) { unsigned char *c_uchar ; c_uchar = (unsigned char*)malloc(img_width*img_height); //预先申请动态空间 for (int i = 0; i < inputarray.size(); i++) { int tmp = (int)((double)inputarray[i] / 4096.0*255.0); if (tmp > 255) { tmp = 255; } if (tmp < 0) { tmp = 0; } uchar utmp = (uchar)tmp; c_uchar[i] = utmp; } QImage img; img = QImage(c_uchar, img_width, img_height, QImage::Format_Indexed8); QImage copyImage = img.copy(); // 复制整个图像 //灰度图颜色表 QVector<QRgb> ColourTable; for (int i = 0; i < 256; i++) { ColourTable.append(qRgb(i, i, i)); } copyImage.setColorTable(ColourTable); if (c_uchar!=NULL) { free(c_uchar); c_uchar = NULL; } return copyImage; } QImage mymethod::intChangetoQcolorimg(int img_width, int img_height, QVector<double>& magnetic_strength, double down, double up, QImage & image0) { int w_pic = img_width; int h_pic = img_height; QVector<QRgb> rgbColourTable; unsigned char *Buffer; //磁场强度信息值,根据在上下限up,down中比例转换到0-255 Buffer = (unsigned char *)malloc(w_pic*h_pic); QImage img = QImage(Buffer, w_pic, h_pic, QImage::Format_Indexed8); if (w_pic*h_pic!=magnetic_strength.size()) { return img; } if (down >= up) { return img; } for (int i = 0; i < w_pic*h_pic; i++) { if (magnetic_strength[i] <= down) { Buffer[i] = (uchar)0; } if (magnetic_strength[i] >= up) { Buffer[i] = (uchar)255; } if ((magnetic_strength[i] < up) && (magnetic_strength[i] > down)) { int tmp = (magnetic_strength[i] - down) / (up - down) * 255; uchar utmp = (uchar)tmp; Buffer[i] = utmp; } } QImage copyImage = img.copy(); // 复制整个图像 for (int y = 0; y < 256; y++) { QColor color; int index = (int)((float)(y) / (float)(255) * (float)(image0.height() - 2)); if (index == 0) { color = image0.pixelColor(QPoint(1, image0.height() - 2)); } else if (index == image0.height() - 2) { color = image0.pixelColor(QPoint(1, 1)); } else { color = image0.pixelColor(QPoint(1, image0.height() - 2 - index)); } QRgb rgb = color.rgb(); rgbColourTable.push_back(rgb); } copyImage.setColorTable(rgbColourTable); if (Buffer != NULL) { free(Buffer); Buffer = NULL; } return copyImage; } int mymethod::saveRawMat(int img_width, int img_height, unsigned char * Rawbuffer, string savepath) { cv::Mat img; img = Mat(img_height, img_width / 2 * 3, CV_8UC1, Rawbuffer); cv::imwrite(savepath, img); return 0; } int mymethod::readRawMat(string imgpath, unsigned char * Rawbuff) { cv::Mat image; //创建一个空图像image image = cv::imread(imgpath, cv::IMREAD_UNCHANGED); //读取文件夹中的图像 if (image.empty()) { return -1; } // QVector<unsigned char> raw_mat; // for (int i = 0; i < image.rows; i++) // { // uchar *ptr = image.ptr<uchar>(i); // for (int j = 0; j < image.cols; j++) // { // raw_mat.push_back(ptr[j]); // // } // } //mat to char* int nHeight = image.rows; int nWidth = image.cols; int nBytes = nHeight * nWidth;//图像总的字节 memcpy(Rawbuff, image.data, nBytes);//转化函数,注意Mat的data成员 return 0; } int mymethod::readSingleValueFromRaw(string imgpath, int value_x, int value_y, int & output) { cv::Mat image; //创建一个空图像image image = cv::imread(imgpath, cv::IMREAD_UNCHANGED); //读取文件夹中的图像 if (image.empty()) { return -1; } uchar *ptr = image.ptr<uchar>(value_y); int raw_x = value_x * 3 / 2; if (raw_x %3 == 0) { int a0 = ptr[raw_x]; int a1 = ptr[raw_x + 1]; int a2 = ptr[raw_x + 2]; int raw1 = (a0 << 4) | (a1 & 0xf); int raw2 = (a2 << 4) | ((a1 & 0xf0) >> 4); output = raw1; } if (raw_x % 3 == 1) { int a0 = ptr[raw_x-1]; int a1 = ptr[raw_x]; int a2 = ptr[raw_x+1]; int raw1 = (a0 << 4) | (a1 & 0xf); int raw2 = (a2 << 4) | ((a1 & 0xf0) >> 4); output = raw2; } return 0; } int mymethod::save16Mat(int img_width, int img_height, unsigned char * Rawbuffer, string savepath) { QVector <int> v_12int;//原相机数据转到0-4096的int mymethod::rawChangetoInt(Rawbuffer, img_width, img_height, v_12int); for (int i = 0; i < v_12int.size(); ++i) { v_12int[i] *= 16;//4096转到65535范围 } std::vector<ushort> us_vec(v_12int.begin(), v_12int.end()); cv::Mat img_16bit(us_vec.size(), 1, CV_16UC1, &us_vec[0]); // 构造Mat图片,每个像素占用一个16bit数据 img_16bit = img_16bit.reshape(0, img_height); cv::imwrite(savepath, img_16bit); return 0; } int mymethod::read16Mat(string imgpath, QVector<int>&v_12int) { // 读取16位Mat cv::Mat mat16 = cv::imread(imgpath, cv::IMREAD_ANYDEPTH); // 将16位Mat数据放入vector中 std::vector<ushort> us_data; if (mat16.type() == CV_16U) { const ushort* p = mat16.ptr<ushort>(); for (int i = 0; i < mat16.total(); i++) { us_data.push_back(*p++ / 16);//65535转到4096范围 } } //ushort转到int std::vector<int>i_data(us_data.size()); std::transform(us_data.begin(), us_data.end(), i_data.begin(), [](ushort us) { return static_cast<int>(us); }); v_12int=QVector<int>::fromStdVector(i_data); return 0; } int mymethod::save16Raw(int img_width, int img_height, unsigned char * Rawbuffer, string savepath) { return 0; } int mymethod::read16Raw(string rawpath,int imgWidth,int imgHeight, QVector<int>& v_12int) { // 读取raw10图片 std::string strFilename = rawpath; int nWidth = imgWidth; int nHeight = imgHeight; ushort* pRaw16buf = new ushort[(size_t)nWidth * nHeight]; if (!pRaw16buf) { //std::cout << "ERROR: 开辟内存失败!" << std::endl; return -1; } FILE* pfile = nullptr; errno_t err_code = fopen_s(&pfile, strFilename.c_str(), "rb"); if (!pfile) { //std::cout << "ERROR: 打开文件失败!" << std::endl; return -1; } fread(pRaw16buf, sizeof(pRaw16buf[0]), (size_t)nWidth * nHeight, pfile); fclose(pfile); pfile = nullptr; for (int i = 0; i < nWidth * nHeight; ++i) { v_12int.push_back(pRaw16buf[i]/16); } if (pRaw16buf != NULL) { delete pRaw16buf; pRaw16buf = NULL; } return 0; } int mymethod::MattoQVector(Mat inputarray, QVector<double>& v_double) { v_double.clear(); for (int i = 0; i < inputarray.rows; i++) { double* ptr = inputarray.ptr<double>(i); // 获取第i行数据的指针 for (int j = 0; j < inputarray.cols; j++) { double value = ptr[j]; // 获取第i行j列像素点的值 v_double.push_back(value); } } return 0; }
基本满足MindVision测试需要,有些格式转换的坑。这里使用的相机为12bit相机,可根据你们的相机深度自己设置输出深度。
如有问题欢迎交流。