汕尾海湾 发表于 2024-8-14 06:53:27

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

测试情况】
vs2019
opencv==4.8.0
【效果演示】
https://i-blog.csdnimg.cn/direct/171bb7eac04f47438a7ccba1009881e8.gif
【核心实现代码】
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;
        blackWhiteParams = CLIP_RANGE(red   * 100, -100, 100);
        blackWhiteParams = CLIP_RANGE(yellow* 100, -100, 100);
        blackWhiteParams = CLIP_RANGE(green   * 100, -100, 100);
        blackWhiteParams = CLIP_RANGE(cyan    * 100, -100, 100);
        blackWhiteParams = CLIP_RANGE(blue    * 100, -100, 100);
        blackWhiteParams = 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;
        int indexes;
        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 = in; values = in; values = in;
                        indexes=INDEX_BLUE; indexes=INDEX_GREEN; indexes=INDEX_RED;

                        //sort values and indexes
                        if ( values > values ) {
                                SWAP(values, values, tmp);
                                SWAP(indexes, indexes, tmp);
                        }

                        if ( values > values ) {
                                SWAP(values, values, tmp);
                                SWAP(indexes, indexes, tmp);
                        }

                        if ( values > values ) {
                                SWAP(values, values, tmp);
                                SWAP(indexes, indexes, tmp);
                        }

                        //get ratio_max
                        ratio_max = blackWhiteParams[ indexes ];

                        //calculate ratio_max_mid
                        if ( indexes == INDEX_RED ) {
                                tmp = (indexes == INDEX_GREEN) ? INDEX_YELLOW : INDEX_CYAN;
                        } elseif ( indexes == INDEX_GREEN ) {
                                tmp = (indexes == INDEX_RED) ? INDEX_YELLOW : INDEX_CYAN ;
                        } else {
                                tmp = (indexes == 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 - values) * ratio_max +
                                        (values - values) * ratio_max_mid + values * 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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: [C++][opencv]基于opencv实现photoshop算法灰度化图像