(VS2013+Opencv3.0)
本篇结合自己的研究项目,仅对算术平均最小值法、兰氏距离法(系数 c=0.1 时)、绝对值倒数法(系数 M=0.1 时和最大值_最小值法共4中相似矩阵的构造进行算法实现:
- h文件:
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
class FSMatrix
{
public:
cv::Mat Avg(cv::Mat Fuzzy);//均值
cv::Mat sqrtD(cv::Mat sqrtd);//开根号
cv::Mat StandardDeviation(cv::Mat Standard);//标准差
cv::Mat Max_Min(cv::Mat Maxmin);//最大值_最小值法
cv::Mat Translation_standarddviation(cv::Mat Translation);//平移_标准差变换
cv::Mat Translation_range(cv::Mat Translation);//平移_极差变换
cv::Mat ZeroElementAdjustment(cv::Mat Adjustment);//矩阵内元素为0时,调整
cv::Mat ArithmeticAverage_Min(cv::Mat AverageMin);//算术平均最小值法
cv::Mat Lance_distance(cv::Mat Lancedistance, double Lance_c);//兰氏距离法
cv::Mat AbsoluteValue_Reciprocal(cv::Mat AbsoluteReciprocal, double Reciprocal_c);//绝对值倒数法
cv::Mat FuzzySimilarMatrix(cv::Mat HSV, int i, double H, double S, double V);//模糊相似矩阵实现
};
- cpp文件:
#include "FuzzySimilarMatrix.h"
#include<fstream>
/**********均值************/
cv::Mat FSMatrix::Avg(cv::Mat Fuzzy)
{
cv::Mat A = Fuzzy;
double sum = 0;
cv::Mat Avg(1, A.cols, CV_64FC1);
cv::Mat s(1, A.cols, CV_64FC1);
for (int j = 0; j < A.cols; j++) //列
{
sum = A.at<double>(0, j);
for (int i = 1; i < A.rows; i++) //行
{
sum += A.at<double>(i, j);
}
Avg.at<double>(0, j) = sum / A.rows;
}
//cout << "Avg =" << Avg << endl;
return Avg;
}
/**********开根号************/
cv::Mat FSMatrix::sqrtD(cv::Mat sqrtd)
{
cv::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);
}
}
//cout << "sq =" << sq << endl;
return sq;
}
/**********标准差************/
cv::Mat FSMatrix::StandardDeviation(cv::Mat Standard)
{
cv::Mat s(Standard.rows, Standard.cols, CV_64FC1);
cv::Mat C(1, Standard.cols, CV_64FC1);
C = Avg(Standard);
double sum = 0;
if (s.cols)
{
for (int j = 0; j<Standard.cols; j++) //列
{
for (int i = 0; i<Standard.rows; i++)
{
s.at<double>(i, j) = Standard.at<double>(i, j) - C.at<double>(0, j);
//s.at<double>(i, j) = (s.at<double>(i, j) * s.at<double>(i, j));
s.at<double>(i, j) = (s.at<double>(i, j) * s.at<double>(i, j));
// cout << "S =" << s.at<double>(i, j) << endl;
}
}
C = Avg(s);
// cout << "C_Avg =" << C << endl;
C = sqrtD(C);
}
// cout << "C =" << C << endl;
return C;
}
/*********平移_标准差变换**********/
cv::Mat FSMatrix::Translation_standarddviation(cv::Mat Translation)
{
cv::Mat S(1, Translation.cols, CV_64FC1);
cv::Mat Av(1, Translation.cols, CV_64FC1);
cv::Mat T(Translation.rows, Translation.cols, CV_64FC1);
S = StandardDeviation(Translation);
Av = Avg(Translation);
for (int j = 0; j<Translation.cols; j++) //列
{
for (int i = 0; i<Translation.rows; i++)
{
T.at<double>(i, j) = (Translation.at<double>(i, j) - Av.at<double>(0, j)) / S.at<double>(0, j);
}
}
cout << "T =" << T << endl;
return T;
}
/*********平移_极差变换********/
cv::Mat FSMatrix::Translation_range(cv::Mat Translation)
{
cv::Mat Range = Translation_standarddviation(Translation);
cv::Mat Range_max = cv::Mat::zeros(cv::Size(Range.cols, 1), CV_64FC1);
cv::Mat Range_min = cv::Mat::zeros(cv::Size(Range.cols, 1), CV_64FC1);
for (int j = 0; j<Range.cols; j++) //列
{
Range_max.at<double>(0, j) = Range.at<double>(0, j);
Range_min.at<double>(0, j) = Range.at<double>(0, j);
for (int i = 1; i< Range.rows; i++)
{
if (Range_max.at<double>(0, j) < Range.at<double>(i, j))
{
Range_max.at<double>(0, j) = Range.at<double>(i, j);
//cout << "Range_max =" << Range_max << endl;
}
if (Range_min.at<double>(0, j) > Range.at<double>(i, j))
{
Range_min.at<double>(0, j) = Range.at<double>(i, j);
//cout << "Range_min =" << Range_min << endl;
}
}
}
cout << "Range_max =" << Range_max << endl;
cout << "Range_min =" << Range_min << endl;
for (int j = 0; j<Range.cols; j++) //列
{
for (int i = 0; i< Range.rows; i++)
{
Range.at<double>(i, j) = (Range.at<double>(i, j) - Range_min.at<double>(0, j)) / (Range_max.at<double>(0, j) - Range_min.at<double>(0, j));
}
}
cout << "Range =" << Range << endl;
return Range;
}
/*********矩阵内元素为0时,调整********/
cv::Mat FSMatrix::ZeroElementAdjustment(cv::Mat Adjustment)
{
//cout << "Adjustment =" << Adjustment << endl;
for (int i = 1; i < Adjustment.rows; i++) //行
{
for (int j = 0; j < Adjustment.cols; j++)
{
if (Adjustment.at<double>(i, j) == 0)
{
Adjustment.at<double>(i, j) = Adjustment.at<double>(0, j) / 2;
}
}
}
return Adjustment;
}
/*********最大值_最小值法********/
cv::Mat FSMatrix::Max_Min(cv::Mat Maxmin)
{
cv::Mat R(Maxmin.rows, 1, CV_64FC1);
//cout << "Maxmin =" << Maxmin << endl;
for (int i = 0; i<Maxmin.rows; i++) //行
{
double SumMax = 0;
double SumMin = 0;
double SumMaxMin = 0;
for (int j = 0; j < Maxmin.cols; j++)
{
double Max = Maxmin.at<double>(0, j);
double Min = Maxmin.at<double>(0, j);
if (Max <= Maxmin.at<double>(i, j))
{
Max = Maxmin.at<double>(i, j);
}
SumMax += Max;
if (Min >= Maxmin.at<double>(i, j))
{
Min = Maxmin.at<double>(i, j);
}
SumMin += Min;
}
SumMaxMin = SumMin / SumMax;
R.at<double>(i, 0) = SumMin / SumMax;
ofstream oFile;
oFile.open("Max_Min.csv", ios::out | ios::trunc);
oFile << R << endl;
oFile.close();
}
return R;
}
/*********算术平均最小值法********/
cv::Mat FSMatrix::ArithmeticAverage_Min(cv::Mat AverageMin)
{
cv::Mat A(AverageMin.rows, 1, CV_64FC1);
//cout << "AverageMin =" << AverageMin << endl;
for (int i = 0; i<AverageMin.rows; i++) //行
{
double SumMin = 0;
double ArithmeticAverageMin = 0;
double S = 0;
for (int j = 0; j < AverageMin.cols; j++)
{
S += AverageMin.at<double>(0, j);
double Min = AverageMin.at<double>(0, j);
if (Min >= AverageMin.at<double>(i, j))
{
Min = AverageMin.at<double>(i, j);
}
SumMin += Min;
S += AverageMin.at<double>(i, j);
}
ArithmeticAverageMin = (2*SumMin) / S;
//cout << "ArithmeticAverageMin =" << ArithmeticAverageMin << endl;
A.at<double>(i, 0) = (2 * SumMin) / S;
ofstream oFile;
oFile.open("ArithmeticAverage_Min.csv", ios::out | ios::trunc);
oFile << A << endl;
oFile.close();
}
return A;
}
/*********兰氏距离法********/
cv::Mat FSMatrix::Lance_distance(cv::Mat Lancedistance, double Lance_c)
{
cv::Mat L(Lancedistance.rows, 1, CV_64FC1);
//cout << "Lancedistance =" << Lancedistance << endl;
for (int i = 0; i<Lancedistance.rows; i++) //行
{
double S1 = 0;
double S2 = 0;
double S = 0;
for (int j = 0; j < Lancedistance.cols; j++)
{
S1 = abs(Lancedistance.at<double>(0, j) - Lancedistance.at<double>(i, j));
S2 = abs(Lancedistance.at<double>(0, j) + Lancedistance.at<double>(i, j));
S += S1 / S2;
}
L.at<double>(i, 0) = 1 - (Lance_c * S) ;
ofstream oFile;
oFile.open("Lancedistance.csv", ios::out | ios::trunc);
oFile << L << endl;
oFile.close();
}
return L;
}
/*********绝对值倒数法********/
cv::Mat FSMatrix::AbsoluteValue_Reciprocal(cv::Mat AbsoluteReciprocal, double Reciprocal_c)
{
cv::Mat Ab(AbsoluteReciprocal.rows, 1, CV_64FC1);
//cout << "AbsoluteReciprocal =" << AbsoluteReciprocal << endl;
for (int i = 0; i<AbsoluteReciprocal.rows; i++) //行
{
double S1 = 0;
for (int j = 0; j < AbsoluteReciprocal.cols; j++)
{
S1+= abs(AbsoluteReciprocal.at<double>(0, j) - AbsoluteReciprocal.at<double>(i, j));
}
Ab.at<double>(i, 0) = (Reciprocal_c / S1);
Ab.at<double>(0, 0) = 1;
ofstream oFile;
oFile.open("AbsoluteReciprocal.csv", ios::out | ios::trunc);
oFile << Ab << endl;
oFile.close();
}
return Ab;
}
/*********模糊相似矩阵实现********/
cv::Mat FSMatrix::FuzzySimilarMatrix(cv::Mat HSV, int i, double H, double S, double V)
{
int row = 0;//有几行,即几个参数
for (int j = 0; j<HSV.rows; j++)
{
if (HSV.at<double>(j, 0) == i)
{
row++;//有几行,即几个参数
cout << "HSV.at<double>(j, 0) =" << HSV.at<double>(j, 0) << endl; //调用文档(HSV.txt)的几行,即HSV矩阵的几行
}
}
cv::Mat HSVR = cv::Mat::zeros(cv::Size(3, row+1), CV_64FC1);
if (row)
{
int j0 = 1;
HSVR.at<double>(0, 0) = H;
HSVR.at<double>(0, 1) = S;
HSVR.at<double>(0, 2) = V;
for (int j = 0; j < HSV.rows; j++)
{
if (HSV.at<double>(j, 0) == i)
{
HSVR.at<double>(j0, 0) = HSV.at<double>(j, 1);
HSVR.at<double>(j0, 1) = HSV.at<double>(j, 2);
HSVR.at<double>(j0, 2) = HSV.at<double>(j, 3);
j0++;
}
}
cout << "HSVR =" << HSVR << endl; //HSVR为原始数据矩阵,第一行为H、S、V值
}
cv::Mat Mm;
cv::Mat Ad;
cv::Mat Tr;
cv::Mat AverageMin;
Tr = Translation_range(HSVR);
Ad = ZeroElementAdjustment(Tr);
cout << "ZeroElementAdjustment =" << Ad << endl;
Mm = Max_Min(Ad);
cout << "Max_Min =" << Mm << endl;
AverageMin = ArithmeticAverage_Min(Ad);
cout << "AverageMin =" << AverageMin << endl;
cv::Mat Lance;
Lance = Lance_distance(Tr, 0.1);
cout << "Lance =" << Lance << endl;
cv::Mat Rec;
Rec = AbsoluteValue_Reciprocal(Tr, 0.1);
cout << "Rec =" << Rec << endl;
ofstream oFilese2("Max_MinCSV.csv", ios::app);
oFilese2 << Mm << endl;
oFilese2.close();
return Mm;
}
- main主函数调用:
#include<fstream>
#include "FuzzySimilarMatrix.h"
using namespace std;
using namespace cv;
void main()
{
ifstream file;//创建文件流对象
file.open("HSV.txt");
cv::Mat Hhsv = cv::Mat::zeros(64, 4, CV_64FC1);//创建Mat类矩阵,定义初始化值全部是0,矩阵大小和txt一致
//将txt文件数据写入到Hhsv矩阵中
for (int ii = 0; ii < 64; ii++)
{
for (int j = 0; j < 4; j++)
{
file >> Hhsv.at<double>(ii, j);
}
}
FSMatrix FSm;
FSm.FuzzySimilarMatrix(Hhsv, 10, 166, 67, 162);
}
- 运行结果展示:
注意:HSV.txt文档部分数据:(64行4列)