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

打印 上一主题 下一主题

主题 927|帖子 927|积分 2781

测试情况】
vs2019
opencv==4.8.0
【效果演示】

【核心实现代码】
BlackWhite.hpp
  1. #ifndef OPENCV2_PS_BLACKWHITE_HPP_
  2. #define OPENCV2_PS_BLACKWHITE_HPP_
  3. #include "opencv2/core.hpp"
  4. namespace cv {
  5. class BlackWhite {
  6. public:
  7.         float         red;     //红色的灰度系数值,取值范围: [-1.0, 1.0]
  8.         float         yellow;  //黄色的灰度系数值,取值范围: [-1.0, 1.0]
  9.         float         green;   //绿色的灰度系数值,取值范围: [-1.0, 1.0]
  10.         float         cyan;    //青色的灰度系数值,取值范围: [-1.0, 1.0]
  11.         float         blue;    //蓝色的灰度系数值,取值范围: [-1.0, 1.0]
  12.         float         magenta; //洋红色的灰度系数值,取值范围: [-1.0, 1.0]
  13.         BlackWhite();
  14.         virtual ~BlackWhite();
  15.         int adjust(InputArray src, OutputArray dst);//实施黑白调整
  16. };
  17. } /* namespace cv */
  18. #endif /* OPENCV2_PS_BLACKWHITE_HPP_ */
复制代码
 BlackWhite.cpp
  1. #include "BlackWhite.hpp"
  2. #define SWAP(a, b, t)  do { t = a; a = b; b = t; } while(0)
  3. #define CLIP_RANGE(value, min, max)  ( (value) > (max) ? (max) : (((value) < (min)) ? (min) : (value)) )
  4. #define COLOR_RANGE(value)  CLIP_RANGE(value, 0, 255)
  5. //color index
  6. typedef enum COLOR_INDEX {
  7.         INDEX_RED,
  8.         INDEX_YELLOW,
  9.         INDEX_GREEN,
  10.         INDEX_CYAN,
  11.         INDEX_BLUE,
  12.         INDEX_MAGENTA
  13. } color_index_t;
  14. namespace cv {
  15. BlackWhite::BlackWhite()
  16. {
  17.         //set to default settings
  18.         red = 0.4;
  19.         yellow = 0.6;
  20.         green = 0.4;
  21.         cyan = 0.6;
  22.         blue = 0.2;
  23.         magenta = 0.8;
  24. }
  25. BlackWhite::~BlackWhite() {
  26. }
  27. int BlackWhite::adjust(InputArray src, OutputArray dst)
  28. {
  29.         Mat input = src.getMat();
  30.         if( input.empty() ) {
  31.                 return -1;
  32.         }
  33.         dst.create(src.size(), src.type());
  34.         Mat output = dst.getMat();
  35.         int blackWhiteParams[6];
  36.         blackWhiteParams[0] = CLIP_RANGE(red     * 100, -100, 100);
  37.         blackWhiteParams[1] = CLIP_RANGE(yellow  * 100, -100, 100);
  38.         blackWhiteParams[2] = CLIP_RANGE(green   * 100, -100, 100);
  39.         blackWhiteParams[3] = CLIP_RANGE(cyan    * 100, -100, 100);
  40.         blackWhiteParams[4] = CLIP_RANGE(blue    * 100, -100, 100);
  41.         blackWhiteParams[5] = CLIP_RANGE(magenta * 100, -100, 100);
  42.         const uchar *in;
  43.         uchar *out;
  44.         int channels  = input.channels();
  45.         int rows = input.rows;
  46.         int cols = input.cols;
  47.         uchar gray;
  48.         int tmp;
  49.         int values[3];
  50.         int indexes[3];
  51.         int ratio_max;
  52.         int ratio_max_mid;
  53.         for (int y = 0; y < rows; y ++ )
  54.         {
  55.                 in = input.ptr<uchar>(y);
  56.                 out = output.ptr<uchar>(y);
  57.                 for (int x = 0; x < cols; x ++)
  58.                 {
  59.                         //read RGB into values, set index in indexes.
  60.                         values[0] = in[0]; values[1] = in[1]; values[2] = in[2];
  61.                         indexes[0]=INDEX_BLUE; indexes[1]=INDEX_GREEN; indexes[2]=INDEX_RED;
  62.                         //sort values and indexes
  63.                         if ( values[1] > values[0] ) {
  64.                                 SWAP(values[0], values[1], tmp);
  65.                                 SWAP(indexes[0], indexes[1], tmp);
  66.                         }
  67.                         if ( values[2] > values[1] ) {
  68.                                 SWAP(values[1], values[2], tmp);
  69.                                 SWAP(indexes[1], indexes[2], tmp);
  70.                         }
  71.                         if ( values[1] > values[0] ) {
  72.                                 SWAP(values[0], values[1], tmp);
  73.                                 SWAP(indexes[0], indexes[1], tmp);
  74.                         }
  75.                         //get ratio_max
  76.                         ratio_max = blackWhiteParams[ indexes[0] ];
  77.                         //calculate ratio_max_mid
  78.                         if ( indexes[0] == INDEX_RED ) {
  79.                                 tmp = (indexes[1] == INDEX_GREEN) ? INDEX_YELLOW : INDEX_CYAN;
  80.                         } else  if ( indexes[0] == INDEX_GREEN ) {
  81.                                 tmp = (indexes[1] == INDEX_RED) ? INDEX_YELLOW : INDEX_CYAN ;
  82.                         } else {
  83.                                 tmp = (indexes[1] == INDEX_RED) ? INDEX_MAGENTA : INDEX_CYAN;
  84.                         }
  85.                         ratio_max_mid = blackWhiteParams[ tmp ];
  86.                         //calculate gray =  (max - mid) * ratio_max + (mid - min) * ratio_max_mid + min
  87.                         gray = COLOR_RANGE ( (
  88.                                         (values[0] - values[1]) * ratio_max +
  89.                                         (values[1] - values[2]) * ratio_max_mid + values[2] * 100
  90.                                         ) / 100 );
  91.                         //save to ouput
  92.                         *out++ = gray;
  93.                         *out++ = gray;
  94.                         *out++ = gray;
  95.                         //move pointer forward
  96.                         in += 3;
  97.                         for (int j = 0; j < channels - 3; j++) {
  98.                                 *out++ = *in++;
  99.                         }
  100.                 }
  101.         }
  102.         return 0;
  103. }
  104. } /* namespace cv */
复制代码
【完整演示代码下载】
https://download.csdn.net/download/FL1623863129/89633221

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

汕尾海湾

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表