(VS2013+Opencv3.0)
结合前一篇颜色判别之RES判别法理论的编码实现:
- h文件
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
class Res
{
public:
double Res::readregx();
double Res::readthd();
double detect(cv::Mat, int i, double r, double g, double b);
Mat sum(Mat summat);
Mat sqrtD(Mat sqrtd);
Mat ptMulti(Mat X1, Mat X2);
};
- cpp文件:
#include “Res.h”
double Res::detect(cv::Mat reg, int i, double r, double g, double b)
{
int row = 0;//有几行,即几个参数
for (int j = 0; j<reg.rows; j++)
{
if (reg.at<double>(j, 0) == i)
{
row++;//有几行,即几个参数
}
}
if (row)
{
//regr是reg的偏差计算值dx,regn是标准值sd
Mat regr = Mat::zeros(cv::Size(row, 3), CV_64FC1);
Mat regn = Mat::zeros(cv::Size(row, 1), CV_64FC1);
Mat Z = Mat::zeros(cv::Size(1, 1), CV_64FC1);
int j0 = 0;
for (int j = 0; j<reg.rows; j++)
{
if (reg.at<double>(j, 0) == i)
{
regr.at<double>(0, j0) = reg.at<double>(j, 1);
regr.at<double>(1, j0) = reg.at<double>(j, 2);
regr.at<double>(2, j0) = reg.at<double>(j, 3);
regn.at<double>(0, j0) = reg.at<double>(j, 4);
j0++;
}
}
Mat Y = (Mat_<double>(1, 3) << r, g, b);
Z = ptMulti(Y, Y);//平方
Z = sqrtD(Z);//求平方根
double rr = (r / (norm(Z))) * 255;
double gg = (g / (norm(Z))) * 255;
double bb = (b / (norm(Z))) * 255;
cout << "rr= " << rr << endl;
cout << "gg= " << gg << endl;
cout << "bb= " << bb << endl;
Mat X(3, row, CV_64FC1);
for (int j = 0; j < row; j++)
{
X.at<double>(0, j) = rr;
X.at<double>(1, j) = gg;
X.at<double>(2, j) = bb;
}
Mat D(3, row, CV_64FC1);
//开始计算
D = regr - X;//rgb-reg值
D = ptMulti(D, D);//平方
D = sum(D);//求平方和,将3,k的矩阵转化为1,k矩阵
D = sqrtD(D);//求平方根
cout << "sqrtD = " << endl << D << endl;
cout << "---------------------------------------------------------------" << endl;
double minVal = 0, maxVal = 0;
cv::Point minPt, maxPt;
minMaxLoc(D, &minVal, &maxVal, &minPt, &maxPt);
int m = 0, k = 0;//偏差值中的m与k
//测试用取得的最小值为Minval_,编号为m
double dxm, dxk, sdm, sdk;
dxm = minVal;
m = minPt.x;
if (row > 1)
{
if (m < row - 1)
{
if (m)
{
if (D.at<double>(0, m + 1) < D.at<double>(0, m - 1))
{
k = m + 1;
}
else
{
k = m - 1;
}
}
else
{
k = 1;
}
}
else
{
k = row - 2;
}
double res = (regn.at<double>(0, m)*D.at<double>(0, k) + regn.at<double>(0, k)*D.at<double>(0, m)) / (D.at<double>(0, m) + D.at<double>(0, k));
return res;
}
else
{
double reserr = regn.at<double>(0, m);
return reserr;
}
}
return 0;
}
Mat Res::sum(Mat summat)
{
Mat s(1, summat.cols, CV_64FC1);
if (s.cols)
{
for (int i = 0; i<summat.cols; i++)
{
s.at<double>(0, i) = 0;
for (int j = 0; j<summat.rows; j++)
{
s.at<double>(0, i) += summat.at<double>(j, i);
}
}
return s;
}
return summat;
}
Mat Res::sqrtD(Mat sqrtd)
{
Mat sq(sqrtd.rows, sqrtd.cols, CV_64FC1);
for (int i = 0; i<sqrtd.rows; i++)
{
for (int j = 0; j<sqrtd.cols; j++)
{
sq.at<double>(i, j) = sqrt(sqrtd.at<double>(i, j));
double xxx = sq.at<double>(i, j);
}
}
return sq;
}
Mat Res::ptMulti(Mat X1, Mat X2)
{
if (X1.rows == X2.rows &&X1.rows == X2.rows)
{
Mat Y(X1.rows, X1.cols, CV_64FC1);
if (Y.cols)
{
for (int i = 0; i < X1.rows; i++)
{
for (int j = 0; j < X1.cols; j++)
{
Y.at<double>(i, j) = X1.at<double>(i, j)*X2.at<double>(i, j);
}
}
return Y;
}
return X1;
}
}
- main主函数调用:
#include
//#include “FuzzySimilarMatrix.h”
#include “Res.h”
using namespace std;
using namespace cv;
void main()
{
ifstream file_RES;//创建文件流对象
file_RES.open(“RES.txt”);
cv::Mat RES = cv::Mat::zeros(40, 5, CV_64FC1);//创建Mat类矩阵,定义初始化值全部是0,矩阵大小和txt一致
//将txt文件数据写入到RES矩阵中
for (int ii = 0; ii < 40; ii++)
{
for (int j = 0; j < 5; j++)
{
file_RES >> RES.at<double>(ii, j);
}
}
Res Rrgb;
double ResResult = 0;
ResResult=Rrgb.detect(RES, 2, 20, 45.7, 111.3);
cout << "ResResult: " << ResResult <<endl;
}
- 运行结果展示:
注意:RES.txt文档部分数据:(40行5列)