颜色判别之RES判别法_算法

(VS2013+Opencv3.0)
结合前一篇颜色判别之RES判别法理论的编码实现:

  1. 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);
};
  1. 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;
	}
}
  1. 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;

}

  1. 运行结果展示:
    在这里插入图片描述

注意:RES.txt文档部分数据:(40行5列)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值