1 | initial version |
You wanted an example, so here you go. This assumes the first two dimensions of the convolution have been done.
This does a BGR 2 Gray as a convolution between the channels. The center channel is properly gray, but the edges use reflected borders, so it does the math with gbg or grg, which of course doesn't come out correctly. Hopefully you can see how this would extend to images with a much higher number of channels.
image.create(100, 100, CV_8UC3);
image.setTo(cv::Scalar(50,100,200));
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
std::cout << image(cv::Rect(0, 0, 1, 1)) << "\n\n";
std::cout << gray(cv::Rect(0, 0, 1, 1)) << "\n\n";
cv::Mat thirdD, kernel;
kernel.create(1, 3, CV_32F);//3 is the Size of the kernel in the third dimension.
kernel.at<float>(0) = 0.114;//Blue
kernel.at<float>(1) = 0.587;//Green
kernel.at<float>(2) = 0.299;//Red
thirdD = image.reshape(1, image.rows*image.cols);
cv::filter2D(thirdD, output, -1, kernel, cv::Point(-1, -1), 0.0, cv::BORDER_REFLECT_101);//g|bgr|g
//The -1 says keep it in the same pixel format CV_8U. You can choose different border types, but this is the default.
trueGray = output.reshape(3, image.rows);//3 is the number of channels you started with, the depth of the image in the third dimension.
std::cout << trueGray(cv::Rect(0, 0, 1, 1)) << "\n\n";