RGB空间色彩溢出修正-保留hue值不变(附:cpp类的代码)

基本原理:连接RGB中心点与溢出像素点,与RGB空间的交点即为对溢出像素修正的颜色值。

上图立方体为RGB颜色空间,B为色彩溢出点所在位置,C为修正后的颜色值。

#ifndef _CV2GAMUT_H_ 
#define _CV2GAMUT_H_ 
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc.hpp>
using namespace cv;
using namespace std;


class Cv2Gamut{



private:
	Vec3f OF_RGB;
	Vec3f iDot;//线面交点
	Vec3f oDot = Vec3f(0.5, 0.5, 0.5);//RGB 立方体中心
	Vec3f pDot;//平面经过的一点坐标

	Vec3f PnorVec;//平面法向量
	Vec3f LnorVec;//直线方向向量
	float vpt;//直线向量与法向量的乘积
	float t;



public:
	Cv2Gamut(const Vec3f &OF_RGB){
		this->OF_RGB = OF_RGB;

	}
	Cv2Gamut(){
	}
	void setRGB(const Vec3f &OF_RGB){
		this->OF_RGB = OF_RGB;
	}

	void lineXplane(){
		LnorVec = OF_RGB - oDot;
		vpt = LnorVec.val[0] * PnorVec.val[0] + LnorVec.val[1] * PnorVec.val[1] + LnorVec.val[2] * PnorVec.val[2];
		if (vpt == 0){
			iDot = Vec3f(-0.5, -0.5, -0.5);
		}
		else{
			t = ((pDot.val[0] - 0.5)*PnorVec.val[0] + (pDot.val[1] - 0.5)*PnorVec.val[1] + (pDot.val[2] - 0.5)*PnorVec.val[2]) / vpt;
			iDot.val[0] = 0.5 + LnorVec.val[0] * t;
			iDot.val[1] = 0.5 + LnorVec.val[1] * t;
			iDot.val[2] = 0.5 + LnorVec.val[2] * t;
		}
	}
	bool Judge(){
		bool J = 1;
		if (iDot.val[0] > 1)J = 0;
		if (iDot.val[0] < 0)J = 0;
		if (iDot.val[1] > 1)J = 0;
		if (iDot.val[1] < 0)J = 0;
		if (iDot.val[2] > 1)J = 0;
		if (iDot.val[2] < 0)J = 0;
		if (OF_RGB.val[0]>1 && iDot.val[0] < 0.5)J = 0;
		if (OF_RGB.val[1]>1 && iDot.val[1] < 0.5)J = 0;
		if (OF_RGB.val[2]>1 && iDot.val[2] < 0.5)J = 0;
		if (OF_RGB.val[0]<0&& iDot.val[0] > 0.5)J = 0;
		if (OF_RGB.val[1]<0 && iDot.val[1] > 0.5)J = 0;
		if (OF_RGB.val[2]<0 && iDot.val[2] > 0.5)J = 0;


		return J;

	}

	Vec3f submit(){
		if (OF_RGB[2] <= 1 && OF_RGB[0] <= 1 && OF_RGB[1] <= 1 && OF_RGB[2] >= 0 && OF_RGB[1] >= 0 && OF_RGB[0] >= 0)return OF_RGB;
		pDot = Vec3f(0, 1, 0);//平面经过的一点坐标 
		PnorVec = Vec3f(0, 1, 0);//平面法向量 
		lineXplane();
		if (Judge())return iDot;
		else{
			pDot = Vec3f(1, 0, 0);
			PnorVec = Vec3f(1, 0, 0);
			lineXplane();
			if (Judge())return iDot;
			else{
				pDot = Vec3f(1, 0, 0);
				PnorVec = Vec3f(0, 0, -1);
				lineXplane();
				if (Judge())return iDot;
				else{
					pDot = Vec3f(0, 0, 1);
					PnorVec = Vec3f(0, 0, 1);
					lineXplane();
					if (Judge())return iDot;
					else{
						pDot = Vec3f(0, 0, 1);
						PnorVec = Vec3f(0, -1, 0);
						lineXplane();
						if (Judge())return iDot;
						else{
							pDot = Vec3f(0, 0, 1);
							PnorVec = Vec3f(-1, 0, 0);
							lineXplane();
							return iDot;
						}

					}

				}

			}

		}




	}




};


#endif

上面为颜色溢出修正类的代码,输入为Vec3f BGR值,输出为 修正好的 Vec3fBGR值,范围为0~1;

本修正方法保留了hue值的不变。

如下图所示:

下图中左侧为已经溢出的颜色值,不能正常显示色相为101.538的绿色色相,右侧为修正结果。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值