[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

相关推荐
JSU_曾是此间年少10 分钟前
数据结构——线性表与链表
数据结构·c++·算法
许野平22 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨26 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar34 分钟前
yelp数据集上识别潜在的热门商家
开发语言·python
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧1 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵1 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong2 小时前
Java反射
java·开发语言·反射
Troc_wangpeng2 小时前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习