OpenCV中的一个反复出现的问题是如何将单通道函数应用于多通道图像(如用cv::LUT减少颜色深度)。一般情况很简单:
但是,当唯一改变的是应用于通道的函数(以及奇怪的额外参数)时,我不得不一遍又一遍地对相同的算法进行编码,这有点傻。
OpenCV是否提供了上述算法的通用实现--将单通道函数应用于多通道图像的每个通道?
如果没有,您建议如何在C++中解决这个问题?宏可以做到这一点,但它将是一个有点复杂的宏观,大和丑陋。如果可以的话,我更喜欢一个更优雅的解决方案。
发布于 2014-01-06 15:42:20
FP负责救援工作。;)
你不需要马可。std:功能提供了我们对此所需的一切:
#include <opencv2/opencv.hpp>
#include <functional>
#include <iterator>
// Apply a given function to every channel of an image.
cv::Mat ApplyToChannels(const cv::Mat& img,
const std::function<cv::Mat(const cv::Mat& src)>& f)
{
// Split image.
std::vector<cv::Mat> channelsIn;
cv::split(img, channelsIn);
// Apply function to channels.
std::vector<cv::Mat> channelsOut;
std::transform(begin(channelsIn), end(channelsIn),
std::back_inserter(channelsOut), [&f](const cv::Mat& channel)
{
return f(channel);
});
// Merge image.
cv::Mat result;
cv::merge(channelsOut, result);
return result;
}
cv::Mat Identity(const cv::Mat& src)
{
return src;
}
cv::Mat Sobel(const cv::Mat& src)
{
cv::Mat result;
cv::Sobel(src, result, src.depth(), 1, 1);
return result;
}
int main()
{
// Lamdas also work.
auto Blur = [](const cv::Mat& src) -> cv::Mat
{
cv::Mat result;
cv::blur(src, result, cv::Size(15, 15));
return result;
};
// Create test image and draw something on it.
cv::Mat image(120, 160, CV_8UC3, cv::Scalar(0, 0, 0));
cv::line(image, cv::Point(32, 32), cv::Point(120, 80),
cv::Scalar(56, 123, 234), 28);
// Apply two different operations.
auto image2 = ApplyToChannels(image, Sobel);
auto image3 = ApplyToChannels(image, Blur);
// Save results.
cv::imwrite("1.png", image);
cv::imwrite("2.png", image2);
cv::imwrite("3.png", image3);
}
如果您想让您的函数更通用,可以使用std:绑定等来设置例如sobel参数。
https://stackoverflow.com/questions/20945933
复制相似问题