openCV中的线性颜色渐变

时间:2014-09-02 11:43:44

标签: android c++ opencv image-processing computer-vision

我正在尝试创建两种颜色的渐变,如Photoshop。 输入两种颜色的r,g,b,结果将是渐变的Mat。我尝试了至少5个小时,我找不到Photoshop的确切效果。 我尝试创建我自己的公式(因为我在网上找不到任何公式),通过将RGB更改为HSV,然后将相对于总行数的色调差异添加到Mat的每一行,并且还减少强度到图像中心然后再增加它。代码是自我解释的。

此外,如果有人能告诉我创建渐变的确切公式,那将非常有用。

这是Photoshop渐变的样子

enter image description here

这就是我从代码enter image description here

获得的内容
 int r1, g1, b1, r2, g2, b2;

 r1 = 255;
 g1 = 0;
 b1 = 0;
 r2 = 0;
 g2 = 255;
 b2 = 0;

 Mat input = imread("img.jpg");
 Mat color1(input.size(), input.type());
 Mat color2(input.size(), input.type());

 vector<Mat> bgr1;
 vector<Mat> bgr2;

 split(color1, bgr1);
 bgr1[0] = b1;
 bgr1[1] = g1;
 bgr1[2] = r1;
 merge(bgr1, color1);

 split(color2, bgr2);
 bgr2[0] = b2;
 bgr2[1] = g2;
 bgr2[2] = r2;
 merge(bgr2, color2);

 vector<Mat> hls1;
 vector<Mat> hls2;

 cvtColor(color1, color1, CV_BGRA2BGR);
 cvtColor(color1, color1, CV_BGR2HSV);
 split(color1, hls1);

 cvtColor(color2, color2, CV_BGRA2BGR);
 cvtColor(color2, color2, CV_BGR2HSV);
 split(color2, hls2);

 double h1 = hls1[0].at<uchar>(0, 0);
 double h2 = hls2[0].at<uchar>(0, 0);
 double dif = (h2 - h1) / input.rows;
 double h = h1;

 double halfL = 255 / 2;
 double halfR = input.rows / 2;
 double ldif = halfL / halfR;
 double l = 255;
 bool isHalf = false;

 for (int i = 0; i < input.rows; i++)
 {
  for (int j = 0; j < input.cols; j++)
  {
   hls1[0].at<uchar>(i, j) = h;
   hls1[2].at<uchar>(i, j) = l;
  }


  if (isHalf == false){
   l -= ldif;
  }
  else{
   l += ldif;
  }

  if (i < input.rows * 0.40)
  {
   h += dif * 0.40;
  }
  else if (i < input.rows * 0.60)
  {
   h += dif * 3;
  }
  else
  {
   h += dif * 0.40;
  }

  if (i >= input.rows / 2)
  {
   isHalf = true;
  }
 }

 merge(hls1, color1);
 merge(hls2, color2);

 cvtColor(color1, color1, CV_HSV2BGR);
 cvtColor(color1, color1, CV_BGR2BGRA);

 cvtColor(color2, color2, CV_HSV2BGR);
 cvtColor(color2, color2, CV_BGR2BGRA);

 namedWindow("Color1", cv::WINDOW_NORMAL);
 resizeWindow("Color1", color1.size().width / 2, color1.size().height / 2);
 imshow("Color1", color1);

 waitKey(0);
 destroyAllWindows();
 system("pause");

1 个答案:

答案 0 :(得分:7)

我更正了我的第一个代码

对于应该更容易的事情,这似乎是一个非常复杂的代码。 我会做那样的事情。

int taille = 500;    
Mat image(taille,taille,CV_8UC3);
for(int y = 0; y < taille; y++){
   Vec3b val;
   val[0] = 0; val[1] = (y*255)/taille; val[2] = (taille-y)*255/taille;
   for(int x = 0; x < taille; x++)
      image.at<Vec3b>(y,x) = val;
}

在Micka的建议中,我添加了尾部= 400的结果图片; Result of the previous code.