快速有效的方法来标准化具有不同值的图像的每个通道

时间:2017-12-04 11:51:50

标签: c++ opencv c++17

我必须将每个通道的所有像素除以一个值(标准化)。我所做的是将图像分成三个通道,划分所有像素,然后合并三个通道。我是这样做的:

template <typename T, typename ... Ts>
void insert_all(std::vector<T> &vec, Ts ... ts)
{
    (vec.push_back(ts), ...);
} 

std::vector<cv::Mat> rgb, rgbN; 
cv::split(src, rgb); //src is my RGB image

rgbN.reserve(3);
insert_all(rgbN, cv::Mat_<float>(rgb[0])/A0, 
                 cv::Mat_<float>(rgb[1])/A1, 
                 cv::Mat_<float>(rgb[2])/A2);
cv::Mat srcN;
cv::merge(rgbN, srcN_gray); 

我认为对于简单的规范化来说代码太多了,有没有更好的方法来实现它,可能没有spiting和合并?

1 个答案:

答案 0 :(得分:3)

正如我在评论中所写的那样,你可以尝试做所有事情而不将其分开......尽可能用最少的代码我认为这是要走的路:

// dummy values, replace as needed
float A0 = 1.0, A1 = 2.0, A2 = 3.0;
// creates a copy to work in
cv::Mat srcN = src.clone();
// normalizes in one pass
std::transform(srcN.begin<cv::Vec3f>(), srcN.end<cv::Vec3f>(), srcN.begin<cv::Vec3f>(), [A0, A1, A2](const cv::Vec3f pixel){
  return cv::Vec3f(pixel[0]/A0, pixel[1]/A1, pixel[2]/A2);
});

以类似的方式,您可以尝试其他方法,例如OpenCV foreach或并发库。

编辑:

这是我尝试使用OpenCV foreach ...我没有测试过,但是应该可以工作

cv::Mat srcN = src.clone();
srcN.forEach<cv::Vec3f>
(
  [A0, A1, A2](cv::Vec3f &pixel, const int * position) -> void
  {
    pixel[0]/=A0;
    pixel[1]/=A1;
    pixel[2]/=A2;
  }
);