How can I change the 8bit rgb images into 16bit grayscale? [closed]
I have the file saved as bmp format in c #. A strange problem arose in the process of converting files from a c ++ opencv.
Save the file format is bmp -> jp2
The following code is the source code that I work.
//////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) void ConvertJp2to16bitGrayScaleJp2(char* InputFileName,char* OutputFileName)
{
// TODO: 응용 프로그램의 동작은 여기에서 코딩합니다.
// Mat image,fin_img;
// image = imread("제목 없음-6.png", CV_LOAD_IMAGE_COLOR); // Read the file
cv::Mat image(128,128,CV_16UC1);
image = cv::imread(InputFileName, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
if (!image.data) {
std::cout << "Image file not found\n";
return ;
}
cv::Mat pic16bit(128,128,CV_16UC1);
std::cout << image.depth() << std::endl;
//
//cv::cvtColor(image, image, CV_RGB2GRAY);
image.convertTo(pic16bit,CV_16UC1);
//cvConvertScale(&image,&pic16bit,2.0,0);
//pic16bit=image;
//pic16bit.convertTo(pic16bit, CV_16U, );
// image.convertTo(pic16bit, CV_16U, 255); //convert to 16-bit by multiplying all values by 255
//
// params.append(cv.CV_IMWRITE_PNG_COMPRESSION);
// params.append(8);
// namedWindow( "Result window", CV_WINDOW_AUTOSIZE );
// imshow( "Result window", image );
//
// namedWindow( "Result window", CV_WINDOW_AUTOSIZE );
// imshow( "Result window", pic16bit );
// create image window named "asdfasdf"
//cv::namedWindow("asdfasdf");
//divide( image, pic16bit, image, image.depth() == 16 ? UCHAR_MAX : USHRT_MAX );
// show the image on window
//imshow("asdfasdf", pic16bit);
vector<int> compression_params;
compression_params.push_back(CV_16U);
imwrite(OutputFileName,pic16bit,compression_params);
// // wait for key
cv::waitKey(0);
//
//
// Mat imageNew8, newImage16;
// newImage16 = imread("dest.jp2", CV_LOAD_IMAGE_ANYDEPTH|CV_LOAD_IMAGE_ANYCOLOR);
// newImage16.convertTo(imageNew8, CV_8UC1, 1.0/255);
return;
}
///////////////////////////////////////////////////////////
If you check the work product to the code is 16bit unsigend gray scale images created through
Format image of a strange mix of stripes and the width is cut in half.
What is one to do wrong and right way to get the results?
original image
result image
I can see some problems in you code first:
size and type of image is fixed by imread. cv:Mat image it's a good and enough. It's same thing for cv::Mat pic16bit(128,128,CV_16UC1); cv::Mat pic16bit it's enough
After image.convertTo(pic16bit,CV_16UC1); I'm not sure what happen because your image (Mat image) can have 4 channels like many png file. I don't know how to convert a 3 or 4 channels images in a one channel 16 bits image.
Check your image :
you don't need to preallocate cv::Mat when you do imread() or convertTo(), those will get overwritten anyway.
it does not do any harm, but you'll fool yourself believing it has a certain type/size, e.g. your bmp input is for sure not 16bit (but CV_8UC3 in this case)
then, looking at the jp2 encoder, it ignores your params vector.
@LBerger, " I don't know how to convert a 3 or 4 channels images in a one channel 16 bits image."
@berak yes this I know you have changed my question in how to convert image in grayscale. Even with your answer I think I can do a better works because I don't need saturate to 255 but 65536 dynamics is lost using cvtColor(img,img,COLOR_BGR2GRAY) something like cvtColor(img,img,COLOR_BGR2GRAY16BIT) is better but it does not exist
@LBerger, ah, right. misread it then.
it was a bug that fixed