[C++][opencv]基于opencv实现photoshop算法灰度化图像

测试环境】

vs2019

opencv==4.8.0

【效果演示】

【核心实现代码】

BlackWhite.hpp

#ifndef OPENCV2_PS_BLACKWHITE_HPP_
#define OPENCV2_PS_BLACKWHITE_HPP_

#include "opencv2/core.hpp"

namespace cv {

class BlackWhite {
public:
	float 	red;     //红色的灰度系数值,取值范围: [-1.0, 1.0]
	float 	yellow;  //黄色的灰度系数值,取值范围: [-1.0, 1.0]
	float 	green;   //绿色的灰度系数值,取值范围: [-1.0, 1.0]
	float 	cyan;    //青色的灰度系数值,取值范围: [-1.0, 1.0]
	float 	blue;    //蓝色的灰度系数值,取值范围: [-1.0, 1.0]
	float 	magenta; //洋红色的灰度系数值,取值范围: [-1.0, 1.0]

	BlackWhite();
	virtual ~BlackWhite();

	int adjust(InputArray src, OutputArray dst);//实施黑白调整
};

} /* namespace cv */

#endif /* OPENCV2_PS_BLACKWHITE_HPP_ */

BlackWhite.cpp

#include "BlackWhite.hpp"

#define SWAP(a, b, t)  do { t = a; a = b; b = t; } while(0)
#define CLIP_RANGE(value, min, max)  ( (value) > (max) ? (max) : (((value) < (min)) ? (min) : (value)) )
#define COLOR_RANGE(value)  CLIP_RANGE(value, 0, 255)

//color index
typedef enum COLOR_INDEX {
	INDEX_RED,
	INDEX_YELLOW,
	INDEX_GREEN,
	INDEX_CYAN,
	INDEX_BLUE,
	INDEX_MAGENTA
} color_index_t;

namespace cv {

BlackWhite::BlackWhite()
{
	//set to default settings
	red = 0.4;
	yellow = 0.6;
	green = 0.4;
	cyan = 0.6;
	blue = 0.2;
	magenta = 0.8;
}

BlackWhite::~BlackWhite() {
}


int BlackWhite::adjust(InputArray src, OutputArray dst)
{
	Mat input = src.getMat();
	if( input.empty() ) {
		return -1;
	}

	dst.create(src.size(), src.type());
	Mat output = dst.getMat();

	int blackWhiteParams[6];
	blackWhiteParams[0] = CLIP_RANGE(red     * 100, -100, 100);
	blackWhiteParams[1] = CLIP_RANGE(yellow  * 100, -100, 100);
	blackWhiteParams[2] = CLIP_RANGE(green   * 100, -100, 100);
	blackWhiteParams[3] = CLIP_RANGE(cyan    * 100, -100, 100);
	blackWhiteParams[4] = CLIP_RANGE(blue    * 100, -100, 100);
	blackWhiteParams[5] = CLIP_RANGE(magenta * 100, -100, 100);

	const uchar *in;
	uchar *out;
	int channels  = input.channels();
	int rows = input.rows;
	int cols = input.cols;
	uchar gray;

	int tmp;
	int values[3];
	int indexes[3];
	int ratio_max;
	int ratio_max_mid;

	for (int y = 0; y < rows; y ++ )
	{
		in = input.ptr<uchar>(y);
		out = output.ptr<uchar>(y);
		for (int x = 0; x < cols; x ++)
		{
			//read RGB into values, set index in indexes.
			values[0] = in[0]; values[1] = in[1]; values[2] = in[2];
			indexes[0]=INDEX_BLUE; indexes[1]=INDEX_GREEN; indexes[2]=INDEX_RED;

			//sort values and indexes
			if ( values[1] > values[0] ) {
				SWAP(values[0], values[1], tmp);
				SWAP(indexes[0], indexes[1], tmp);
			}

			if ( values[2] > values[1] ) {
				SWAP(values[1], values[2], tmp);
				SWAP(indexes[1], indexes[2], tmp);
			}

			if ( values[1] > values[0] ) {
				SWAP(values[0], values[1], tmp);
				SWAP(indexes[0], indexes[1], tmp);
			}

			//get ratio_max
			ratio_max = blackWhiteParams[ indexes[0] ];

			//calculate ratio_max_mid
			if ( indexes[0] == INDEX_RED ) {
				tmp = (indexes[1] == INDEX_GREEN) ? INDEX_YELLOW : INDEX_CYAN;
			} else  if ( indexes[0] == INDEX_GREEN ) {
				tmp = (indexes[1] == INDEX_RED) ? INDEX_YELLOW : INDEX_CYAN ;
			} else {
				tmp = (indexes[1] == INDEX_RED) ? INDEX_MAGENTA : INDEX_CYAN;
			}
			ratio_max_mid = blackWhiteParams[ tmp ];

			//calculate gray =  (max - mid) * ratio_max + (mid - min) * ratio_max_mid + min
			gray = COLOR_RANGE ( (
					(values[0] - values[1]) * ratio_max +
					(values[1] - values[2]) * ratio_max_mid + values[2] * 100
					) / 100 );

			//save to ouput
			*out++ = gray;
			*out++ = gray;
			*out++ = gray;

			//move pointer forward
			in += 3;
			for (int j = 0; j < channels - 3; j++) {
				*out++ = *in++;
			}
		}
	}

	return 0;

}

} /* namespace cv */

【完整演示代码下载】

https://download.csdn.net/download/FL1623863129/89633221

相关推荐
坊钰16 分钟前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang121 分钟前
leetcode hot100 LRU缓存
java·开发语言
时雨h36 分钟前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
云计算DevOps-韩老师1 小时前
【网络云计算】2024第52周-每日【2024/12/25】小测-理论&实操-自己构造场景,写5个系统管理的脚本-解析
开发语言·网络·云计算·bash·perl
伊一大数据&人工智能学习日志1 小时前
OpenCV计算机视觉 01 图像与视频的读取操作&颜色通道
人工智能·opencv·计算机视觉
暮色尽染1 小时前
Python 正则表达式
开发语言·python
IT猿手1 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解GLSMOP1-GLSMOP9及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·算法·机器学习·matlab·强化学习
小爬虫程序猿1 小时前
利用Java爬虫获取速卖通(AliExpress)商品详情的详细指南
java·开发语言·爬虫
xlsw_1 小时前
java全栈day21--Web后端实战之利用Mybaits查询数据
java·开发语言
王老师青少年编程1 小时前
gesp(二级)(12)洛谷:B3955:[GESP202403 二级] 小杨的日字矩阵
c++·算法·矩阵·gesp·csp·信奥赛