I wish to convert a color image to a 16-bit grayscale image using C++'s OpenCV library. I'm using OpenCV 4.1.2 and C++ 17.
I'm able to load a color image & save it as 8-bit grayscale with the following minimal example code:
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>
int main()
{
cv::Mat image = cv::imread("test.jpg", -1);
cv::Mat imageGray;
cv::cvtColor(image, imageGray, cv::COLOR_BGR2GRAY);
std::cout << "First pixel: " + std::to_string(imageGray.at<uchar>(0, 0)) + "\n";
cv::imwrite("gray.jpg", imageGray);
return 0;
}
Alongside saving the grayscale image using cv::imwrite, I also wish to be able to access the pixels inside the image with the at function.
Currently I am able to convert the color image into an 8-bit grayscale using the cvtColor function and access the pixels inside of it using the uchar type template.
test.jpg:
gray.jpg:
However, I wish to convert the image into a 16-bit grayscale for a more detailed grayscale gradient.
Simply attempting to use the ushort type template with the at function instead of uchar results in a memory exception inside at.
Doing something like this instead from the following post answer:
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>
int main()
{
cv::Mat image = cv::imread("test.jpg", -1);
cv::Mat imageGray;
cv::cvtColor(image, imageGray, cv::COLOR_BGR2GRAY);
image.convertTo(imageGray, CV_16U, 255);
std::cout << "First pixel: " + std::to_string(imageGray.at<ushort>(0, 0)) + "\n";
cv::imwrite("gray.jpg", imageGray);
return 0;
}
doesn't cause an exception, however it appears to break gray.jpg:
Plus, wouldn't this also cause the image data to not be upscaled & interpolated to 16-bit properly?
What is the proper way to convert a color image to a 16-bit grayscale in OpenCV?
Thanks for reading my post, any guidance is appreciated.


