How can I change the 8bit rgb images into 16bit grayscale? [closed]

asked 2015-09-05 00:08:37 -0600

Winterer gravatar image

updated 2015-09-05 02:08:36 -0600

LBerger gravatar image

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?

image description

original image

image description

result image

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by sturkmen
close date 2020-11-13 13:54:01.693250

Comments

2

I can see some problems in you code first:

cv::Mat image(128,128,CV_16UC1);  
image = cv::imread(InputFileName, CV_LOAD_IMAGE_ANYDEPTH  | CV_LOAD_IMAGE_ANYCOLOR);

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 :

cout <<image.size()<<" "<<image.depth()<<" "<<image.channels()<<"\n";
LBerger gravatar imageLBerger ( 2015-09-05 02:20:56 -0600 )edit

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."

 cvtColor(img,img,COLOR_BGR2GRAY); // 3 to 1 chan
 im.convertTo(im, CV_16U, 255); // 8bit to 16
berak gravatar imageberak ( 2015-09-05 02:25:32 -0600 )edit

@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 gravatar imageLBerger ( 2015-09-05 03:06:02 -0600 )edit

@LBerger, ah, right. misread it then.

berak gravatar imageberak ( 2015-09-05 03:09:25 -0600 )edit

it was a bug that fixed

sturkmen gravatar imagesturkmen ( 2016-04-18 07:02:36 -0600 )edit